aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Tello <pablo.tello@arm.com>2019-09-24 11:03:47 +0100
committerPablo Marquez <pablo.tello@arm.com>2019-10-15 14:05:55 +0000
commitdb8485ac24135f17e9882c76196924435abc064f (patch)
treedfe4ff6a50012ac93c6b1cf3fb29c099a7592522
parenta046e164b96a8441b2fa14ef578f7db46a0e97da (diff)
downloadComputeLibrary-db8485ac24135f17e9882c76196924435abc064f.tar.gz
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>
-rw-r--r--arm_compute/core/CL/CLCoreRuntimeContext.h63
-rw-r--r--arm_compute/core/CL/CLHelpers.h13
-rw-r--r--arm_compute/core/CL/CLKernelLibrary.h78
-rw-r--r--arm_compute/core/CL/OpenCL.h3
-rw-r--r--arm_compute/core/CL/kernels/CLActivationLayerKernel.h11
-rw-r--r--arm_compute/graph/backends/CL/CLDeviceBackend.h10
-rw-r--r--arm_compute/runtime/CL/CLBufferAllocator.h20
-rw-r--r--arm_compute/runtime/CL/CLHelpers.h10
-rw-r--r--arm_compute/runtime/CL/CLMemoryRegion.h33
-rw-r--r--arm_compute/runtime/CL/CLRuntimeContext.h70
-rw-r--r--arm_compute/runtime/CL/CLScheduler.h74
-rw-r--r--arm_compute/runtime/CL/CLTensor.h27
-rw-r--r--arm_compute/runtime/CL/CLTensorAllocator.h6
-rw-r--r--arm_compute/runtime/CL/ICLSimpleFunction.h20
-rw-r--r--arm_compute/runtime/CL/functions/CLActivationLayer.h2
-rw-r--r--arm_compute/runtime/GLES_COMPUTE/GCTensor.h9
-rw-r--r--arm_compute/runtime/Tensor.h10
-rw-r--r--src/core/CL/CLCoreRuntimeContext.cpp52
-rw-r--r--src/core/CL/CLHelpers.cpp16
-rw-r--r--src/core/CL/CLKernelLibrary.cpp65
-rw-r--r--src/core/CL/OpenCL.cpp5
-rw-r--r--src/core/CL/kernels/CLActivationLayerKernel.cpp8
-rw-r--r--src/graph/backends/CL/CLDeviceBackend.cpp7
-rw-r--r--src/runtime/CL/CLBufferAllocator.cpp27
-rw-r--r--src/runtime/CL/CLHelpers.cpp16
-rw-r--r--src/runtime/CL/CLMemoryRegion.cpp39
-rw-r--r--src/runtime/CL/CLRuntimeContext.cpp67
-rw-r--r--src/runtime/CL/CLScheduler.cpp70
-rw-r--r--src/runtime/CL/CLTensor.cpp16
-rw-r--r--src/runtime/CL/CLTensorAllocator.cpp54
-rw-r--r--src/runtime/CL/ICLSimpleFunction.cpp13
-rw-r--r--src/runtime/CL/functions/CLActivationLayer.cpp9
-rw-r--r--src/runtime/GLES_COMPUTE/GCTensor.cpp4
-rw-r--r--src/runtime/Tensor.cpp4
-rw-r--r--tests/Globals.h2
-rw-r--r--tests/Utils.h10
-rw-r--r--tests/framework/Framework.cpp28
-rw-r--r--tests/framework/ParametersLibrary.cpp (renamed from tests/ParametersLibrary.cpp)15
-rw-r--r--tests/framework/ParametersLibrary.h (renamed from tests/ParametersLibrary.h)29
-rw-r--r--tests/main.cpp33
-rw-r--r--tests/validation/CL/ActivationLayer.cpp9
-rw-r--r--tests/validation/fixtures/ActivationLayerFixture.h14
-rw-r--r--utils/Utils.cpp1
43 files changed, 802 insertions, 270 deletions
diff --git a/arm_compute/core/CL/CLCoreRuntimeContext.h b/arm_compute/core/CL/CLCoreRuntimeContext.h
new file mode 100644
index 0000000000..6e2bd43d53
--- /dev/null
+++ b/arm_compute/core/CL/CLCoreRuntimeContext.h
@@ -0,0 +1,63 @@
+/*
+ * 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_CLCORERUNTIME_CONTEXT_H__
+#define __ARM_COMPUTE_CLCORERUNTIME_CONTEXT_H__
+
+#include "arm_compute/core/CL/OpenCL.h"
+
+namespace arm_compute
+{
+class CLKernelLibrary;
+/** Core runtime context */
+class CLCoreRuntimeContext final
+{
+public:
+ /** Legacy constructor */
+ CLCoreRuntimeContext();
+
+ /** Constructor */
+ CLCoreRuntimeContext(CLKernelLibrary *kernel_lib, cl::Context ctx, cl::CommandQueue queue);
+ /** Destructor */
+ ~CLCoreRuntimeContext() = default;
+ /** Default copy constructor */
+ CLCoreRuntimeContext(const CLCoreRuntimeContext &) = default;
+ /** Default move constructor */
+ CLCoreRuntimeContext(CLCoreRuntimeContext &&) = default;
+ /** Default copy assignment */
+ CLCoreRuntimeContext &operator=(const CLCoreRuntimeContext &) = default;
+ /** Default move assignment operator */
+ CLCoreRuntimeContext &operator=(CLCoreRuntimeContext &&) = default;
+ /** CPU Scheduler setter */
+
+ CLKernelLibrary *kernel_library() const;
+ cl::Context context();
+ cl::CommandQueue queue();
+
+private:
+ CLKernelLibrary *_kernel_lib{ nullptr };
+ cl::Context _ctx{};
+ cl::CommandQueue _queue{};
+};
+} // namespace arm_compute
+#endif /*__ARM_COMPUTE_CLCORERUNTIME_CONTEXT_H__ */
diff --git a/arm_compute/core/CL/CLHelpers.h b/arm_compute/core/CL/CLHelpers.h
index 16fe09fb96..1d647a86b0 100644
--- a/arm_compute/core/CL/CLHelpers.h
+++ b/arm_compute/core/CL/CLHelpers.h
@@ -34,6 +34,9 @@
namespace arm_compute
{
+class CLCoreRuntimeContext;
+class CLBuildOptions;
+
enum class DataType;
/** Max vector width of an OpenCL vector */
@@ -153,5 +156,15 @@ size_t preferred_vector_width(const cl::Device &device, DataType dt);
* @return True if dummy work-items should be preferred to dispatch the NDRange
*/
bool preferred_dummy_work_items_support(const cl::Device &device);
+
+/** Creates an opencl kernel
+ *
+ * @param[in] ctx A context to be used to create the opencl kernel.
+ * @param[in] kernel_name The kernel name.
+ * @param[in] build_opts The build options to be used for the opencl kernel compilation.
+ *
+ * @return An opencl kernel
+ */
+cl::Kernel create_opencl_kernel(CLCoreRuntimeContext *ctx, const std::string &kernel_name, const CLBuildOptions &build_opts);
}
#endif /* __ARM_COMPUTE_CLHELPERS_H__ */
diff --git a/arm_compute/core/CL/CLKernelLibrary.h b/arm_compute/core/CL/CLKernelLibrary.h
index 9f183f1232..f2282692f9 100644
--- a/arm_compute/core/CL/CLKernelLibrary.h
+++ b/arm_compute/core/CL/CLKernelLibrary.h
@@ -34,7 +34,7 @@
namespace arm_compute
{
/** Build options */
-class CLBuildOptions
+class CLBuildOptions final
{
using StringSet = std::set<std::string>;
@@ -80,7 +80,7 @@ private:
StringSet _build_opts; /**< Build options set */
};
/** Program class */
-class Program
+class Program final
{
public:
/** Default constructor. */
@@ -147,7 +147,7 @@ private:
};
/** Kernel class */
-class Kernel
+class Kernel final
{
public:
/** Default Constructor. */
@@ -189,20 +189,19 @@ private:
};
/** CLKernelLibrary class */
-class CLKernelLibrary
+class CLKernelLibrary final
{
using StringSet = std::set<std::string>;
-private:
+public:
/** Default Constructor. */
CLKernelLibrary();
-
-public:
/** Prevent instances of this class from being copied */
CLKernelLibrary(const CLKernelLibrary &) = delete;
/** Prevent instances of this class from being copied */
const CLKernelLibrary &operator=(const CLKernelLibrary &) = delete;
/** Access the KernelLibrary singleton.
+ * This method has been deprecated and will be removed in the next release.
* @return The KernelLibrary instance.
*/
static CLKernelLibrary &get();
@@ -212,26 +211,15 @@ public:
* @param[in] context CL context used to create programs.
* @param[in] device CL device for which the programs are created.
*/
- void init(std::string kernel_path, cl::Context context, cl::Device device)
- {
- _kernel_path = std::move(kernel_path);
- _context = std::move(context);
- _device = std::move(device);
- }
+ void init(std::string kernel_path, cl::Context context, cl::Device device);
/** Sets the path that the kernels reside in.
*
* @param[in] kernel_path Path of the kernel.
*/
- void set_kernel_path(const std::string &kernel_path)
- {
- _kernel_path = kernel_path;
- };
+ void set_kernel_path(const std::string &kernel_path);
/** Gets the path that the kernels reside in.
*/
- std::string get_kernel_path()
- {
- return _kernel_path;
- };
+ std::string get_kernel_path();
/** Gets the source of the selected program.
*
* @param[in] program_name Program name.
@@ -246,51 +234,22 @@ public:
*
* @param[in] context A CL context.
*/
- void set_context(cl::Context context)
- {
- _context = std::move(context);
- if(_context.get() == nullptr)
- {
- _device = cl::Device();
- }
- else
- {
- const auto cl_devices = _context.getInfo<CL_CONTEXT_DEVICES>();
-
- if(cl_devices.empty())
- {
- _device = cl::Device();
- }
- else
- {
- _device = cl_devices[0];
- }
- }
- }
+ void set_context(cl::Context context);
/** Accessor for the associated CL context.
*
* @return A CL context.
*/
- cl::Context &context()
- {
- return _context;
- }
+ cl::Context &context();
/** Gets the CL device for which the programs are created. */
- cl::Device &get_device()
- {
- return _device;
- }
+ cl::Device &get_device();
/** Sets the CL device for which the programs are created.
*
* @param[in] device A CL device.
*/
- void set_device(cl::Device device)
- {
- _device = std::move(device);
- }
+ void set_device(cl::Device device);
/** Return the device version
*
@@ -321,17 +280,10 @@ public:
/** Clear the library's cache of binary programs
*/
- void clear_programs_cache()
- {
- _programs_map.clear();
- _built_programs_map.clear();
- }
+ void clear_programs_cache();
/** Access the cache of built OpenCL programs */
- const std::map<std::string, cl::Program> &get_built_programs() const
- {
- return _built_programs_map;
- }
+ const std::map<std::string, cl::Program> &get_built_programs() const;
/** Add a new built program to the cache
*
diff --git a/arm_compute/core/CL/OpenCL.h b/arm_compute/core/CL/OpenCL.h
index 912a53103a..b1d50e73b1 100644
--- a/arm_compute/core/CL/OpenCL.h
+++ b/arm_compute/core/CL/OpenCL.h
@@ -60,11 +60,10 @@ bool opencl_is_available();
/** Class for loading OpenCL symbols. */
class CLSymbols final
{
-private:
+public:
CLSymbols() = default;
void load_symbols(void *handle);
-public:
/** Get the static instance of CLSymbols.
*
* @return The static instance of CLSymbols.
diff --git a/arm_compute/core/CL/kernels/CLActivationLayerKernel.h b/arm_compute/core/CL/kernels/CLActivationLayerKernel.h
index f20d6c3362..c64f7c42ac 100644
--- a/arm_compute/core/CL/kernels/CLActivationLayerKernel.h
+++ b/arm_compute/core/CL/kernels/CLActivationLayerKernel.h
@@ -29,13 +29,13 @@
namespace arm_compute
{
class ICLTensor;
-
+class CLCoreRuntimeContext;
/** Interface for the activation layer kernel. */
class CLActivationLayerKernel : public ICLKernel
{
public:
/** Default constructor */
- CLActivationLayerKernel();
+ CLActivationLayerKernel(CLCoreRuntimeContext *ctx = nullptr);
/** Prevent instances of this class from being copied (As this class contains pointers) */
CLActivationLayerKernel(const CLActivationLayerKernel &) = delete;
/** Prevent instances of this class from being copied (As this class contains pointers) */
@@ -71,9 +71,10 @@ public:
void run(const Window &window, cl::CommandQueue &queue) override;
private:
- ICLTensor *_input;
- ICLTensor *_output;
- bool _run_in_place;
+ ICLTensor *_input;
+ ICLTensor *_output;
+ bool _run_in_place;
+ CLCoreRuntimeContext *_ctx;
};
} // namespace arm_compute
#endif /*__ARM_COMPUTE_CLACTIVATIONLAYERKERNEL_H__ */
diff --git a/arm_compute/graph/backends/CL/CLDeviceBackend.h b/arm_compute/graph/backends/CL/CLDeviceBackend.h
index 8569cf1f34..1239d5d3ad 100644
--- a/arm_compute/graph/backends/CL/CLDeviceBackend.h
+++ b/arm_compute/graph/backends/CL/CLDeviceBackend.h
@@ -31,6 +31,7 @@
namespace arm_compute
{
+class CLCoreRuntimeContext;
namespace graph
{
namespace backends
@@ -70,10 +71,11 @@ public:
std::shared_ptr<arm_compute::IWeightsManager> create_weights_manager() override;
private:
- int _context_count; /**< Counts how many contexts are currently using the backend */
- CLTuner _tuner; /**< CL kernel tuner */
- std::unique_ptr<CLBufferAllocator> _allocator; /**< CL buffer affinity allocator */
- std::string _tuner_file; /**< Filename to load/store the tuner's values from */
+ int _context_count; /**< Counts how many contexts are currently using the backend */
+ CLTuner _tuner; /**< CL kernel tuner */
+ std::unique_ptr<CLBufferAllocator> _allocator; /**< CL buffer affinity allocator */
+ std::string _tuner_file; /**< Filename to load/store the tuner's values from */
+ std::unique_ptr<CLCoreRuntimeContext> _legacy_ctx;
};
} // namespace backends
} // namespace graph
diff --git a/arm_compute/runtime/CL/CLBufferAllocator.h b/arm_compute/runtime/CL/CLBufferAllocator.h
index 19a3e627ca..772402270b 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 @@ public:
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 f3b11f8b75..84f155afd2 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 @@ namespace arm_compute
* 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 dbfd8225ca..6f7c3cd9a8 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 @@ public:
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 @@ class CLBufferMemoryRegion final : public ICLMemoryRegion
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 @@ class ICLSVMMemoryRegion : public ICLMemoryRegion
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 @@ class CLCoarseSVMMemoryRegion final : public ICLSVMMemoryRegion
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 @@ class CLFineSVMMemoryRegion final : public ICLSVMMemoryRegion
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 0000000000..971dfd2224
--- /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 53cb88ad5b..720c8b37f5 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 @@ public:
*
* @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 @@ public:
*
* @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);
- }
- }
-
- bool is_initialised() const
- {
- return _is_initialised;
- }
+ void tune_kernel_static(ICLKernel &kernel);
+
+ 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 bc72839492..c108d1afad 100644
--- a/arm_compute/runtime/CL/CLTensor.h
+++ b/arm_compute/runtime/CL/CLTensor.h
@@ -35,13 +35,32 @@ namespace arm_compute
// 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 @@ public:
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 @@ protected:
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 3450c72d61..b3ffd8b949 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 @@ public:
/** 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 @@ private:
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 130c58a98c..8399a3d58e 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 @@ public:
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 1201d7d355..e1e3e877d5 100644
--- a/arm_compute/runtime/CL/functions/CLActivationLayer.h
+++ b/arm_compute/runtime/CL/functions/CLActivationLayer.h
@@ -43,7 +43,7 @@ public:
*
* @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 344c78852b..a308ba0237 100644
--- a/arm_compute/runtime/GLES_COMPUTE/GCTensor.h
+++ b/arm_compute/runtime/GLES_COMPUTE/GCTensor.h
@@ -32,13 +32,18 @@ namespace arm_compute
{
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 6fa7c8ca0e..e469f70817 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 */
diff --git a/src/core/CL/CLCoreRuntimeContext.cpp b/src/core/CL/CLCoreRuntimeContext.cpp
new file mode 100644
index 0000000000..f9efad2c0d
--- /dev/null
+++ b/src/core/CL/CLCoreRuntimeContext.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+#include "arm_compute/core/CL/CLCoreRuntimeContext.h"
+
+namespace arm_compute
+{
+cl::Context CLCoreRuntimeContext::context()
+{
+ return _ctx;
+}
+
+cl::CommandQueue CLCoreRuntimeContext::queue()
+{
+ return _queue;
+}
+
+CLCoreRuntimeContext::CLCoreRuntimeContext()
+ : _kernel_lib(nullptr), _ctx(), _queue()
+{
+}
+
+CLCoreRuntimeContext::CLCoreRuntimeContext(CLKernelLibrary *kernel_lib, cl::Context ctx, cl::CommandQueue queue)
+ : _kernel_lib(kernel_lib), _ctx(ctx), _queue(queue)
+{
+}
+
+CLKernelLibrary *CLCoreRuntimeContext::kernel_library() const
+{
+ return _kernel_lib;
+}
+} // namespace arm_compute
diff --git a/src/core/CL/CLHelpers.cpp b/src/core/CL/CLHelpers.cpp
index d051810090..a3c73677c7 100644
--- a/src/core/CL/CLHelpers.cpp
+++ b/src/core/CL/CLHelpers.cpp
@@ -22,6 +22,8 @@
* SOFTWARE.
*/
#include "arm_compute/core/CL/CLHelpers.h"
+#include "arm_compute/core/CL/CLCoreRuntimeContext.h"
+#include "arm_compute/core/CL/CLKernelLibrary.h"
#include "arm_compute/core/CL/CLTypes.h"
#include "arm_compute/core/Error.h"
#include "arm_compute/core/Log.h"
@@ -283,4 +285,18 @@ bool preferred_dummy_work_items_support(const cl::Device &device)
// TODO (COMPMID-2044)
return true;
}
+
+cl::Kernel create_opencl_kernel(CLCoreRuntimeContext *ctx, const std::string &kernel_name, const CLBuildOptions &build_opts)
+{
+ if(ctx && ctx->kernel_library())
+ {
+ //New api going through the core context
+ return static_cast<cl::Kernel>(ctx->kernel_library()->create_kernel(kernel_name, build_opts.options()));
+ }
+ else
+ {
+ //Legacy code through the singleton
+ return static_cast<cl::Kernel>(CLKernelLibrary::get().create_kernel(kernel_name, build_opts.options()));
+ }
+}
} // namespace arm_compute
diff --git a/src/core/CL/CLKernelLibrary.cpp b/src/core/CL/CLKernelLibrary.cpp
index 7b7263fca7..c27f886129 100644
--- a/src/core/CL/CLKernelLibrary.cpp
+++ b/src/core/CL/CLKernelLibrary.cpp
@@ -1144,6 +1144,49 @@ Kernel CLKernelLibrary::create_kernel(const std::string &kernel_name, const Stri
return Kernel(kernel_name, cl_program);
}
+void CLKernelLibrary::init(std::string kernel_path, cl::Context context, cl::Device device)
+{
+ _kernel_path = std::move(kernel_path);
+ _context = std::move(context);
+ _device = std::move(device);
+}
+
+void CLKernelLibrary::set_kernel_path(const std::string &kernel_path)
+{
+ _kernel_path = kernel_path;
+}
+
+cl::Context &CLKernelLibrary::context()
+{
+ return _context;
+}
+
+cl::Device &CLKernelLibrary::get_device()
+{
+ return _device;
+}
+
+void CLKernelLibrary::set_device(cl::Device device)
+{
+ _device = std::move(device);
+}
+
+std::string CLKernelLibrary::get_kernel_path()
+{
+ return _kernel_path;
+}
+
+void CLKernelLibrary::clear_programs_cache()
+{
+ _programs_map.clear();
+ _built_programs_map.clear();
+}
+
+const std::map<std::string, cl::Program> &CLKernelLibrary::get_built_programs() const
+{
+ return _built_programs_map;
+}
+
void CLKernelLibrary::add_built_program(const std::string &built_program_name, const cl::Program &program)
{
_built_programs_map.emplace(built_program_name, program);
@@ -1205,6 +1248,28 @@ const Program &CLKernelLibrary::load_program(const std::string &program_name) co
return new_program.first->second;
}
+void CLKernelLibrary::set_context(cl::Context context)
+{
+ _context = std::move(context);
+ if(_context.get() == nullptr)
+ {
+ _device = cl::Device();
+ }
+ else
+ {
+ const auto cl_devices = _context.getInfo<CL_CONTEXT_DEVICES>();
+
+ if(cl_devices.empty())
+ {
+ _device = cl::Device();
+ }
+ else
+ {
+ _device = cl_devices[0];
+ }
+ }
+}
+
std::string CLKernelLibrary::stringify_set(const StringSet &s) const
{
std::string concat_set;
diff --git a/src/core/CL/OpenCL.cpp b/src/core/CL/OpenCL.cpp
index 1ce1b526d7..74c5b041d7 100644
--- a/src/core/CL/OpenCL.cpp
+++ b/src/core/CL/OpenCL.cpp
@@ -27,6 +27,8 @@
#include "arm_compute/core/CL/OpenCL.h"
#pragma GCC diagnostic pop
+#include "arm_compute/core/Error.h"
+
#include <dlfcn.h>
#include <iostream>
@@ -54,6 +56,7 @@ bool CLSymbols::load_default()
{
if(load(lib))
{
+ ARM_COMPUTE_ERROR_ON_MSG(this->clBuildProgram_ptr == nullptr, "Failed to load OpenCL symbols from shared library");
return true;
}
}
@@ -948,4 +951,4 @@ clImportMemoryARM(cl_context context,
}
return nullptr;
}
-} \ No newline at end of file
+}
diff --git a/src/core/CL/kernels/CLActivationLayerKernel.cpp b/src/core/CL/kernels/CLActivationLayerKernel.cpp
index 97a0ff6c6c..5062fd1801 100644
--- a/src/core/CL/kernels/CLActivationLayerKernel.cpp
+++ b/src/core/CL/kernels/CLActivationLayerKernel.cpp
@@ -23,8 +23,8 @@
*/
#include "arm_compute/core/CL/kernels/CLActivationLayerKernel.h"
+#include "arm_compute/core/CL/CLCoreRuntimeContext.h"
#include "arm_compute/core/CL/CLHelpers.h"
-#include "arm_compute/core/CL/CLKernelLibrary.h"
#include "arm_compute/core/CL/CLValidate.h"
#include "arm_compute/core/CL/ICLTensor.h"
#include "arm_compute/core/Helpers.h"
@@ -111,8 +111,8 @@ std::pair<Status, Window> validate_and_configure_window(ITensorInfo *input, ITen
}
} // namespace
-CLActivationLayerKernel::CLActivationLayerKernel()
- : _input(nullptr), _output(nullptr), _run_in_place(false)
+CLActivationLayerKernel::CLActivationLayerKernel(CLCoreRuntimeContext *ctx)
+ : _input(nullptr), _output(nullptr), _run_in_place(false), _ctx(ctx)
{
}
@@ -205,8 +205,8 @@ void CLActivationLayerKernel::configure(ICLTensor *input, ICLTensor *output, Act
{
kernel_name += perform_activation_in_float ? std::string("_quant_f32") : std::string("_quant");
}
- _kernel = static_cast<cl::Kernel>(CLKernelLibrary::get().create_kernel(kernel_name, build_opts.options()));
+ _kernel = create_opencl_kernel(_ctx, kernel_name, build_opts);
// Make sure _kernel is initialized before calling the parent's configure
_input = input;
_output = output;
diff --git a/src/graph/backends/CL/CLDeviceBackend.cpp b/src/graph/backends/CL/CLDeviceBackend.cpp
index ea3b6b801a..58c666c3cc 100644
--- a/src/graph/backends/CL/CLDeviceBackend.cpp
+++ b/src/graph/backends/CL/CLDeviceBackend.cpp
@@ -34,6 +34,7 @@
#include "arm_compute/graph/backends/CL/CLSubTensorHandle.h"
#include "arm_compute/graph/backends/CL/CLTensorHandle.h"
+#include "arm_compute/core/CL/CLCoreRuntimeContext.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/runtime/BlobLifetimeManager.h"
#include "arm_compute/runtime/CL/CLBufferAllocator.h"
@@ -64,7 +65,7 @@ bool file_exists(const std::string &filename)
static detail::BackendRegistrar<CLDeviceBackend> CLDeviceBackend_registrar(Target::CL);
CLDeviceBackend::CLDeviceBackend()
- : _context_count(0), _tuner(), _allocator(nullptr), _tuner_file()
+ : _context_count(0), _tuner(), _allocator(nullptr), _tuner_file(), _legacy_ctx()
{
}
@@ -91,9 +92,9 @@ void CLDeviceBackend::initialize_backend()
{
// Setup Scheduler
CLScheduler::get().default_init(&_tuner);
-
+ _legacy_ctx = support::cpp14::make_unique<CLCoreRuntimeContext>(nullptr, CLScheduler::get().context(), CLScheduler::get().queue());
// Create allocator with new context
- _allocator = support::cpp14::make_unique<CLBufferAllocator>();
+ _allocator = support::cpp14::make_unique<CLBufferAllocator>(_legacy_ctx.get());
}
void CLDeviceBackend::release_backend_context(GraphContext &ctx)
diff --git a/src/runtime/CL/CLBufferAllocator.cpp b/src/runtime/CL/CLBufferAllocator.cpp
index 84789e70d2..ed27320650 100644
--- a/src/runtime/CL/CLBufferAllocator.cpp
+++ b/src/runtime/CL/CLBufferAllocator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -22,25 +22,35 @@
* SOFTWARE.
*/
#include "arm_compute/runtime/CL/CLBufferAllocator.h"
-#include "arm_compute/runtime/CL/CLMemoryRegion.h"
+#include "arm_compute/core/CL/CLCoreRuntimeContext.h"
#include "arm_compute/core/CL/OpenCL.h"
#include "arm_compute/core/Error.h"
+#include "arm_compute/runtime/CL/CLMemoryRegion.h"
+#include "arm_compute/runtime/CL/CLScheduler.h"
#include "support/ToolchainSupport.h"
#include <cstddef>
-using namespace arm_compute;
-
-CLBufferAllocator::CLBufferAllocator(cl::Context context)
- : _context(std::move(context))
+namespace arm_compute
+{
+CLBufferAllocator::CLBufferAllocator(CLCoreRuntimeContext *ctx)
+ : _ctx(ctx)
{
}
void *CLBufferAllocator::allocate(size_t size, size_t alignment)
{
ARM_COMPUTE_UNUSED(alignment);
- cl_mem buf = clCreateBuffer(_context.get(), CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, size, nullptr, nullptr);
+ cl_mem buf;
+ if(_ctx == nullptr)
+ {
+ buf = clCreateBuffer(CLScheduler::get().context().get(), CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, size, nullptr, nullptr);
+ }
+ else
+ {
+ buf = clCreateBuffer(_ctx->context().get(), CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, size, nullptr, nullptr);
+ }
return static_cast<void *>(buf);
}
@@ -53,5 +63,6 @@ void CLBufferAllocator::free(void *ptr)
std::unique_ptr<IMemoryRegion> CLBufferAllocator::make_region(size_t size, size_t alignment)
{
ARM_COMPUTE_UNUSED(alignment);
- return arm_compute::support::cpp14::make_unique<CLBufferMemoryRegion>(_context, CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, size);
+ return arm_compute::support::cpp14::make_unique<CLBufferMemoryRegion>(_ctx, CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, size);
}
+} // namespace arm_compute
diff --git a/src/runtime/CL/CLHelpers.cpp b/src/runtime/CL/CLHelpers.cpp
index edfc8ed2aa..c4c7ee2107 100644
--- a/src/runtime/CL/CLHelpers.cpp
+++ b/src/runtime/CL/CLHelpers.cpp
@@ -26,6 +26,7 @@
#include "arm_compute/core/CL/CLHelpers.h"
#include "arm_compute/core/Error.h"
+#include "arm_compute/runtime/CL/CLRuntimeContext.h"
namespace
{
@@ -103,4 +104,19 @@ create_opencl_context_and_device()
ARM_COMPUTE_ERROR_ON_MSG(err != CL_SUCCESS, "Failed to create OpenCL context");
return std::make_tuple(cl_context, device, err);
}
+
+void schedule_kernel_on_ctx(CLRuntimeContext *ctx, ICLKernel *kernel, bool flush)
+{
+ ARM_COMPUTE_ERROR_ON_NULLPTR(kernel);
+ if(ctx)
+ {
+ ARM_COMPUTE_ERROR_ON(ctx->gpu_scheduler() == nullptr);
+ ctx->gpu_scheduler()->enqueue(*kernel, flush);
+ }
+ else
+ {
+ CLScheduler::get().enqueue(*kernel, flush);
+ }
+}
+
} // namespace arm_compute
diff --git a/src/runtime/CL/CLMemoryRegion.cpp b/src/runtime/CL/CLMemoryRegion.cpp
index 2976903c93..52906a893f 100644
--- a/src/runtime/CL/CLMemoryRegion.cpp
+++ b/src/runtime/CL/CLMemoryRegion.cpp
@@ -23,13 +23,18 @@
*/
#include "arm_compute/runtime/CL/CLMemoryRegion.h"
+#include "arm_compute/core/CL/CLCoreRuntimeContext.h"
#include "arm_compute/core/Error.h"
#include "arm_compute/runtime/CL/CLScheduler.h"
namespace arm_compute
{
-ICLMemoryRegion::ICLMemoryRegion(cl::Context ctx, size_t size)
- : IMemoryRegion(size), _ctx(std::move(ctx)), _mapping(nullptr), _mem()
+ICLMemoryRegion::ICLMemoryRegion(CLCoreRuntimeContext *ctx, size_t size)
+ : IMemoryRegion(size),
+ _queue((ctx != nullptr) ? ctx->queue() : CLScheduler::get().queue()),
+ _ctx((ctx != nullptr) ? ctx->context() : CLScheduler::get().context()),
+ _mapping(nullptr),
+ _mem()
{
}
@@ -54,17 +59,17 @@ std::unique_ptr<IMemoryRegion> ICLMemoryRegion::extract_subregion(size_t offset,
return nullptr;
}
-CLBufferMemoryRegion::CLBufferMemoryRegion(cl::Context ctx, cl_mem_flags flags, size_t size)
- : ICLMemoryRegion(std::move(ctx), size)
+CLBufferMemoryRegion::CLBufferMemoryRegion(CLCoreRuntimeContext *ctx, cl_mem_flags flags, size_t size)
+ : ICLMemoryRegion(ctx, size)
{
if(_size != 0)
{
- _mem = cl::Buffer(_ctx, flags, _size);
+ _mem = cl::Buffer((ctx != nullptr) ? ctx->context() : CLScheduler::get().context(), flags, _size);
}
}
-CLBufferMemoryRegion::CLBufferMemoryRegion(const cl::Buffer &buffer)
- : ICLMemoryRegion(buffer.getInfo<CL_MEM_CONTEXT>(), buffer.getInfo<CL_MEM_SIZE>())
+CLBufferMemoryRegion::CLBufferMemoryRegion(const cl::Buffer &buffer, CLCoreRuntimeContext *ctx)
+ : ICLMemoryRegion(ctx, buffer.getInfo<CL_MEM_SIZE>())
{
_mem = buffer;
}
@@ -88,15 +93,15 @@ void CLBufferMemoryRegion::unmap(cl::CommandQueue &q)
_mapping = nullptr;
}
-ICLSVMMemoryRegion::ICLSVMMemoryRegion(cl::Context ctx, cl_mem_flags flags, size_t size, size_t alignment)
- : ICLMemoryRegion(std::move(ctx), size), _ptr(nullptr)
+ICLSVMMemoryRegion::ICLSVMMemoryRegion(CLCoreRuntimeContext *ctx, cl_mem_flags flags, size_t size, size_t alignment)
+ : ICLMemoryRegion(ctx, size), _ptr(nullptr)
{
if(size != 0)
{
- _ptr = clSVMAlloc(_ctx.get(), flags, size, alignment);
+ _ptr = clSVMAlloc((ctx != nullptr) ? ctx->context().get() : CLScheduler::get().context().get(), flags, size, alignment);
if(_ptr != nullptr)
{
- _mem = cl::Buffer(_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, _size, _ptr);
+ _mem = cl::Buffer((ctx != nullptr) ? ctx->context() : CLScheduler::get().context(), CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, _size, _ptr);
}
}
}
@@ -107,7 +112,7 @@ ICLSVMMemoryRegion::~ICLSVMMemoryRegion()
{
try
{
- clFinish(CLScheduler::get().queue().get());
+ clFinish(_queue.get());
_mem = cl::Buffer();
clSVMFree(_ctx.get(), _ptr);
}
@@ -122,8 +127,8 @@ void *ICLSVMMemoryRegion::ptr()
return _ptr;
}
-CLCoarseSVMMemoryRegion::CLCoarseSVMMemoryRegion(cl::Context ctx, cl_mem_flags flags, size_t size, size_t alignment)
- : ICLSVMMemoryRegion(std::move(ctx), flags, size, alignment)
+CLCoarseSVMMemoryRegion::CLCoarseSVMMemoryRegion(CLCoreRuntimeContext *ctx, cl_mem_flags flags, size_t size, size_t alignment)
+ : ICLSVMMemoryRegion(ctx, flags, size, alignment)
{
}
@@ -142,8 +147,8 @@ void CLCoarseSVMMemoryRegion::unmap(cl::CommandQueue &q)
_mapping = nullptr;
}
-CLFineSVMMemoryRegion::CLFineSVMMemoryRegion(cl::Context ctx, cl_mem_flags flags, size_t size, size_t alignment)
- : ICLSVMMemoryRegion(std::move(ctx), flags, size, alignment)
+CLFineSVMMemoryRegion::CLFineSVMMemoryRegion(CLCoreRuntimeContext *ctx, cl_mem_flags flags, size_t size, size_t alignment)
+ : ICLSVMMemoryRegion(ctx, flags, size, alignment)
{
}
@@ -162,4 +167,4 @@ void CLFineSVMMemoryRegion::unmap(cl::CommandQueue &q)
ARM_COMPUTE_UNUSED(q);
_mapping = nullptr;
}
-} // namespace arm_compute \ No newline at end of file
+} // namespace arm_compute
diff --git a/src/runtime/CL/CLRuntimeContext.cpp b/src/runtime/CL/CLRuntimeContext.cpp
new file mode 100644
index 0000000000..49e4c10c84
--- /dev/null
+++ b/src/runtime/CL/CLRuntimeContext.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+#include "arm_compute/runtime/CL/CLRuntimeContext.h"
+#include "arm_compute/core/Validate.h"
+#include "arm_compute/runtime/CL/CLHelpers.h"
+#include "arm_compute/runtime/CL/CLScheduler.h"
+
+namespace arm_compute
+{
+CLRuntimeContext::CLRuntimeContext()
+ : _gpu_owned_scheduler(support::cpp14::make_unique<CLScheduler>()), _gpu_scheduler(_gpu_owned_scheduler.get()), _symbols(), _core_context()
+{
+ _symbols.load_default();
+ auto ctx_dev_err = create_opencl_context_and_device();
+ ARM_COMPUTE_ERROR_ON_MSG(std::get<2>(ctx_dev_err) != CL_SUCCESS, "Failed to create OpenCL context");
+ auto ctx = std::get<0>(ctx_dev_err);
+ auto dev = std::get<1>(ctx_dev_err);
+ cl::CommandQueue queue = cl::CommandQueue(ctx, dev);
+ _gpu_owned_scheduler->init(ctx, queue, dev, &_tuner);
+ const std::string cl_kernels_folder("./cl_kernels");
+ _kernel_lib.init(cl_kernels_folder, ctx, dev);
+ _core_context = CLCoreRuntimeContext(&_kernel_lib, _gpu_owned_scheduler->context(), _gpu_owned_scheduler->queue());
+}
+
+CLKernelLibrary &CLRuntimeContext::kernel_library()
+{
+ return _kernel_lib;
+}
+
+CLCoreRuntimeContext *CLRuntimeContext::core_runtime_context()
+{
+ return &_core_context;
+}
+
+void CLRuntimeContext::set_gpu_scheduler(CLScheduler *scheduler)
+{
+ ARM_COMPUTE_ERROR_ON_NULLPTR(scheduler);
+ _gpu_scheduler = scheduler;
+}
+
+CLScheduler *CLRuntimeContext::gpu_scheduler()
+{
+ return _gpu_scheduler;
+}
+
+} // namespace arm_compute
diff --git a/src/runtime/CL/CLScheduler.cpp b/src/runtime/CL/CLScheduler.cpp
index 701ffe0ab1..e78eaa482f 100644
--- a/src/runtime/CL/CLScheduler.cpp
+++ b/src/runtime/CL/CLScheduler.cpp
@@ -23,13 +23,71 @@
*/
#include "arm_compute/runtime/CL/CLScheduler.h"
-#include "arm_compute/runtime/CL/CLHelpers.h"
-
+#include "arm_compute/core/CL/CLKernelLibrary.h"
#include "arm_compute/core/CL/ICLKernel.h"
+#include "arm_compute/runtime/CL/CLHelpers.h"
#include "arm_compute/runtime/CL/CLTuner.h"
#include "arm_compute/runtime/CL/tuners/Tuners.h"
-using namespace arm_compute;
+namespace arm_compute
+{
+cl::Context &CLScheduler::context()
+{
+ ARM_COMPUTE_ERROR_ON(!_is_initialised);
+ _context = CLKernelLibrary::get().context();
+ return _context;
+}
+
+cl::CommandQueue &CLScheduler::queue()
+{
+ ARM_COMPUTE_ERROR_ON(!_is_initialised);
+ return _queue;
+}
+
+GPUTarget CLScheduler::target() const
+{
+ return _target;
+}
+
+void CLScheduler::set_queue(cl::CommandQueue queue)
+{
+ _queue = std::move(queue);
+}
+
+void CLScheduler::set_target(GPUTarget target)
+{
+ _target = target;
+}
+
+void CLScheduler::set_tuner(ICLTuner *tuner)
+{
+ _cl_tuner = tuner;
+}
+
+void CLScheduler::sync()
+{
+ _queue.finish();
+}
+
+cl::Event CLScheduler::enqueue_sync_event()
+{
+ cl::Event event;
+ _queue.enqueueMarker(&event);
+ return event;
+}
+
+void CLScheduler::tune_kernel_static(ICLKernel &kernel)
+{
+ if(_cl_tuner != nullptr)
+ {
+ _cl_tuner->tune_kernel_static(kernel);
+ }
+}
+
+bool CLScheduler::is_initialised() const
+{
+ return _is_initialised;
+}
std::once_flag CLScheduler::_initialize_symbols;
@@ -49,8 +107,9 @@ void CLScheduler::default_init_with_context(cl::Device &device, cl::Context &ctx
{
if(!_is_initialised)
{
- cl::CommandQueue queue = cl::CommandQueue(ctx, device);
- CLKernelLibrary::get().init("./cl_kernels/", ctx, device);
+ const std::string cl_kernels_folder("./cl_kernels/");
+ cl::CommandQueue queue = cl::CommandQueue(ctx, device);
+ CLKernelLibrary::get().init(cl_kernels_folder, ctx, device);
init(ctx, queue, device, cl_tuner);
_cl_default_static_tuner = tuners::TunerFactory::create_tuner(_target);
_cl_tuner = (cl_tuner == nullptr) ? _cl_default_static_tuner.get() : cl_tuner;
@@ -113,3 +172,4 @@ void CLScheduler::enqueue(ICLKernel &kernel, bool flush)
_queue.flush();
}
}
+} // namespace arm_compute
diff --git a/src/runtime/CL/CLTensor.cpp b/src/runtime/CL/CLTensor.cpp
index 9bbf926b58..a6d0cf77ca 100644
--- a/src/runtime/CL/CLTensor.cpp
+++ b/src/runtime/CL/CLTensor.cpp
@@ -23,15 +23,21 @@
*/
#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLRuntimeContext.h"
#include "arm_compute/runtime/CL/CLScheduler.h"
namespace arm_compute
{
-CLTensor::CLTensor()
- : _allocator(this)
+CLTensor::CLTensor(IRuntimeContext *ctx)
+ : _allocator(this, static_cast<CLRuntimeContext *>(ctx)), _ctx(static_cast<CLRuntimeContext *>(ctx))
{
}
+CLRuntimeContext *CLTensor::context()
+{
+ return _ctx;
+}
+
TensorInfo *CLTensor::info() const
{
return &_allocator.info();
@@ -59,12 +65,12 @@ CLTensorAllocator *CLTensor::allocator()
void CLTensor::map(bool blocking)
{
- ICLTensor::map(CLScheduler::get().queue(), blocking);
+ ICLTensor::map(_ctx == nullptr ? CLScheduler::get().queue() : _ctx->gpu_scheduler()->queue(), blocking);
}
void CLTensor::unmap()
{
- ICLTensor::unmap(CLScheduler::get().queue());
+ ICLTensor::unmap(_ctx == nullptr ? CLScheduler::get().queue() : _ctx->gpu_scheduler()->queue());
}
uint8_t *CLTensor::do_map(cl::CommandQueue &q, bool blocking)
@@ -81,4 +87,4 @@ void CLTensor::associate_memory_group(arm_compute::IMemoryGroup *memory_group)
{
_allocator.set_associated_memory_group(memory_group);
}
-} // namespace arm_compute \ No newline at end of file
+} // namespace arm_compute
diff --git a/src/runtime/CL/CLTensorAllocator.cpp b/src/runtime/CL/CLTensorAllocator.cpp
index 2b5fbb8241..eaf46d42ca 100644
--- a/src/runtime/CL/CLTensorAllocator.cpp
+++ b/src/runtime/CL/CLTensorAllocator.cpp
@@ -25,6 +25,7 @@
#include "arm_compute/core/Error.h"
#include "arm_compute/core/TensorInfo.h"
+#include "arm_compute/runtime/CL/CLRuntimeContext.h"
#include "arm_compute/runtime/CL/CLScheduler.h"
namespace arm_compute
@@ -41,10 +42,10 @@ namespace
*
* @return A wrapped memory region
*/
-std::unique_ptr<ICLMemoryRegion> allocate_region(const cl::Context &context, size_t size, cl_uint alignment)
+std::unique_ptr<ICLMemoryRegion> allocate_region(CLCoreRuntimeContext *ctx, size_t size, cl_uint alignment)
{
// Try fine-grain SVM
- std::unique_ptr<ICLMemoryRegion> region = support::cpp14::make_unique<CLFineSVMMemoryRegion>(context,
+ std::unique_ptr<ICLMemoryRegion> region = support::cpp14::make_unique<CLFineSVMMemoryRegion>(ctx,
CL_MEM_READ_WRITE | CL_MEM_SVM_FINE_GRAIN_BUFFER,
size,
alignment);
@@ -52,12 +53,12 @@ std::unique_ptr<ICLMemoryRegion> allocate_region(const cl::Context &context, siz
// Try coarse-grain SVM in case of failure
if(region != nullptr && region->ptr() == nullptr)
{
- region = support::cpp14::make_unique<CLCoarseSVMMemoryRegion>(context, CL_MEM_READ_WRITE, size, alignment);
+ region = support::cpp14::make_unique<CLCoarseSVMMemoryRegion>(ctx, CL_MEM_READ_WRITE, size, alignment);
}
// Try legacy buffer memory in case of failure
if(region != nullptr && region->ptr() == nullptr)
{
- region = support::cpp14::make_unique<CLBufferMemoryRegion>(context, CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, size);
+ region = support::cpp14::make_unique<CLBufferMemoryRegion>(ctx, CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, size);
}
return region;
}
@@ -103,8 +104,8 @@ void populate_quantization_info(CLFloatArray &scale, CLInt32Array &offset, const
}
} // namespace
-CLTensorAllocator::CLTensorAllocator(IMemoryManageable *owner)
- : _owner(owner), _associated_memory_group(nullptr), _memory(), _mapping(nullptr), _scale(), _offset()
+CLTensorAllocator::CLTensorAllocator(IMemoryManageable *owner, CLRuntimeContext *ctx)
+ : _ctx(ctx), _owner(owner), _associated_memory_group(nullptr), _memory(), _mapping(nullptr), _scale(), _offset()
{
}
@@ -129,7 +130,15 @@ void CLTensorAllocator::allocate()
if(_associated_memory_group == nullptr)
{
// Perform memory allocation
- _memory.set_owned_region(allocate_region(CLScheduler::get().context(), info().total_size(), 0));
+ if(_ctx == nullptr)
+ {
+ auto legacy_ctx = CLCoreRuntimeContext(nullptr, CLScheduler::get().context(), CLScheduler::get().queue());
+ _memory.set_owned_region(allocate_region(&legacy_ctx, info().total_size(), 0));
+ }
+ else
+ {
+ _memory.set_owned_region(allocate_region(_ctx->core_runtime_context(), info().total_size(), 0));
+ }
}
else
{
@@ -162,9 +171,17 @@ Status CLTensorAllocator::import_memory(cl::Buffer buffer)
ARM_COMPUTE_RETURN_ERROR_ON(buffer.getInfo<CL_MEM_CONTEXT>().get() != CLScheduler::get().context().get());
ARM_COMPUTE_RETURN_ERROR_ON(_associated_memory_group != nullptr);
- _memory.set_owned_region(support::cpp14::make_unique<CLBufferMemoryRegion>(buffer));
- info().set_is_resizable(false);
+ if(_ctx == nullptr)
+ {
+ auto legacy_ctx = CLCoreRuntimeContext(nullptr, CLScheduler::get().context(), CLScheduler::get().queue());
+ _memory.set_owned_region(support::cpp14::make_unique<CLBufferMemoryRegion>(buffer, &legacy_ctx));
+ }
+ else
+ {
+ _memory.set_owned_region(support::cpp14::make_unique<CLBufferMemoryRegion>(buffer, _ctx->core_runtime_context()));
+ }
+ info().set_is_resizable(false);
return Status{};
}
@@ -179,13 +196,28 @@ void CLTensorAllocator::set_associated_memory_group(IMemoryGroup *associated_mem
uint8_t *CLTensorAllocator::lock()
{
- return map(CLScheduler::get().queue(), true);
+ if(_ctx)
+ {
+ return map(_ctx->gpu_scheduler()->queue(), true);
+ }
+ else
+ {
+ return map(CLScheduler::get().queue(), true);
+ }
}
void CLTensorAllocator::unlock()
{
ARM_COMPUTE_ERROR_ON(_memory.region() == nullptr);
- unmap(CLScheduler::get().queue(), reinterpret_cast<uint8_t *>(_memory.region()->buffer()));
+ if(_ctx)
+ {
+ unmap(_ctx->gpu_scheduler()->queue(), reinterpret_cast<uint8_t *>(_memory.region()->buffer()));
+ }
+ else
+ {
+ //Legacy singleton api
+ unmap(CLScheduler::get().queue(), reinterpret_cast<uint8_t *>(_memory.region()->buffer()));
+ }
}
uint8_t *CLTensorAllocator::map(cl::CommandQueue &q, bool blocking)
diff --git a/src/runtime/CL/ICLSimpleFunction.cpp b/src/runtime/CL/ICLSimpleFunction.cpp
index a1a56fd06c..fb8eba8aa4 100644
--- a/src/runtime/CL/ICLSimpleFunction.cpp
+++ b/src/runtime/CL/ICLSimpleFunction.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017 ARM Limited.
+ * Copyright (c) 2016-2019 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -24,20 +24,21 @@
#include "arm_compute/runtime/CL/ICLSimpleFunction.h"
#include "arm_compute/core/Error.h"
+#include "arm_compute/runtime/CL/CLHelpers.h"
#include "arm_compute/runtime/CL/CLScheduler.h"
using namespace arm_compute;
-ICLSimpleFunction::ICLSimpleFunction() // NOLINT
+ICLSimpleFunction::ICLSimpleFunction(CLRuntimeContext *ctx) // NOLINT
: _kernel(),
- _border_handler()
+ _border_handler(),
+ _ctx(ctx)
{
}
void ICLSimpleFunction::run()
{
ARM_COMPUTE_ERROR_ON_MSG(!_kernel, "The child class didn't set the CL kernel or function isn't configured");
-
- CLScheduler::get().enqueue(_border_handler, false);
- CLScheduler::get().enqueue(*_kernel);
+ schedule_kernel_on_ctx(_ctx, &_border_handler, false);
+ schedule_kernel_on_ctx(_ctx, _kernel.get());
}
diff --git a/src/runtime/CL/functions/CLActivationLayer.cpp b/src/runtime/CL/functions/CLActivationLayer.cpp
index 2b66795cf9..00dbb71f4c 100644
--- a/src/runtime/CL/functions/CLActivationLayer.cpp
+++ b/src/runtime/CL/functions/CLActivationLayer.cpp
@@ -25,18 +25,21 @@
#include "arm_compute/core/CL/kernels/CLActivationLayerKernel.h"
#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLRuntimeContext.h"
#include "support/ToolchainSupport.h"
namespace arm_compute
{
-CLActivationLayer::CLActivationLayer(void *ctx)
+CLActivationLayer::CLActivationLayer(CLRuntimeContext *ctx)
+ : ICLSimpleFunction(ctx)
{
- ARM_COMPUTE_UNUSED(ctx);
}
void CLActivationLayer::configure(ICLTensor *input, ICLTensor *output, ActivationLayerInfo act_info)
{
- auto k = arm_compute::support::cpp14::make_unique<CLActivationLayerKernel>();
+ auto core_ctx = _ctx ? _ctx->core_runtime_context() : /* Legacy */ nullptr;
+
+ auto k = arm_compute::support::cpp14::make_unique<CLActivationLayerKernel>(core_ctx);
k->configure(input, output, act_info);
_kernel = std::move(k);
}
diff --git a/src/runtime/GLES_COMPUTE/GCTensor.cpp b/src/runtime/GLES_COMPUTE/GCTensor.cpp
index 66c1abdb6d..e05eb4c4ae 100644
--- a/src/runtime/GLES_COMPUTE/GCTensor.cpp
+++ b/src/runtime/GLES_COMPUTE/GCTensor.cpp
@@ -26,7 +26,7 @@
namespace arm_compute
{
-GCTensor::GCTensor()
+GCTensor::GCTensor(IRuntimeContext *)
: _allocator(this)
{
}
@@ -80,4 +80,4 @@ void GCTensor::do_unmap()
{
_allocator.unmap();
}
-} // namespace arm_compute \ No newline at end of file
+} // namespace arm_compute
diff --git a/src/runtime/Tensor.cpp b/src/runtime/Tensor.cpp
index de08efd731..8f7ecd6ffa 100644
--- a/src/runtime/Tensor.cpp
+++ b/src/runtime/Tensor.cpp
@@ -25,7 +25,7 @@
namespace arm_compute
{
-Tensor::Tensor()
+Tensor::Tensor(IRuntimeContext *)
: _allocator(this)
{
}
@@ -54,4 +54,4 @@ void Tensor::associate_memory_group(IMemoryGroup *memory_group)
{
_allocator.set_associated_memory_group(memory_group);
}
-} // namespace arm_compute \ No newline at end of file
+} // namespace arm_compute
diff --git a/tests/Globals.h b/tests/Globals.h
index 569b1a31c6..989fdfdcd4 100644
--- a/tests/Globals.h
+++ b/tests/Globals.h
@@ -25,7 +25,7 @@
#define __ARM_COMPUTE_TEST_GLOBALS_H__
#include "tests/AssetsLibrary.h"
-#include "tests/ParametersLibrary.h"
+#include "tests/framework/ParametersLibrary.h"
#include <memory>
diff --git a/tests/Utils.h b/tests/Utils.h
index ea70fffe3a..3bb6060951 100644
--- a/tests/Utils.h
+++ b/tests/Utils.h
@@ -520,14 +520,15 @@ inline bool is_in_valid_region(const ValidRegion &valid_region, Coordinates coor
* @param[in] num_channels (Optional) Number of channels.
* @param[in] quantization_info (Optional) Quantization info for asymmetric quantized types.
* @param[in] data_layout (Optional) Data layout. Default is NCHW.
+ * @param[in] ctx (Optional) Pointer to the runtime context.
*
* @return Initialized tensor of given type.
*/
template <typename T>
inline T create_tensor(const TensorShape &shape, DataType data_type, int num_channels = 1,
- QuantizationInfo quantization_info = QuantizationInfo(), DataLayout data_layout = DataLayout::NCHW)
+ QuantizationInfo quantization_info = QuantizationInfo(), DataLayout data_layout = DataLayout::NCHW, IRuntimeContext *ctx = nullptr)
{
- T tensor;
+ T tensor(ctx);
TensorInfo info(shape, num_channels, data_type);
info.set_quantization_info(quantization_info);
info.set_data_layout(data_layout);
@@ -540,15 +541,16 @@ inline T create_tensor(const TensorShape &shape, DataType data_type, int num_cha
*
* @param[in] shape Tensor shape.
* @param[in] format Format type.
+ * @param[in] ctx (Optional) Pointer to the runtime context.
*
* @return Initialized tensor of given type.
*/
template <typename T>
-inline T create_tensor(const TensorShape &shape, Format format)
+inline T create_tensor(const TensorShape &shape, Format format, IRuntimeContext *ctx = nullptr)
{
TensorInfo info(shape, format);
- T tensor;
+ T tensor(ctx);
tensor.allocator()->init(info);
return tensor;
diff --git a/tests/framework/Framework.cpp b/tests/framework/Framework.cpp
index fbc2456047..5d1600e083 100644
--- a/tests/framework/Framework.cpp
+++ b/tests/framework/Framework.cpp
@@ -25,8 +25,12 @@
#include "arm_compute/runtime/Scheduler.h"
#include "support/ToolchainSupport.h"
+#include "tests/framework/ParametersLibrary.h"
+
#ifdef ARM_COMPUTE_CL
+#include "arm_compute/runtime/CL/CLRuntimeContext.h"
#include "arm_compute/runtime/CL/CLScheduler.h"
+
#endif /* ARM_COMPUTE_CL */
#include <chrono>
@@ -38,6 +42,8 @@ namespace arm_compute
{
namespace test
{
+std::unique_ptr<ParametersLibrary> parameters;
+
namespace framework
{
std::unique_ptr<InstrumentsInfo> instruments_info;
@@ -558,17 +564,23 @@ bool Framework::run()
// Every 100 tests, reset the OpenCL context to release the allocated memory
if(opencl_is_available() && (id_run_test % 100) == 0)
{
- auto ctx_properties = CLScheduler::get().context().getInfo<CL_CONTEXT_PROPERTIES>(nullptr);
- auto queue_properties = CLScheduler::get().queue().getInfo<CL_QUEUE_PROPERTIES>(nullptr);
-
- cl::Context new_ctx = cl::Context(CL_DEVICE_TYPE_DEFAULT, ctx_properties.data());
- cl::CommandQueue new_queue = cl::CommandQueue(new_ctx, CLKernelLibrary::get().get_device(), queue_properties);
-
CLKernelLibrary::get().clear_programs_cache();
- CLScheduler::get().set_context(new_ctx);
- CLScheduler::get().set_queue(new_queue);
+ auto cl_ctx = support::cpp14::make_unique<CLRuntimeContext>();
+ assert(cl_ctx != nullptr);
+ CLScheduler *gpu_scheduler = cl_ctx->gpu_scheduler();
+ assert(gpu_scheduler != nullptr);
+ {
+ // Legacy singletons API: This has been deprecated and the singletons will be removed
+ // Setup singleton for backward compatibility
+ CLScheduler::get().init(gpu_scheduler->context(), gpu_scheduler->queue(), cl_ctx->kernel_library().get_device());
+ }
+ if(parameters)
+ {
+ parameters->set_gpu_ctx(std::move(cl_ctx));
+ }
}
#endif // ARM_COMPUTE_CL
+
run_test(test_info, *test_factory);
++id_run_test;
diff --git a/tests/ParametersLibrary.cpp b/tests/framework/ParametersLibrary.cpp
index 16152c8482..65a09eeb64 100644
--- a/tests/ParametersLibrary.cpp
+++ b/tests/framework/ParametersLibrary.cpp
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#include "tests/ParametersLibrary.h"
+#include "tests/framework/ParametersLibrary.h"
namespace arm_compute
{
@@ -32,10 +32,23 @@ void ParametersLibrary::set_cpu_ctx(std::unique_ptr<IRuntimeContext> cpu_ctx)
_cpu_ctx = std::move(cpu_ctx);
}
+void ParametersLibrary::set_gpu_ctx(std::unique_ptr<IRuntimeContext> gpu_ctx)
+{
+ _gpu_ctx = std::move(gpu_ctx);
+}
+
template <>
typename ContextType<Tensor>::type *ParametersLibrary::get_ctx<Tensor>()
{
return _cpu_ctx.get();
}
+
+#if ARM_COMPUTE_CL
+template <>
+typename ContextType<CLTensor>::type *ParametersLibrary::get_ctx<CLTensor>()
+{
+ return static_cast<typename ContextType<CLTensor>::type *>(_gpu_ctx.get());
+}
+#endif /* ARM_COMPUTE_CL */
} // namespace test
} // namespace arm_compute
diff --git a/tests/ParametersLibrary.h b/tests/framework/ParametersLibrary.h
index a99be46d3f..4079ab25b9 100644
--- a/tests/ParametersLibrary.h
+++ b/tests/framework/ParametersLibrary.h
@@ -26,6 +26,13 @@
#include "arm_compute/runtime/IRuntimeContext.h"
#include "arm_compute/runtime/Tensor.h"
+#if ARM_COMPUTE_CL
+#include "arm_compute/runtime/CL/CLRuntimeContext.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#endif /* ARM_COMPUTE_CL */
+#ifdef ARM_COMPUTE_GC
+#include "arm_compute/runtime/GLES_COMPUTE/GCTensor.h"
+#endif /* ARM_COMPUTE_GC */
#include <memory>
@@ -45,6 +52,22 @@ struct ContextType<Tensor>
using type = IRuntimeContext;
};
+#if ARM_COMPUTE_CL
+template <>
+struct ContextType<CLTensor>
+{
+ using type = CLRuntimeContext;
+};
+#endif /* ARM_COMPUTE_CL */
+
+#ifdef ARM_COMPUTE_GC
+template <>
+struct ContextType<GCTensor>
+{
+ using type = IRuntimeContext;
+};
+#endif /* ARM_COMPUTE_GC */
+
/** Class that contains all the global parameters used by the tests */
class ParametersLibrary final
{
@@ -56,6 +79,11 @@ public:
* @param[in] cpu_ctx CPU context to use
*/
void set_cpu_ctx(std::unique_ptr<IRuntimeContext> cpu_ctx);
+ /** Set gpu context to be used by the tests
+ *
+ * @param[in] gpu_ctx GPU context to use
+ */
+ void set_gpu_ctx(std::unique_ptr<IRuntimeContext> gpu_ctx);
/** Get context given a tensor type
*
* @tparam TensorType
@@ -70,6 +98,7 @@ public:
private:
std::unique_ptr<IRuntimeContext> _cpu_ctx{ nullptr };
+ std::unique_ptr<IRuntimeContext> _gpu_ctx{ nullptr };
};
} // namespace test
} // namespace arm_compute
diff --git a/tests/main.cpp b/tests/main.cpp
index 01741939a0..415dba0405 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -23,11 +23,11 @@
*/
#include "support/ToolchainSupport.h"
#include "tests/AssetsLibrary.h"
-#include "tests/ParametersLibrary.h"
#include "tests/framework/DatasetModes.h"
#include "tests/framework/Exceptions.h"
#include "tests/framework/Framework.h"
#include "tests/framework/Macros.h"
+#include "tests/framework/ParametersLibrary.h"
#include "tests/framework/Profiler.h"
#include "tests/framework/command_line/CommonOptions.h"
#include "tests/framework/instruments/Instruments.h"
@@ -74,8 +74,8 @@ namespace arm_compute
{
namespace test
{
-std::unique_ptr<AssetsLibrary> library;
-std::unique_ptr<ParametersLibrary> parameters;
+std::unique_ptr<AssetsLibrary> library;
+extern std::unique_ptr<ParametersLibrary> parameters;
} // namespace test
} // namespace arm_compute
@@ -92,17 +92,6 @@ bool file_exists(const std::string &filename)
int main(int argc, char **argv)
{
-#ifdef ARM_COMPUTE_CL
- CLTuner cl_tuner(false);
- if(opencl_is_available())
- {
- auto ctx_dev_err = create_opencl_context_and_device();
- ARM_COMPUTE_ERROR_ON_MSG(std::get<2>(ctx_dev_err) != CL_SUCCESS, "Failed to create OpenCL context");
- CLScheduler::get()
- .default_init_with_context(std::get<1>(ctx_dev_err), std::get<0>(ctx_dev_err), &cl_tuner);
- }
-#endif /* ARM_COMPUTE_CL */
-
#ifdef ARM_COMPUTE_GC
GCScheduler::get().default_init();
#endif /* ARM_COMPUTE_GC */
@@ -185,6 +174,20 @@ int main(int argc, char **argv)
parameters->set_cpu_ctx(std::move(cpu_ctx));
#ifdef ARM_COMPUTE_CL
+ CLTuner cl_tuner(false);
+ // Create GPU context
+ auto cl_ctx = support::cpp14::make_unique<CLRuntimeContext>();
+ assert(cl_ctx != nullptr);
+ CLScheduler *gpu_scheduler = cl_ctx->gpu_scheduler();
+ assert(gpu_scheduler != nullptr);
+ const auto device_version = cl_ctx->kernel_library().get_device_version();
+ {
+ // Legacy singletons API: This has been deprecated and the singletons will be removed
+ // Setup singleton for backward compatibility
+ CLScheduler::get().init(gpu_scheduler->context(), gpu_scheduler->queue(), cl_ctx->kernel_library().get_device(), &cl_tuner);
+ }
+ parameters->set_gpu_ctx(std::move(cl_ctx));
+
if(enable_tuner->is_set())
{
cl_tuner.set_tune_new_kernels(enable_tuner->value());
@@ -222,7 +225,7 @@ int main(int argc, char **argv)
#ifdef ARM_COMPUTE_CL
if(opencl_is_available())
{
- p->print_entry("CL_DEVICE_VERSION", CLKernelLibrary::get().get_device_version());
+ p->print_entry("CL_DEVICE_VERSION", device_version);
}
else
{
diff --git a/tests/validation/CL/ActivationLayer.cpp b/tests/validation/CL/ActivationLayer.cpp
index 250777d541..a17ad9b269 100644
--- a/tests/validation/CL/ActivationLayer.cpp
+++ b/tests/validation/CL/ActivationLayer.cpp
@@ -95,15 +95,18 @@ TEST_SUITE(ActivationLayer)
DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(datasets::SmallShapes(), CNNDataTypes), framework::dataset::make("InPlace", { false, true })),
shape, data_type, in_place)
{
+ // Create context
+ auto ctx = parameters->get_ctx<CLTensor>();
+
// Create tensors
- CLTensor src = create_tensor<CLTensor>(shape, data_type, 1);
- CLTensor dst = create_tensor<CLTensor>(shape, data_type, 1);
+ CLTensor src = create_tensor<CLTensor>(shape, data_type, 1, QuantizationInfo(), DataLayout::NCHW, ctx);
+ CLTensor dst = create_tensor<CLTensor>(shape, data_type, 1, QuantizationInfo(), DataLayout::NCHW, ctx);
ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
// Create and configure function
- CLActivationLayer act_layer;
+ CLActivationLayer act_layer(ctx);
if(in_place)
{
diff --git a/tests/validation/fixtures/ActivationLayerFixture.h b/tests/validation/fixtures/ActivationLayerFixture.h
index 8fa74979a8..f6d43ddd89 100644
--- a/tests/validation/fixtures/ActivationLayerFixture.h
+++ b/tests/validation/fixtures/ActivationLayerFixture.h
@@ -29,9 +29,9 @@
#include "tests/AssetsLibrary.h"
#include "tests/Globals.h"
#include "tests/IAccessor.h"
-#include "tests/ParametersLibrary.h"
#include "tests/framework/Asserts.h"
#include "tests/framework/Fixture.h"
+#include "tests/framework/ParametersLibrary.h"
#include "tests/validation/Helpers.h"
#include "tests/validation/reference/ActivationLayer.h"
@@ -47,6 +47,11 @@ template <typename TensorType, typename AccessorType, typename FunctionType, typ
class ActivationValidationGenericFixture : public framework::Fixture
{
public:
+ ActivationValidationGenericFixture()
+ : _target(parameters->get_ctx<TensorType>())
+ {
+ }
+
template <typename...>
void setup(TensorShape shape, bool in_place, ActivationLayerInfo::ActivationFunction function, float alpha_beta, DataType data_type, QuantizationInfo quantization_info)
{
@@ -90,12 +95,13 @@ protected:
TensorType compute_target(const TensorShape &shape, ActivationLayerInfo info)
{
+ auto ctx = parameters->get_ctx<TensorType>();
// Create tensors
- TensorType src = create_tensor<TensorType>(shape, _data_type, 1, _input_quantization_info);
- TensorType dst = create_tensor<TensorType>(shape, _data_type, 1, _output_quantization_info);
+ TensorType src = create_tensor<TensorType>(shape, _data_type, 1, _input_quantization_info, DataLayout::NCHW, ctx);
+ TensorType dst = create_tensor<TensorType>(shape, _data_type, 1, _output_quantization_info, DataLayout::NCHW, ctx);
// Create and configure function
- FunctionType act_layer(parameters->get_ctx<TensorType>());
+ FunctionType act_layer(ctx);
TensorType *dst_ptr = _in_place ? nullptr : &dst;
diff --git a/utils/Utils.cpp b/utils/Utils.cpp
index b0e162accd..8cc3fcf9b0 100644
--- a/utils/Utils.cpp
+++ b/utils/Utils.cpp
@@ -24,6 +24,7 @@
#include "Utils.h"
#ifdef ARM_COMPUTE_CL
+#include "arm_compute/core/CL/CLKernelLibrary.h"
#include "arm_compute/runtime/CL/CLScheduler.h"
#endif /* ARM_COMPUTE_CL */