From 402740da11c4fd2a9dc7aee5dadf3b1fdda0afde Mon Sep 17 00:00:00 2001 From: Michalis Spyrou Date: Tue, 20 Apr 2021 11:26:21 +0100 Subject: Add support for CLVK This patch enables CLVK through the graph API and inside the CLScheduler. By default the Native platform is selected. Selecting CLVK can be done via --target=clvk. Resolves COMPMID-4205 and COMPMID-4206 Change-Id: Ic60744980c6b8a60e776627ea677ed46be88f656 Signed-off-by: Michalis Spyrou Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/5475 Tested-by: Arm Jenkins Reviewed-by: Georgios Pinitas --- src/core/CL/OpenCL.cpp | 19 +++++++++++++ src/graph/GraphManager.cpp | 14 +++++++++- src/graph/TypeLoader.cpp | 1 + src/graph/backends/CL/CLDeviceBackend.cpp | 5 ++-- src/runtime/CL/CLHelpers.cpp | 44 +++++++++++++++++++++++++++---- src/runtime/CL/CLRuntimeContext.cpp | 6 ++--- src/runtime/CL/CLScheduler.cpp | 10 +++---- 7 files changed, 83 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/core/CL/OpenCL.cpp b/src/core/CL/OpenCL.cpp index dd9960a7b3..a7be534397 100644 --- a/src/core/CL/OpenCL.cpp +++ b/src/core/CL/OpenCL.cpp @@ -122,6 +122,7 @@ bool CLSymbols::load(const std::string &library) LOAD_FUNCTION_PTR(clGetDeviceIDs, handle); LOAD_FUNCTION_PTR(clGetMemObjectInfo, handle); LOAD_FUNCTION_PTR(clRetainEvent, handle); + LOAD_FUNCTION_PTR(clGetPlatformInfo, handle); LOAD_FUNCTION_PTR(clGetPlatformIDs, handle); LOAD_FUNCTION_PTR(clGetKernelWorkGroupInfo, handle); LOAD_FUNCTION_PTR(clGetCommandQueueInfo, handle); @@ -865,6 +866,24 @@ cl_int clRetainEvent(cl_event event) } } +cl_int clGetPlatformInfo(cl_platform_id platform, + cl_platform_info param_name, + size_t param_value_size, + void *param_value, + size_t *param_value_size_ret) +{ + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clGetPlatformInfo_ptr; + if(func != nullptr) + { + return func(platform, param_name, param_value_size, param_value, param_value_size_ret); + } + else + { + return CL_OUT_OF_RESOURCES; + } +} + cl_int clGetPlatformIDs(cl_uint num_entries, cl_platform_id *platforms, cl_uint *num_platforms) { arm_compute::CLSymbols::get().load_default(); diff --git a/src/graph/GraphManager.cpp b/src/graph/GraphManager.cpp index 9d53172dc8..ab7aac6230 100644 --- a/src/graph/GraphManager.cpp +++ b/src/graph/GraphManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 Arm Limited. + * Copyright (c) 2018-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -57,6 +57,18 @@ void GraphManager::finalize_graph(Graph &graph, GraphContext &ctx, PassManager & // Force target to all graph construct // TODO (COMPMID-2014) : Support heterogeneous execution Target forced_target = target; + + // In case CLVK is selected, use the CL backend and + // update config + if(target == Target::CLVK) + { + forced_target = Target::CL; + GraphConfig config = ctx.config(); + config.backend_type = CLBackendType::Clvk; + + ctx.set_config(config); + } + if(!is_target_supported(target)) { forced_target = get_default_target(); diff --git a/src/graph/TypeLoader.cpp b/src/graph/TypeLoader.cpp index 8efd66f2c5..3c51289dba 100644 --- a/src/graph/TypeLoader.cpp +++ b/src/graph/TypeLoader.cpp @@ -59,6 +59,7 @@ Target target_from_name(const std::string &name) { { "neon", Target::NEON }, { "cl", Target::CL }, + { "clvk", Target::CLVK }, }; #ifndef ARM_COMPUTE_EXCEPTIONS_DISABLED diff --git a/src/graph/backends/CL/CLDeviceBackend.cpp b/src/graph/backends/CL/CLDeviceBackend.cpp index f8e22ca7a0..eafda98669 100644 --- a/src/graph/backends/CL/CLDeviceBackend.cpp +++ b/src/graph/backends/CL/CLDeviceBackend.cpp @@ -65,7 +65,7 @@ bool file_exists(const std::string &filename) static detail::BackendRegistrar CLDeviceBackend_registrar(Target::CL); CLDeviceBackend::CLDeviceBackend() - : _context_count(0), _tuner(), _gemm_heuristics(), _allocator(nullptr), _tuner_file() + : _context_count(0), _tuner(), _gemm_heuristics(), _allocator(nullptr), _tuner_file(), _backend_type(CLBackendType::Native) { } @@ -87,7 +87,7 @@ void CLDeviceBackend::set_kernel_tuning_mode(CLTunerMode tuning_mode) void CLDeviceBackend::initialize_backend() { // Setup Scheduler - CLScheduler::get().default_init(&_tuner, &_gemm_heuristics); + CLScheduler::get().default_init(&_tuner, &_gemm_heuristics, _backend_type); // Create allocator with new context _allocator = std::make_unique(nullptr /* legacy path for CLCoreRuntimeContext */); } @@ -108,6 +108,7 @@ void CLDeviceBackend::setup_backend_context(GraphContext &ctx) _context_count++; if(_context_count == 1) { + _backend_type = ctx.config().backend_type; initialize_backend(); } diff --git a/src/runtime/CL/CLHelpers.cpp b/src/runtime/CL/CLHelpers.cpp index 5f1842f76d..5b4bbbcde0 100644 --- a/src/runtime/CL/CLHelpers.cpp +++ b/src/runtime/CL/CLHelpers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020 Arm Limited. + * Copyright (c) 2019-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -85,14 +85,48 @@ void initialise_context_properties(const cl::Platform &platform, const cl::Devic namespace arm_compute { -std::tuple -create_opencl_context_and_device() +cl::Platform select_preferable_platform(CLBackendType cl_backend_type) { - ARM_COMPUTE_ERROR_ON(!opencl_is_available()); std::vector platforms; cl::Platform::get(&platforms); ARM_COMPUTE_ERROR_ON_MSG(platforms.size() == 0, "Couldn't find any OpenCL platform"); - cl::Platform p = platforms[0]; + + cl::Platform selected_platform{ nullptr }; + + // If the user has selected the Native platform, return the first available. + switch(cl_backend_type) + { + case CLBackendType::Native: + selected_platform = platforms[0]; + break; + case CLBackendType::Clvk: + for(auto p : platforms) + { + std::string res = p.getInfo(); + if(res.find("clvk") != std::string::npos) + { + selected_platform = p; + break; + } + } + break; + default: + ARM_COMPUTE_ERROR("Unsupported backend type"); + } + + if(!selected_platform()) + { + ARM_COMPUTE_ERROR("No valid platform found"); + } + + return selected_platform; +} + +std::tuple +create_opencl_context_and_device(CLBackendType cl_backend_type) +{ + ARM_COMPUTE_ERROR_ON(!opencl_is_available()); + cl::Platform p = select_preferable_platform(cl_backend_type); cl::Device device; std::vector platform_devices; p.getDevices(CL_DEVICE_TYPE_DEFAULT, &platform_devices); diff --git a/src/runtime/CL/CLRuntimeContext.cpp b/src/runtime/CL/CLRuntimeContext.cpp index 9d46126ee4..0c1d011f9a 100644 --- a/src/runtime/CL/CLRuntimeContext.cpp +++ b/src/runtime/CL/CLRuntimeContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020 Arm Limited. + * Copyright (c) 2019-2021 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -29,10 +29,10 @@ namespace arm_compute { CLRuntimeContext::CLRuntimeContext() - : _gpu_owned_scheduler(std::make_unique()), _gpu_scheduler(_gpu_owned_scheduler.get()), _symbols(), _core_context() + : _gpu_owned_scheduler(std::make_unique()), _gpu_scheduler(_gpu_owned_scheduler.get()), _symbols(), _core_context(), _backend_type() { _symbols.load_default(); - auto ctx_dev_err = create_opencl_context_and_device(); + auto ctx_dev_err = create_opencl_context_and_device(_backend_type); 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); diff --git a/src/runtime/CL/CLScheduler.cpp b/src/runtime/CL/CLScheduler.cpp index f228cf6513..cb5f04ce8b 100644 --- a/src/runtime/CL/CLScheduler.cpp +++ b/src/runtime/CL/CLScheduler.cpp @@ -24,7 +24,6 @@ #include "arm_compute/runtime/CL/CLScheduler.h" #include "arm_compute/core/CL/CLKernelLibrary.h" -#include "arm_compute/runtime/CL/CLHelpers.h" #include "arm_compute/runtime/CL/CLTuner.h" #include "src/core/CL/ICLKernel.h" @@ -96,7 +95,7 @@ bool CLScheduler::is_initialised() const std::once_flag CLScheduler::_initialize_symbols; CLScheduler::CLScheduler() - : _context(), _queue(), _target(GPUTarget::MIDGARD), _is_initialised(false), _cl_tuner(nullptr), _gemm_heuristics(nullptr) + : _context(), _queue(), _target(GPUTarget::MIDGARD), _is_initialised(false), _cl_tuner(nullptr), _gemm_heuristics(nullptr), _backend_type(CLBackendType::Native) { } @@ -119,14 +118,14 @@ void CLScheduler::default_init_with_context(cl::Device &device, cl::Context &ctx } } -void CLScheduler::default_init(ICLTuner *cl_tuner, CLGEMMHeuristicsHandle *gemm_h) +void CLScheduler::default_init(ICLTuner *cl_tuner, CLGEMMHeuristicsHandle *gemm_h, CLBackendType cl_backend_type) { if(!_is_initialised) { cl::Context ctx; cl::Device dev; cl_int err; - std::tie(ctx, dev, err) = create_opencl_context_and_device(); + std::tie(ctx, dev, err) = create_opencl_context_and_device(cl_backend_type); ARM_COMPUTE_ERROR_ON_MSG(err != CL_SUCCESS, "Failed to create OpenCL context"); cl::CommandQueue queue = cl::CommandQueue(ctx, dev); CLKernelLibrary::get().init("./cl_kernels/", ctx, dev); @@ -143,7 +142,7 @@ void CLScheduler::set_context(cl::Context context) CLKernelLibrary::get().set_context(_context); } -void CLScheduler::init(cl::Context context, cl::CommandQueue queue, const cl::Device &device, ICLTuner *cl_tuner, CLGEMMHeuristicsHandle *gemm_h) +void CLScheduler::init(cl::Context context, cl::CommandQueue queue, const cl::Device &device, ICLTuner *cl_tuner, CLGEMMHeuristicsHandle *gemm_h, CLBackendType cl_backend_type) { set_context(std::move(context)); _queue = std::move(queue); @@ -151,6 +150,7 @@ void CLScheduler::init(cl::Context context, cl::CommandQueue queue, const cl::De _is_initialised = true; _cl_tuner = cl_tuner; _gemm_heuristics = gemm_h; + _backend_type = cl_backend_type; } void CLScheduler::enqueue_common(ICLKernel &kernel, ITensorPack &tensors, bool flush) -- cgit v1.2.1