COMPMID-2204:  RuntimeContext interface for NEON functions.

This patch creates the interfaces for the runtime context for NEON.

Only the Neon backend implements the context which currently only holds
an instance of the scheduler.

The NEActivationLayer function has been updated to use the new context
interface and the corresponding validation tests ported.

Change-Id: I32e7e6aa888796dcbbfc5039b1e7f784a24f47da
Signed-off-by: Pablo Tello <pablo.tello@arm.com>
Reviewed-on: https://review.mlplatform.org/c/1851
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com>
diff --git a/tests/framework/instruments/Instruments.h b/tests/framework/instruments/Instruments.h
index 370db8d..8adf501 100644
--- a/tests/framework/instruments/Instruments.h
+++ b/tests/framework/instruments/Instruments.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -33,6 +33,7 @@
 #include "SchedulerTimer.h"
 #include "WallClockTimer.h"
 
+#include <memory>
 #include <sstream>
 #include <string>
 
@@ -59,6 +60,12 @@
     SCHEDULER_TIMESTAMPS    = 0x0900,
 };
 
+struct InstrumentsInfo
+{
+    std::vector<ISchedulerUser *> _scheduler_users{};
+};
+extern std::unique_ptr<InstrumentsInfo> instruments_info;
+
 using InstrumentsDescription = std::pair<InstrumentType, ScaleFactor>;
 
 InstrumentsDescription instrument_type_from_name(const std::string &name);
diff --git a/tests/framework/instruments/SchedulerTimer.cpp b/tests/framework/instruments/SchedulerTimer.cpp
index c114dfb..98c9b87 100644
--- a/tests/framework/instruments/SchedulerTimer.cpp
+++ b/tests/framework/instruments/SchedulerTimer.cpp
@@ -23,6 +23,7 @@
  */
 #include "SchedulerTimer.h"
 
+#include "Instruments.h"
 #include "WallClockTimer.h"
 #include "arm_compute/core/CPP/ICPPKernel.h"
 #include "arm_compute/core/utils/misc/Cast.h"
@@ -114,8 +115,12 @@
 
 template <bool output_timestamps>
 SchedulerClock<output_timestamps>::SchedulerClock(ScaleFactor scale_factor)
-    : _kernels(), _real_scheduler(nullptr), _real_scheduler_type(), _real_graph_function(nullptr), _scale_factor(scale_factor), _interceptor(nullptr)
+    : _kernels(), _real_scheduler(nullptr), _real_scheduler_type(), _real_graph_function(nullptr), _scale_factor(scale_factor), _interceptor(nullptr), _scheduler_users()
 {
+    if(instruments_info != nullptr)
+    {
+        _scheduler_users = instruments_info->_scheduler_users;
+    }
 }
 
 template <bool output_timestamps>
@@ -157,6 +162,17 @@
         _interceptor    = std::make_shared<Interceptor<output_timestamps>>(_kernels, *_real_scheduler, _scale_factor);
         Scheduler::set(std::static_pointer_cast<IScheduler>(_interceptor));
         graph::TaskExecutor::get().execute_function = task_interceptor;
+
+        // Create an interceptor for each scheduler
+        // TODO(COMPID-2638) : Allow multiple schedulers, now it assumes the same scheduler is used.
+        std::for_each(std::begin(_scheduler_users), std::end(_scheduler_users),
+                      [&](ISchedulerUser * user)
+        {
+            if(user != nullptr && user->scheduler() != nullptr)
+            {
+                user->intercept_scheduler(support::cpp14::make_unique<Interceptor<output_timestamps>>(_kernels, *user->scheduler(), _scale_factor));
+            }
+        });
     }
 }
 
@@ -175,6 +191,16 @@
     _interceptor                                = nullptr;
     graph::TaskExecutor::get().execute_function = _real_graph_function;
     _real_graph_function                        = nullptr;
+
+    // Restore schedulers
+    std::for_each(std::begin(_scheduler_users), std::end(_scheduler_users),
+                  [&](ISchedulerUser * user)
+    {
+        if(user != nullptr)
+        {
+            user->restore_scheduler();
+        }
+    });
 }
 
 template <bool              output_timestamps>
diff --git a/tests/framework/instruments/SchedulerTimer.h b/tests/framework/instruments/SchedulerTimer.h
index 64adb48..ea64b22 100644
--- a/tests/framework/instruments/SchedulerTimer.h
+++ b/tests/framework/instruments/SchedulerTimer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -29,6 +29,8 @@
 #include "arm_compute/runtime/Scheduler.h"
 
 #include <list>
+#include <memory>
+#include <vector>
 
 namespace arm_compute
 {
@@ -36,6 +38,26 @@
 {
 namespace framework
 {
+/** Scheduler user interface  */
+class ISchedulerUser
+{
+public:
+    /** Default Destructor */
+    virtual ~ISchedulerUser() = default;
+    /** Intercept the scheduler used by
+     *
+     * @param interceptor Intercept the scheduler used by the scheduler user.
+     */
+    virtual void intercept_scheduler(std::unique_ptr<IScheduler> interceptor) = 0;
+    /** Restore the original scheduler */
+    virtual void restore_scheduler() = 0;
+    /** Real scheduler accessor
+     *
+     * @return The real scheduler
+     */
+    virtual IScheduler *scheduler() = 0;
+};
+
 /** Instrument creating measurements based on the information returned by clGetEventProfilingInfo for each OpenCL kernel executed*/
 template <bool output_timestamps>
 class SchedulerClock : public Instrument
@@ -46,7 +68,6 @@
      * @param[in] scale_factor Measurement scale factor.
      */
     SchedulerClock(ScaleFactor scale_factor);
-
     /** Prevent instances of this class from being copy constructed */
     SchedulerClock(const SchedulerClock &) = delete;
     /** Prevent instances of this class from being copied */
@@ -58,6 +79,7 @@
     /** Use the default destructor */
     ~SchedulerClock() = default;
 
+    // Inherited overridden methods
     std::string                 id() const override;
     void                        test_start() override;
     void                        start() override;
@@ -79,6 +101,7 @@
     std::function<decltype(graph::execute_task)> _real_graph_function;
     ScaleFactor                                  _scale_factor;
     std::shared_ptr<IScheduler>                  _interceptor;
+    std::vector<ISchedulerUser *>                _scheduler_users;
 };
 
 using SchedulerTimer      = SchedulerClock<false>;