From 725788e33c163f95a6fdc054b6b78296ed7dfe50 Mon Sep 17 00:00:00 2001 From: Moritz Pflanzer Date: Fri, 7 Jul 2017 15:35:56 +0100 Subject: COMPMID-417: Allow loading of custom OpenCL library Change-Id: Ic26266f164ec26f9f2923c0ffe366fea37b970ae Reviewed-on: http://mpd-gerrit.cambridge.arm.com/80090 Tested-by: Kaizen Reviewed-by: Anthony Barbier --- src/core/CL/OpenCL.cpp | 253 +++++++++++++++++++++++++------------------------ 1 file changed, 128 insertions(+), 125 deletions(-) (limited to 'src/core/CL/OpenCL.cpp') diff --git a/src/core/CL/OpenCL.cpp b/src/core/CL/OpenCL.cpp index 3b8dfd2465..4eba709b52 100644 --- a/src/core/CL/OpenCL.cpp +++ b/src/core/CL/OpenCL.cpp @@ -27,114 +27,91 @@ #include #include -using clBuildProgram_func = cl_int (*)(cl_program, cl_uint, const cl_device_id *, const char *, void (*pfn_notify)(cl_program, void *), void *); -using clEnqueueNDRangeKernel_func = cl_int (*)(cl_command_queue, cl_kernel, cl_uint, const size_t *, const size_t *, const size_t *, cl_uint, const cl_event *, cl_event *); -using clSetKernelArg_func = cl_int (*)(cl_kernel, cl_uint, size_t, const void *); -using clReleaseMemObject_func = cl_int (*)(cl_mem); -using clEnqueueUnmapMemObject_func = cl_int (*)(cl_command_queue, cl_mem, void *, cl_uint, const cl_event *, cl_event *); -using clRetainCommandQueue_func = cl_int (*)(cl_command_queue command_queue); -using clReleaseContext_func = cl_int (*)(cl_context); -using clReleaseEvent_func = cl_int (*)(cl_event); -using clEnqueueWriteBuffer_func = cl_int (*)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, const void *, cl_uint, const cl_event *, cl_event *); -using clEnqueueReadBuffer_func = cl_int (*)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *); -using clGetProgramBuildInfo_func = cl_int (*)(cl_program, cl_device_id, cl_program_build_info, size_t, void *, size_t *); -using clRetainProgram_func = cl_int (*)(cl_program program); -using clEnqueueMapBuffer_func = void *(*)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, size_t, size_t, cl_uint, const cl_event *, cl_event *, cl_int *); -using clReleaseCommandQueue_func = cl_int (*)(cl_command_queue); -using clCreateProgramWithBinary_func = cl_program (*)(cl_context, cl_uint, const cl_device_id *, const size_t *, const unsigned char **, cl_int *, cl_int *); -using clRetainContext_func = cl_int (*)(cl_context context); -using clReleaseProgram_func = cl_int (*)(cl_program program); -using clFlush_func = cl_int (*)(cl_command_queue command_queue); -using clGetProgramInfo_func = cl_int (*)(cl_program, cl_program_info, size_t, void *, size_t *); -using clCreateKernel_func = cl_kernel (*)(cl_program, const char *, cl_int *); -using clRetainKernel_func = cl_int (*)(cl_kernel kernel); -using clCreateBuffer_func = cl_mem (*)(cl_context, cl_mem_flags, size_t, void *, cl_int *); -using clCreateProgramWithSource_func = cl_program (*)(cl_context, cl_uint, const char **, const size_t *, cl_int *); -using clReleaseKernel_func = cl_int (*)(cl_kernel kernel); -using clGetDeviceInfo_func = cl_int (*)(cl_device_id, cl_device_info, size_t, void *, size_t *); -using clGetDeviceIDs_func = cl_int (*)(cl_platform_id, cl_device_type, cl_uint, cl_device_id *, cl_uint *); - -class CLSymbols +namespace arm_compute { -private: - CLSymbols() +CLSymbols &CLSymbols::get() +{ + static CLSymbols symbols; + return symbols; +} + +bool CLSymbols::load_default() +{ + static const std::vector libraries{ "libOpenCL.so", "libGLES_mali.so", "libmali.so" }; + + if(_loaded.first) { - void *handle = dlopen("libOpenCL.so", RTLD_LAZY | RTLD_LOCAL); - if(handle == nullptr) - { - std::cerr << "Can't load libOpenCL.so: " << dlerror() << std::endl; - } - else + return _loaded.second; + } + + // Indicate that default loading has been tried + _loaded.first = true; + + for(const auto &lib : libraries) + { + if(load(lib)) { - clBuildProgram = reinterpret_cast(dlsym(handle, "clBuildProgram")); - clEnqueueNDRangeKernel = reinterpret_cast(dlsym(handle, "clEnqueueNDRangeKernel")); - clSetKernelArg = reinterpret_cast(dlsym(handle, "clSetKernelArg")); - clReleaseKernel = reinterpret_cast(dlsym(handle, "clReleaseKernel")); - clCreateProgramWithSource = reinterpret_cast(dlsym(handle, "clCreateProgramWithSource")); - clCreateBuffer = reinterpret_cast(dlsym(handle, "clCreateBuffer")); - clRetainKernel = reinterpret_cast(dlsym(handle, "clRetainKernel")); - clCreateKernel = reinterpret_cast(dlsym(handle, "clCreateKernel")); - clGetProgramInfo = reinterpret_cast(dlsym(handle, "clGetProgramInfo")); - clFlush = reinterpret_cast(dlsym(handle, "clFlush")); - clReleaseProgram = reinterpret_cast(dlsym(handle, "clReleaseProgram")); - clRetainContext = reinterpret_cast(dlsym(handle, "clRetainContext")); - clCreateProgramWithBinary = reinterpret_cast(dlsym(handle, "clCreateProgramWithBinary")); - clReleaseCommandQueue = reinterpret_cast(dlsym(handle, "clReleaseCommandQueue")); - clEnqueueMapBuffer = reinterpret_cast(dlsym(handle, "clEnqueueMapBuffer")); - clRetainProgram = reinterpret_cast(dlsym(handle, "clRetainProgram")); - clGetProgramBuildInfo = reinterpret_cast(dlsym(handle, "clGetProgramBuildInfo")); - clEnqueueReadBuffer = reinterpret_cast(dlsym(handle, "clEnqueueReadBuffer")); - clEnqueueWriteBuffer = reinterpret_cast(dlsym(handle, "clEnqueueWriteBuffer")); - clReleaseEvent = reinterpret_cast(dlsym(handle, "clReleaseEvent")); - clReleaseContext = reinterpret_cast(dlsym(handle, "clReleaseContext")); - clRetainCommandQueue = reinterpret_cast(dlsym(handle, "clRetainCommandQueue")); - clEnqueueUnmapMemObject = reinterpret_cast(dlsym(handle, "clEnqueueUnmapMemObject")); - clReleaseMemObject = reinterpret_cast(dlsym(handle, "clReleaseMemObject")); - clGetDeviceInfo = reinterpret_cast(dlsym(handle, "clGetDeviceInfo")); - clGetDeviceIDs = reinterpret_cast(dlsym(handle, "clGetDeviceIDs")); - dlclose(handle); + return true; } } -public: - static CLSymbols &get() - { - static CLSymbols symbols = CLSymbols(); - return symbols; - } - - clBuildProgram_func clBuildProgram = nullptr; - clEnqueueNDRangeKernel_func clEnqueueNDRangeKernel = nullptr; - clSetKernelArg_func clSetKernelArg = nullptr; - clReleaseKernel_func clReleaseKernel = nullptr; - clCreateProgramWithSource_func clCreateProgramWithSource = nullptr; - clCreateBuffer_func clCreateBuffer = nullptr; - clRetainKernel_func clRetainKernel = nullptr; - clCreateKernel_func clCreateKernel = nullptr; - clGetProgramInfo_func clGetProgramInfo = nullptr; - clFlush_func clFlush = nullptr; - clReleaseProgram_func clReleaseProgram = nullptr; - clRetainContext_func clRetainContext = nullptr; - clCreateProgramWithBinary_func clCreateProgramWithBinary = nullptr; - clReleaseCommandQueue_func clReleaseCommandQueue = nullptr; - clEnqueueMapBuffer_func clEnqueueMapBuffer = nullptr; - clRetainProgram_func clRetainProgram = nullptr; - clGetProgramBuildInfo_func clGetProgramBuildInfo = nullptr; - clEnqueueReadBuffer_func clEnqueueReadBuffer = nullptr; - clEnqueueWriteBuffer_func clEnqueueWriteBuffer = nullptr; - clReleaseEvent_func clReleaseEvent = nullptr; - clReleaseContext_func clReleaseContext = nullptr; - clRetainCommandQueue_func clRetainCommandQueue = nullptr; - clEnqueueUnmapMemObject_func clEnqueueUnmapMemObject = nullptr; - clReleaseMemObject_func clReleaseMemObject = nullptr; - clGetDeviceInfo_func clGetDeviceInfo = nullptr; - clGetDeviceIDs_func clGetDeviceIDs = nullptr; -}; - -bool arm_compute::opencl_is_available() + std::cerr << "Couldn't find any OpenCL library.\n"; + return false; +} + +bool CLSymbols::load(const std::string &library) +{ + void *handle = dlopen(library.c_str(), RTLD_LAZY | RTLD_LOCAL); + + if(handle == nullptr) + { + std::cerr << "Can't load " << library << ": " << dlerror() << "\n"; + // Set status of loading to failed + _loaded.second = false; + return false; + } + + clBuildProgram = reinterpret_cast(dlsym(handle, "clBuildProgram")); + clEnqueueNDRangeKernel = reinterpret_cast(dlsym(handle, "clEnqueueNDRangeKernel")); + clSetKernelArg = reinterpret_cast(dlsym(handle, "clSetKernelArg")); + clReleaseKernel = reinterpret_cast(dlsym(handle, "clReleaseKernel")); + clCreateProgramWithSource = reinterpret_cast(dlsym(handle, "clCreateProgramWithSource")); + clCreateBuffer = reinterpret_cast(dlsym(handle, "clCreateBuffer")); + clRetainKernel = reinterpret_cast(dlsym(handle, "clRetainKernel")); + clCreateKernel = reinterpret_cast(dlsym(handle, "clCreateKernel")); + clGetProgramInfo = reinterpret_cast(dlsym(handle, "clGetProgramInfo")); + clFlush = reinterpret_cast(dlsym(handle, "clFlush")); + clReleaseProgram = reinterpret_cast(dlsym(handle, "clReleaseProgram")); + clRetainContext = reinterpret_cast(dlsym(handle, "clRetainContext")); + clCreateProgramWithBinary = reinterpret_cast(dlsym(handle, "clCreateProgramWithBinary")); + clReleaseCommandQueue = reinterpret_cast(dlsym(handle, "clReleaseCommandQueue")); + clEnqueueMapBuffer = reinterpret_cast(dlsym(handle, "clEnqueueMapBuffer")); + clRetainProgram = reinterpret_cast(dlsym(handle, "clRetainProgram")); + clGetProgramBuildInfo = reinterpret_cast(dlsym(handle, "clGetProgramBuildInfo")); + clEnqueueReadBuffer = reinterpret_cast(dlsym(handle, "clEnqueueReadBuffer")); + clEnqueueWriteBuffer = reinterpret_cast(dlsym(handle, "clEnqueueWriteBuffer")); + clReleaseEvent = reinterpret_cast(dlsym(handle, "clReleaseEvent")); + clReleaseContext = reinterpret_cast(dlsym(handle, "clReleaseContext")); + clRetainCommandQueue = reinterpret_cast(dlsym(handle, "clRetainCommandQueue")); + clEnqueueUnmapMemObject = reinterpret_cast(dlsym(handle, "clEnqueueUnmapMemObject")); + clReleaseMemObject = reinterpret_cast(dlsym(handle, "clReleaseMemObject")); + clGetDeviceInfo = reinterpret_cast(dlsym(handle, "clGetDeviceInfo")); + clGetDeviceIDs = reinterpret_cast(dlsym(handle, "clGetDeviceIDs")); + + dlclose(handle); + + // Disable default loading and set status to successful + _loaded = std::make_pair(true, true); + + return true; +} + +bool opencl_is_available() { + CLSymbols::get().load_default(); return CLSymbols::get().clBuildProgram != nullptr; } +} // namespace arm_compute cl_int clBuildProgram( cl_program program, @@ -144,7 +121,8 @@ cl_int clBuildProgram( void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data), void *user_data) { - auto func = CLSymbols::get().clBuildProgram; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clBuildProgram; if(func != nullptr) { return func(program, num_devices, device_list, options, pfn_notify, user_data); @@ -166,7 +144,8 @@ cl_int clEnqueueNDRangeKernel( const cl_event *event_wait_list, cl_event *event) { - auto func = CLSymbols::get().clEnqueueNDRangeKernel; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clEnqueueNDRangeKernel; if(func != nullptr) { return func(command_queue, kernel, work_dim, global_work_offset, global_work_size, local_work_size, num_events_in_wait_list, event_wait_list, event); @@ -183,7 +162,8 @@ cl_int clSetKernelArg( size_t arg_size, const void *arg_value) { - auto func = CLSymbols::get().clSetKernelArg; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clSetKernelArg; if(func != nullptr) { return func(kernel, arg_index, arg_size, arg_value); @@ -196,7 +176,8 @@ cl_int clSetKernelArg( cl_int clReleaseMemObject(cl_mem memobj) { - auto func = CLSymbols::get().clReleaseMemObject; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clReleaseMemObject; if(func != nullptr) { return func(memobj); @@ -215,7 +196,8 @@ cl_int clEnqueueUnmapMemObject( const cl_event *event_wait_list, cl_event *event) { - auto func = CLSymbols::get().clEnqueueUnmapMemObject; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clEnqueueUnmapMemObject; if(func != nullptr) { return func(command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event); @@ -228,7 +210,8 @@ cl_int clEnqueueUnmapMemObject( cl_int clRetainCommandQueue(cl_command_queue command_queue) { - auto func = CLSymbols::get().clRetainCommandQueue; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clRetainCommandQueue; if(func != nullptr) { return func(command_queue); @@ -241,7 +224,8 @@ cl_int clRetainCommandQueue(cl_command_queue command_queue) cl_int clReleaseContext(cl_context context) { - auto func = CLSymbols::get().clReleaseContext; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clReleaseContext; if(func != nullptr) { return func(context); @@ -253,7 +237,8 @@ cl_int clReleaseContext(cl_context context) } cl_int clReleaseEvent(cl_event event) { - auto func = CLSymbols::get().clReleaseEvent; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clReleaseEvent; if(func != nullptr) { return func(event); @@ -275,7 +260,8 @@ cl_int clEnqueueWriteBuffer( const cl_event *event_wait_list, cl_event *event) { - auto func = CLSymbols::get().clEnqueueWriteBuffer; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clEnqueueWriteBuffer; if(func != nullptr) { return func(command_queue, buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list, event); @@ -297,7 +283,8 @@ cl_int clEnqueueReadBuffer( const cl_event *event_wait_list, cl_event *event) { - auto func = CLSymbols::get().clEnqueueReadBuffer; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clEnqueueReadBuffer; if(func != nullptr) { return func(command_queue, buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list, event); @@ -316,7 +303,8 @@ cl_int clGetProgramBuildInfo( void *param_value, size_t *param_value_size_ret) { - auto func = CLSymbols::get().clGetProgramBuildInfo; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clGetProgramBuildInfo; if(func != nullptr) { return func(program, device, param_name, param_value_size, param_value, param_value_size_ret); @@ -329,7 +317,8 @@ cl_int clGetProgramBuildInfo( cl_int clRetainProgram(cl_program program) { - auto func = CLSymbols::get().clRetainProgram; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clRetainProgram; if(func != nullptr) { return func(program); @@ -352,7 +341,8 @@ void *clEnqueueMapBuffer( cl_event *event, cl_int *errcode_ret) { - auto func = CLSymbols::get().clEnqueueMapBuffer; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clEnqueueMapBuffer; if(func != nullptr) { return func(command_queue, buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list, event, errcode_ret); @@ -369,7 +359,8 @@ void *clEnqueueMapBuffer( cl_int clReleaseCommandQueue(cl_command_queue command_queue) { - auto func = CLSymbols::get().clReleaseCommandQueue; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clReleaseCommandQueue; if(func != nullptr) { return func(command_queue); @@ -389,7 +380,8 @@ cl_program clCreateProgramWithBinary( cl_int *binary_status, cl_int *errcode_ret) { - auto func = CLSymbols::get().clCreateProgramWithBinary; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clCreateProgramWithBinary; if(func != nullptr) { return func(context, num_devices, device_list, lengths, binaries, binary_status, errcode_ret); @@ -406,7 +398,8 @@ cl_program clCreateProgramWithBinary( cl_int clRetainContext(cl_context context) { - auto func = CLSymbols::get().clRetainContext; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clRetainContext; if(func != nullptr) { return func(context); @@ -419,7 +412,8 @@ cl_int clRetainContext(cl_context context) cl_int clReleaseProgram(cl_program program) { - auto func = CLSymbols::get().clReleaseProgram; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clReleaseProgram; if(func != nullptr) { return func(program); @@ -432,7 +426,8 @@ cl_int clReleaseProgram(cl_program program) cl_int clFlush(cl_command_queue command_queue) { - auto func = CLSymbols::get().clFlush; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clFlush; if(func != nullptr) { return func(command_queue); @@ -450,7 +445,8 @@ cl_int clGetProgramInfo( void *param_value, size_t *param_value_size_ret) { - auto func = CLSymbols::get().clGetProgramInfo; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clGetProgramInfo; if(func != nullptr) { return func(program, param_name, param_value_size, param_value, param_value_size_ret); @@ -466,7 +462,8 @@ cl_kernel clCreateKernel( const char *kernel_name, cl_int *errcode_ret) { - auto func = CLSymbols::get().clCreateKernel; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clCreateKernel; if(func != nullptr) { return func(program, kernel_name, errcode_ret); @@ -483,7 +480,8 @@ cl_kernel clCreateKernel( cl_int clRetainKernel(cl_kernel kernel) { - auto func = CLSymbols::get().clRetainKernel; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clRetainKernel; if(func != nullptr) { return func(kernel); @@ -501,7 +499,8 @@ cl_mem clCreateBuffer( void *host_ptr, cl_int *errcode_ret) { - auto func = CLSymbols::get().clCreateBuffer; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clCreateBuffer; if(func != nullptr) { return func(context, flags, size, host_ptr, errcode_ret); @@ -523,7 +522,8 @@ cl_program clCreateProgramWithSource( const size_t *lengths, cl_int *errcode_ret) { - auto func = CLSymbols::get().clCreateProgramWithSource; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clCreateProgramWithSource; if(func != nullptr) { return func(context, count, strings, lengths, errcode_ret); @@ -540,7 +540,8 @@ cl_program clCreateProgramWithSource( cl_int clReleaseKernel(cl_kernel kernel) { - auto func = CLSymbols::get().clReleaseKernel; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clReleaseKernel; if(func != nullptr) { return func(kernel); @@ -557,7 +558,8 @@ cl_int clGetDeviceIDs(cl_platform_id platform, cl_device_id *devices, cl_uint *num_devices) { - auto func = CLSymbols::get().clGetDeviceIDs; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clGetDeviceIDs; if(func != nullptr) { return func(platform, device_type, num_entries, devices, num_devices); @@ -574,7 +576,8 @@ cl_int clGetDeviceInfo(cl_device_id device, void *param_value, size_t *param_value_size_ret) { - auto func = CLSymbols::get().clGetDeviceInfo; + arm_compute::CLSymbols::get().load_default(); + auto func = arm_compute::CLSymbols::get().clGetDeviceInfo; if(func != nullptr) { return func(device, param_name, param_value_size, param_value, param_value_size_ret); -- cgit v1.2.1