COMPMID-2205: CL runtime context.

CL Interfaces implemented.
Concrete classes implemented.
One test (ActivationLayer) ported to the new interface.

Change-Id: I283808bec36ccfc2f13fe048c45cbbee698ce525
Signed-off-by: Pablo Tello <pablo.tello@arm.com>
Reviewed-on: https://review.mlplatform.org/c/1998
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
diff --git a/arm_compute/runtime/CL/CLBufferAllocator.h b/arm_compute/runtime/CL/CLBufferAllocator.h
index 19a3e62..7724022 100644
--- a/arm_compute/runtime/CL/CLBufferAllocator.h
+++ b/arm_compute/runtime/CL/CLBufferAllocator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -26,19 +26,25 @@
 
 #include "arm_compute/runtime/IAllocator.h"
 
-#include "arm_compute/core/CL/OpenCL.h"
-#include "arm_compute/runtime/CL/CLScheduler.h"
-
 #include <cstddef>
 
 namespace arm_compute
 {
+class CLCoreRuntimeContext;
 /** Default OpenCL cl buffer allocator implementation */
 class CLBufferAllocator final : public IAllocator
 {
 public:
-    /** Default constructor */
-    explicit CLBufferAllocator(cl::Context context = CLScheduler::get().context());
+    /** Default constructor
+     *
+     * @param[in] ctx A runtime context.
+     */
+    CLBufferAllocator(CLCoreRuntimeContext *ctx = nullptr);
+
+    /** Default copy constructor */
+    CLBufferAllocator(const CLBufferAllocator &) = default;
+    /** Default copy assignment operator */
+    CLBufferAllocator &operator=(const CLBufferAllocator &) = default;
 
     // Inherited methods overridden:
     void *allocate(size_t size, size_t alignment) override;
@@ -46,7 +52,7 @@
     std::unique_ptr<IMemoryRegion> make_region(size_t size, size_t alignment) override;
 
 private:
-    cl::Context _context;
+    CLCoreRuntimeContext *_ctx;
 };
 } // arm_compute
 #endif /*__ARM_COMPUTE_CLBUFFERALLOCATOR_H__ */
diff --git a/arm_compute/runtime/CL/CLHelpers.h b/arm_compute/runtime/CL/CLHelpers.h
index f3b11f8..84f155a 100644
--- a/arm_compute/runtime/CL/CLHelpers.h
+++ b/arm_compute/runtime/CL/CLHelpers.h
@@ -25,9 +25,12 @@
 #define __ARM_COMPUTE_CL_HELPERS_H__
 
 #include "arm_compute/core/CL/OpenCL.h"
+#include "arm_compute/runtime/IScheduler.h"
 
 namespace arm_compute
 {
+class CLRuntimeContext;
+class ICLKernel;
 /** This function creates an OpenCL context and a device.
  *
  * @note In debug builds, the function will automatically enable cl_arm_printf if the driver/device supports it.
@@ -37,5 +40,12 @@
  *         a value telling why the function failed.
  */
 std::tuple<cl::Context, cl::Device, cl_int> create_opencl_context_and_device();
+/** Schedules a kernel using the context if not nullptr else uses the legacy scheduling flow.
+ *
+ * @param[in] ctx    Context to use.
+ * @param[in] kernel Kernel to schedule.
+ * @param[in] flush  (Optional) Specifies if the command queue will be flushed after running the kernel.
+ */
+void schedule_kernel_on_ctx(CLRuntimeContext *ctx, ICLKernel *kernel, bool flush = true);
 } // namespace arm_compute
 #endif /* __ARM_COMPUTE_CL_HELPERS_H__ */
diff --git a/arm_compute/runtime/CL/CLMemoryRegion.h b/arm_compute/runtime/CL/CLMemoryRegion.h
index dbfd822..6f7c3cd 100644
--- a/arm_compute/runtime/CL/CLMemoryRegion.h
+++ b/arm_compute/runtime/CL/CLMemoryRegion.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 ARM Limited.
+ * Copyright (c) 2018-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -31,16 +31,17 @@
 
 namespace arm_compute
 {
+class CLCoreRuntimeContext;
 /** OpenCL memory region interface */
 class ICLMemoryRegion : public IMemoryRegion
 {
 public:
     /** Constructor
      *
-     * @param[in] ctx  OpenCL context
+     * @param[in] ctx  Runtime context
      * @param[in] size Region size
      */
-    ICLMemoryRegion(cl::Context ctx, size_t size);
+    ICLMemoryRegion(CLCoreRuntimeContext *ctx, size_t size);
     /** Default Destructor */
     virtual ~ICLMemoryRegion() = default;
     /** Prevent instances of this class from being copied (As this class contains pointers) */
@@ -86,9 +87,10 @@
     std::unique_ptr<IMemoryRegion> extract_subregion(size_t offset, size_t size) override;
 
 protected:
-    cl::Context _ctx;
-    void       *_mapping;
-    cl::Buffer  _mem;
+    cl::CommandQueue _queue;
+    cl::Context      _ctx;
+    void            *_mapping;
+    cl::Buffer       _mem;
 };
 
 /** OpenCL buffer memory region implementation */
@@ -97,16 +99,17 @@
 public:
     /** Constructor
      *
-     * @param[in] ctx   OpenCL context
+     * @param[in] ctx   Runtime context
      * @param[in] flags Memory flags
      * @param[in] size  Region size
      */
-    CLBufferMemoryRegion(cl::Context ctx, cl_mem_flags flags, size_t size);
+    CLBufferMemoryRegion(CLCoreRuntimeContext *ctx, cl_mem_flags flags, size_t size);
     /** Constructor
      *
      * @param[in] buffer Buffer to be used as a memory region
+     * @param[in] ctx    Runtime context
      */
-    CLBufferMemoryRegion(const cl::Buffer &buffer);
+    CLBufferMemoryRegion(const cl::Buffer &buffer, CLCoreRuntimeContext *ctx);
 
     // Inherited methods overridden :
     void *ptr() final;
@@ -120,12 +123,12 @@
 protected:
     /** Constructor
      *
-     * @param[in] ctx       OpenCL context
+     * @param[in] ctx       Runtime context
      * @param[in] flags     Memory flags
      * @param[in] size      Region size
      * @param[in] alignment Alignment
      */
-    ICLSVMMemoryRegion(cl::Context ctx, cl_mem_flags flags, size_t size, size_t alignment);
+    ICLSVMMemoryRegion(CLCoreRuntimeContext *ctx, cl_mem_flags flags, size_t size, size_t alignment);
     /** Destructor */
     virtual ~ICLSVMMemoryRegion();
     /** Prevent instances of this class from being copied (As this class contains pointers) */
@@ -150,12 +153,12 @@
 public:
     /** Constructor
      *
-     * @param[in] ctx       OpenCL context
+     * @param[in] ctx       Runtime context
      * @param[in] flags     Memory flags
      * @param[in] size      Region size
      * @param[in] alignment Alignment
      */
-    CLCoarseSVMMemoryRegion(cl::Context ctx, cl_mem_flags flags, size_t size, size_t alignment);
+    CLCoarseSVMMemoryRegion(CLCoreRuntimeContext *ctx, cl_mem_flags flags, size_t size, size_t alignment);
 
     // Inherited methods overridden :
     void *map(cl::CommandQueue &q, bool blocking) final;
@@ -168,12 +171,12 @@
 public:
     /** Constructor
      *
-     * @param[in] ctx       OpenCL context
+     * @param[in] ctx       Runtime context
      * @param[in] flags     Memory flags
      * @param[in] size      Region size
      * @param[in] alignment Alignment
      */
-    CLFineSVMMemoryRegion(cl::Context ctx, cl_mem_flags flags, size_t size, size_t alignment);
+    CLFineSVMMemoryRegion(CLCoreRuntimeContext *ctx, cl_mem_flags flags, size_t size, size_t alignment);
 
     // Inherited methods overridden :
     void *map(cl::CommandQueue &q, bool blocking) final;
diff --git a/arm_compute/runtime/CL/CLRuntimeContext.h b/arm_compute/runtime/CL/CLRuntimeContext.h
new file mode 100644
index 0000000..971dfd2
--- /dev/null
+++ b/arm_compute/runtime/CL/CLRuntimeContext.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2019 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __ARM_COMPUTE_CLRUNTIME_CONTEXT_H__
+#define __ARM_COMPUTE_CLRUNTIME_CONTEXT_H__
+
+#include "arm_compute/core/CL/CLCoreRuntimeContext.h"
+#include "arm_compute/core/CL/CLKernelLibrary.h"
+#include "arm_compute/core/CL/OpenCL.h"
+#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "arm_compute/runtime/CL/CLTuner.h"
+#include "arm_compute/runtime/IScheduler.h"
+#include "arm_compute/runtime/RuntimeContext.h"
+
+namespace arm_compute
+{
+/** Runtime context */
+class CLRuntimeContext : public RuntimeContext
+{
+public:
+    /** Default Constructor */
+    CLRuntimeContext();
+    /** Destructor */
+    ~CLRuntimeContext() = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    CLRuntimeContext(const CLRuntimeContext &) = delete;
+    /** Default move constructor */
+    CLRuntimeContext(CLRuntimeContext &&) = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    CLRuntimeContext &operator=(const CLRuntimeContext &) = delete;
+    /** Default move assignment operator */
+    CLRuntimeContext &operator=(CLRuntimeContext &&) = default;
+    /** CPU Scheduler setter */
+    void set_gpu_scheduler(CLScheduler *scheduler);
+
+    // Inherited overridden methods
+    CLScheduler          *gpu_scheduler();
+    CLKernelLibrary      &kernel_library();
+    CLCoreRuntimeContext *core_runtime_context();
+
+private:
+    std::unique_ptr<CLScheduler> _gpu_owned_scheduler{ nullptr };
+    CLScheduler                 *_gpu_scheduler{ nullptr };
+    CLTuner                      _tuner{ false };
+    CLKernelLibrary              _kernel_lib{};
+    CLSymbols                    _symbols{};
+    CLCoreRuntimeContext         _core_context{};
+};
+} // namespace arm_compute
+#endif /*__ARM_COMPUTE_CLRUNTIME_CONTEXT_H__ */
diff --git a/arm_compute/runtime/CL/CLScheduler.h b/arm_compute/runtime/CL/CLScheduler.h
index 53cb88a..720c8b3 100644
--- a/arm_compute/runtime/CL/CLScheduler.h
+++ b/arm_compute/runtime/CL/CLScheduler.h
@@ -25,7 +25,6 @@
 #define __ARM_COMPUTE_CLSCHEDULER_H__
 
 #include "arm_compute/core/CL/CLHelpers.h"
-#include "arm_compute/core/CL/CLKernelLibrary.h"
 #include "arm_compute/core/CL/CLTypes.h"
 #include "arm_compute/core/CL/OpenCL.h"
 #include "arm_compute/core/Error.h"
@@ -35,21 +34,21 @@
 namespace arm_compute
 {
 class ICLKernel;
-
+class ICLTuner;
 /** Provides global access to a CL context and command queue. */
-class CLScheduler
+class CLScheduler final
 {
-private:
+public:
     /** Constructor */
     CLScheduler();
     /** Prevent instances of this class from being copied (As this class contains pointers) */
     CLScheduler(const CLScheduler &) = delete;
     /** Prevent instances of this class from being copied (As this class contains pointers) */
     CLScheduler &operator=(const CLScheduler &) = delete;
-
-public:
+    /** Default destructor */
+    ~CLScheduler() = default;
     /** Access the scheduler singleton.
-     *
+     * This method has been deprecated and will be removed in future releases
      * @return The scheduler
      */
     static CLScheduler &get();
@@ -88,31 +87,19 @@
      *
      * @return A CL context.
      */
-    cl::Context &context()
-    {
-        ARM_COMPUTE_ERROR_ON(!_is_initialised);
-        _context = CLKernelLibrary::get().context();
-        return _context;
-    }
+    cl::Context &context();
 
     /** Accessor for the associated CL command queue.
      *
      * @return A CL command queue.
      */
-    cl::CommandQueue &queue()
-    {
-        ARM_COMPUTE_ERROR_ON(!_is_initialised);
-        return _queue;
-    }
+    cl::CommandQueue &queue();
 
     /** Get the target GPU.
      *
      * @return The target GPU.
      */
-    GPUTarget target() const
-    {
-        return _target;
-    }
+    GPUTarget target() const;
 
     /** Accessor to set the CL context to be used by the scheduler.
      *
@@ -124,63 +111,36 @@
      *
      * @param[in] queue A CL command queue.
      */
-    void set_queue(cl::CommandQueue queue)
-    {
-        _queue = std::move(queue);
-    }
+    void set_queue(cl::CommandQueue queue);
 
     /** Accessor to set target GPU to be used by the scheduler.
      *
      * @param[in] target The target GPU.
      */
-    void set_target(GPUTarget target)
-    {
-        _target = target;
-    }
+    void set_target(GPUTarget target);
 
     /** Accessor to set the CL tuner to be used by the scheduler.
      *
      * @param[in] tuner A CL tuner
      */
-    void set_tuner(ICLTuner *tuner)
-    {
-        _cl_tuner = tuner;
-    }
+    void set_tuner(ICLTuner *tuner);
 
     /** Blocks until all commands in the associated command queue have finished. */
-    void sync()
-    {
-        _queue.finish();
-    }
+    void sync();
 
     /** Enqueues a marker into the associated command queue and return the event.
      *
      * @return An event that can be waited on to block the executing thread.
      */
-    cl::Event enqueue_sync_event()
-    {
-        cl::Event event;
-        _queue.enqueueMarker(&event);
-
-        return event;
-    }
+    cl::Event enqueue_sync_event();
 
     /** Tunes OpenCL kernel
      *
      * @param[in] kernel Kernel to tune
      */
-    void tune_kernel_static(ICLKernel &kernel)
-    {
-        if(_cl_tuner != nullptr)
-        {
-            _cl_tuner->tune_kernel_static(kernel);
-        }
-    }
+    void tune_kernel_static(ICLKernel &kernel);
 
-    bool is_initialised() const
-    {
-        return _is_initialised;
-    }
+    bool is_initialised() const;
 
 private:
     /** Flag to ensure symbols initialisation is happening before Scheduler creation */
diff --git a/arm_compute/runtime/CL/CLTensor.h b/arm_compute/runtime/CL/CLTensor.h
index bc72839..c108d1a 100644
--- a/arm_compute/runtime/CL/CLTensor.h
+++ b/arm_compute/runtime/CL/CLTensor.h
@@ -35,13 +35,32 @@
 // Forward declarations
 class ITensorAllocator;
 class ITensorInfo;
-
+class IRuntimeContext;
+class CLRuntimeContext;
 /** Basic implementation of the OpenCL tensor interface */
 class CLTensor : public ICLTensor, public IMemoryManageable
 {
 public:
-    /** Constructor */
-    CLTensor();
+    /** Constructor.
+     *
+     * @param[in] ctx (Optional)  Pointer to a @ref CLRuntimeContext.
+     *                            If nullptr is passed in, the legacy api using the singletons will be used. Otherwise the memory for the
+     *                            tensor will allocate on the context passed in.
+     *                            The singletons legacy api has been deprecated and will be removed.
+     */
+    CLTensor(IRuntimeContext *ctx = nullptr);
+
+    /** Destructor */
+    ~CLTensor() = default;
+    /** Default copy constructor */
+    CLTensor(const CLTensor &) = default;
+    /** Default move constructor */
+    CLTensor(CLTensor &&) = default;
+    /** Default copy assignment */
+    CLTensor &operator=(const CLTensor &) = default;
+    /** Default move assignment operator */
+    CLTensor &operator=(CLTensor &&) = default;
+
     /** Return a pointer to the tensor's allocator
      *
      * @return A pointer to the tensor's allocator
@@ -69,6 +88,7 @@
     const cl::Buffer &cl_buffer() const override;
     CLQuantization    quantization() const override;
     void associate_memory_group(IMemoryGroup *memory_group) override;
+    CLRuntimeContext *context();
 
 protected:
     // Inherited methods overridden:
@@ -77,6 +97,7 @@
 
 private:
     mutable CLTensorAllocator _allocator; /**< Instance of the OpenCL tensor allocator */
+    CLRuntimeContext         *_ctx{ nullptr };
 };
 
 /** OpenCL Image */
diff --git a/arm_compute/runtime/CL/CLTensorAllocator.h b/arm_compute/runtime/CL/CLTensorAllocator.h
index 3450c72..b3ffd8b 100644
--- a/arm_compute/runtime/CL/CLTensorAllocator.h
+++ b/arm_compute/runtime/CL/CLTensorAllocator.h
@@ -37,7 +37,7 @@
 namespace arm_compute
 {
 class CLTensor;
-
+class CLRuntimeContext;
 /** Basic implementation of a CL memory tensor allocator. */
 class CLTensorAllocator : public ITensorAllocator
 {
@@ -45,8 +45,9 @@
     /** Default constructor.
      *
      * @param[in] owner (Optional) Owner of the allocator.
+     * @param[in] ctx   (Optional) Runtime context.
      */
-    CLTensorAllocator(IMemoryManageable *owner = nullptr);
+    CLTensorAllocator(IMemoryManageable *owner = nullptr, CLRuntimeContext *ctx = nullptr);
     /** Prevent instances of this class from being copied (As this class contains pointers) */
     CLTensorAllocator(const CLTensorAllocator &) = delete;
     /** Prevent instances of this class from being copy assigned (As this class contains pointers) */
@@ -139,6 +140,7 @@
     static const cl::Buffer _empty_buffer;
 
 private:
+    CLRuntimeContext *_ctx;
     IMemoryManageable *_owner;                   /**< Memory manageable object that owns the allocator */
     IMemoryGroup      *_associated_memory_group; /**< Registered memory manager */
     CLMemory           _memory;                  /**< OpenCL memory */
diff --git a/arm_compute/runtime/CL/ICLSimpleFunction.h b/arm_compute/runtime/CL/ICLSimpleFunction.h
index 130c58a..8399a3d 100644
--- a/arm_compute/runtime/CL/ICLSimpleFunction.h
+++ b/arm_compute/runtime/CL/ICLSimpleFunction.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017 ARM Limited.
+ * Copyright (c) 2016-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -32,12 +32,25 @@
 
 namespace arm_compute
 {
+class CLRuntimeContext;
 /** Basic interface for functions which have a single OpenCL kernel */
 class ICLSimpleFunction : public IFunction
 {
 public:
-    /** Default constructor */
-    ICLSimpleFunction();
+    /** Constructor
+     *
+     * @param[in] ctx Runtime context to be used by the function
+     */
+    ICLSimpleFunction(CLRuntimeContext *ctx = nullptr);
+
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    ICLSimpleFunction(const ICLSimpleFunction &) = delete;
+    /** Default move constructor */
+    ICLSimpleFunction(ICLSimpleFunction &&) = default;
+    /** Prevent instances of this class from being copied (As this class contains pointers) */
+    ICLSimpleFunction &operator=(const ICLSimpleFunction &) = delete;
+    /** Default move assignment operator */
+    ICLSimpleFunction &operator=(ICLSimpleFunction &&) = default;
 
     // Inherited methods overridden:
     void run() override final;
@@ -45,6 +58,7 @@
 protected:
     std::unique_ptr<ICLKernel> _kernel;         /**< Kernel to run */
     CLFillBorderKernel         _border_handler; /**< Kernel to handle  borders */
+    CLRuntimeContext          *_ctx;            /**< Context to use */
 };
 }
 #endif /*__ARM_COMPUTE_ICLSIMPLEFUNCTION_H__ */
diff --git a/arm_compute/runtime/CL/functions/CLActivationLayer.h b/arm_compute/runtime/CL/functions/CLActivationLayer.h
index 1201d7d..e1e3e87 100644
--- a/arm_compute/runtime/CL/functions/CLActivationLayer.h
+++ b/arm_compute/runtime/CL/functions/CLActivationLayer.h
@@ -43,7 +43,7 @@
      *
      * @param[in] ctx Runtime context to be used by the function
      */
-    CLActivationLayer(void *ctx = nullptr);
+    CLActivationLayer(CLRuntimeContext *ctx = nullptr);
     /** Prevent instances of this class from being copied (As this class contains pointers) */
     CLActivationLayer(const CLActivationLayer &) = delete;
     /** Default move constructor */
diff --git a/arm_compute/runtime/GLES_COMPUTE/GCTensor.h b/arm_compute/runtime/GLES_COMPUTE/GCTensor.h
index 344c788..a308ba0 100644
--- a/arm_compute/runtime/GLES_COMPUTE/GCTensor.h
+++ b/arm_compute/runtime/GLES_COMPUTE/GCTensor.h
@@ -32,13 +32,18 @@
 {
 class ITensorAllocator;
 class ITensorInfo;
+class IRuntimeContext;
 
 /** Interface for OpenGL ES tensor */
 class GCTensor : public IGCTensor, public IMemoryManageable
 {
 public:
-    /** Default constructor */
-    GCTensor();
+    /** Default constructor
+     *
+     * @param[in] ctx (Optional) Pointer to the runtime context.
+     *
+     */
+    GCTensor(IRuntimeContext *ctx = nullptr);
 
     /** Prevent instances of this class from being copied (As this class contains pointers) */
     GCTensor(const GCTensor &) = delete;
diff --git a/arm_compute/runtime/Tensor.h b/arm_compute/runtime/Tensor.h
index 6fa7c8c..e469f70 100644
--- a/arm_compute/runtime/Tensor.h
+++ b/arm_compute/runtime/Tensor.h
@@ -32,13 +32,17 @@
 namespace arm_compute
 {
 class ITensorInfo;
-
+class IRuntimeContext;
 /** Basic implementation of the tensor interface */
 class Tensor : public ITensor, public IMemoryManageable
 {
 public:
-    /** Constructor */
-    Tensor();
+    /** Constructor
+     *
+     * @param[in] ctx (Optional) Pointer to the runtime context.
+     *
+     */
+    Tensor(IRuntimeContext *ctx = nullptr);
     /** Destructor: free the tensor's memory */
     ~Tensor() = default;
     /** Allow instances of this class to be move constructed */