• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017-2022 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #pragma GCC diagnostic push
26 #pragma GCC diagnostic ignored "-Wunused-parameter"
27 #include "arm_compute/core/CL/OpenCL.h"
28 #pragma GCC diagnostic pop
29 
30 #include "arm_compute/core/Error.h"
31 
32 #include <dlfcn.h>
33 #include <iostream>
34 
35 namespace arm_compute
36 {
CLSymbols()37 CLSymbols::CLSymbols() noexcept(false)
38     : _loaded(
39 {
40     false, false
41 })
42 {
43 }
44 
get()45 CLSymbols &CLSymbols::get()
46 {
47     static CLSymbols symbols;
48     return symbols;
49 }
50 
load_default()51 bool CLSymbols::load_default()
52 {
53     static const std::vector<std::string> libraries{ "libOpenCL.so", "libGLES_mali.so", "libmali.so" };
54 
55     if(_loaded.first)
56     {
57         return _loaded.second;
58     }
59 
60     // Indicate that default loading has been tried
61     _loaded.first = true;
62 
63     for(const auto &lib : libraries)
64     {
65         if(load(lib, /* use_loader */false))
66         {
67             ARM_COMPUTE_ERROR_ON_MSG(this->clBuildProgram_ptr == nullptr, "Failed to load OpenCL symbols from shared library");
68             return true;
69         }
70     }
71 
72 #ifdef __ANDROID__
73     // When running in NDK environment, the above libraries are not accessible.
74     static const std::vector<std::string> android_libraries{ "libOpenCL-pixel.so", "libOpenCL-car.so" };
75 
76     for(const auto &lib : android_libraries)
77     {
78         if(load(lib, /* use_loader */true))
79         {
80             ARM_COMPUTE_ERROR_ON_MSG(this->clBuildProgram_ptr == nullptr, "Failed to load OpenCL symbols from android shared library");
81             return true;
82         }
83     }
84 #endif /* __ANDROID__ */
85 
86     std::cerr << "Couldn't find any OpenCL library.\n";
87     return false;
88 }
89 
load(const std::string & library,bool use_loader)90 bool CLSymbols::load(const std::string &library, bool use_loader)
91 {
92     void *handle = dlopen(library.c_str(), RTLD_LAZY | RTLD_LOCAL);
93 
94     if(handle == nullptr)
95     {
96         std::cerr << "Can't load " << library << ": " << dlerror() << "\n";
97         // Set status of loading to failed
98         _loaded.second = false;
99         return false;
100     }
101 
102 #ifdef __ANDROID__
103     typedef void* (*loadOpenCLPointer_t)(const char* name);
104     loadOpenCLPointer_t loadOpenCLPointer;
105     if (use_loader) {
106         typedef void (*enableOpenCL_t)();
107         enableOpenCL_t enableOpenCL =
108             reinterpret_cast<enableOpenCL_t>(dlsym(handle, "enableOpenCL"));
109         enableOpenCL();
110 
111         loadOpenCLPointer = reinterpret_cast<loadOpenCLPointer_t>(
112             dlsym(handle, "loadOpenCLPointer"));
113     } else {
114         loadOpenCLPointer = nullptr;
115     }
116 #define LOAD_FUNCTION_PTR(func_name, _handle) \
117     func_name##_ptr = reinterpret_cast<decltype(func_name) *>( use_loader ? \
118         loadOpenCLPointer(#func_name) : dlsym(handle, #func_name));
119 #else /* __ANDROID__ */
120     (void)use_loader; // Avoid unused warning
121 #define LOAD_FUNCTION_PTR(func_name, handle) \
122     func_name##_ptr = reinterpret_cast<decltype(func_name) *>(dlsym(handle, #func_name));
123 #endif /* __ANDROID__ */
124 
125     LOAD_FUNCTION_PTR(clCreateContext, handle);
126     LOAD_FUNCTION_PTR(clCreateContextFromType, handle);
127     LOAD_FUNCTION_PTR(clCreateCommandQueue, handle);
128     LOAD_FUNCTION_PTR(clCreateCommandQueueWithProperties, handle);
129     LOAD_FUNCTION_PTR(clGetContextInfo, handle);
130     LOAD_FUNCTION_PTR(clBuildProgram, handle);
131     LOAD_FUNCTION_PTR(clEnqueueNDRangeKernel, handle);
132     LOAD_FUNCTION_PTR(clSetKernelArg, handle);
133     LOAD_FUNCTION_PTR(clReleaseKernel, handle);
134     LOAD_FUNCTION_PTR(clCreateProgramWithSource, handle);
135     LOAD_FUNCTION_PTR(clCreateBuffer, handle);
136     LOAD_FUNCTION_PTR(clRetainKernel, handle);
137     LOAD_FUNCTION_PTR(clCreateKernel, handle);
138     LOAD_FUNCTION_PTR(clGetProgramInfo, handle);
139     LOAD_FUNCTION_PTR(clFlush, handle);
140     LOAD_FUNCTION_PTR(clFinish, handle);
141     LOAD_FUNCTION_PTR(clReleaseProgram, handle);
142     LOAD_FUNCTION_PTR(clRetainContext, handle);
143     LOAD_FUNCTION_PTR(clCreateProgramWithBinary, handle);
144     LOAD_FUNCTION_PTR(clReleaseCommandQueue, handle);
145     LOAD_FUNCTION_PTR(clEnqueueMapBuffer, handle);
146     LOAD_FUNCTION_PTR(clRetainProgram, handle);
147     LOAD_FUNCTION_PTR(clGetProgramBuildInfo, handle);
148     LOAD_FUNCTION_PTR(clEnqueueReadBuffer, handle);
149     LOAD_FUNCTION_PTR(clEnqueueWriteBuffer, handle);
150     LOAD_FUNCTION_PTR(clReleaseEvent, handle);
151     LOAD_FUNCTION_PTR(clReleaseContext, handle);
152     LOAD_FUNCTION_PTR(clRetainCommandQueue, handle);
153     LOAD_FUNCTION_PTR(clEnqueueUnmapMemObject, handle);
154     LOAD_FUNCTION_PTR(clRetainMemObject, handle);
155     LOAD_FUNCTION_PTR(clReleaseMemObject, handle);
156     LOAD_FUNCTION_PTR(clGetDeviceInfo, handle);
157     LOAD_FUNCTION_PTR(clGetDeviceIDs, handle);
158     LOAD_FUNCTION_PTR(clGetMemObjectInfo, handle);
159     LOAD_FUNCTION_PTR(clRetainEvent, handle);
160     LOAD_FUNCTION_PTR(clGetPlatformInfo, handle);
161     LOAD_FUNCTION_PTR(clGetPlatformIDs, handle);
162     LOAD_FUNCTION_PTR(clGetKernelWorkGroupInfo, handle);
163     LOAD_FUNCTION_PTR(clGetCommandQueueInfo, handle);
164     LOAD_FUNCTION_PTR(clGetKernelInfo, handle);
165     LOAD_FUNCTION_PTR(clGetEventProfilingInfo, handle);
166     LOAD_FUNCTION_PTR(clSVMAlloc, handle);
167     LOAD_FUNCTION_PTR(clSVMFree, handle);
168     LOAD_FUNCTION_PTR(clEnqueueSVMMap, handle);
169     LOAD_FUNCTION_PTR(clEnqueueSVMUnmap, handle);
170     LOAD_FUNCTION_PTR(clEnqueueMarker, handle);
171     LOAD_FUNCTION_PTR(clWaitForEvents, handle);
172     LOAD_FUNCTION_PTR(clCreateImage, handle);
173     LOAD_FUNCTION_PTR(clSetKernelExecInfo, handle);
174 
175     // Third-party extensions
176     LOAD_FUNCTION_PTR(clImportMemoryARM, handle);
177 
178 #undef LOAD_FUNCTION_PTR
179 
180     //Don't call dlclose(handle) or all the symbols will be unloaded !
181 
182     // Disable default loading and set status to successful
183     _loaded = std::make_pair(true, true);
184 
185     return true;
186 }
187 
opencl_is_available()188 bool opencl_is_available()
189 {
190     CLSymbols::get().load_default();
191 
192     // Using static objects that rely on OpenCL in their constructor or
193     // destructor is implementation defined according to the OpenCL API
194     // Specification. These objects include CLScheduler.
195     //
196     // For compatibility with OpenCL runtimes that also use static objects to
197     // hold their state, we call a harmless OpenCL function (clGetPlatformIDs
198     // with invalid parameters must result in CL_INVALID_VALUE) to ensure the
199     // runtimes have a chance to initialize their static objects first. Thanks
200     // to C++11 rules about normal program completion (cf [basic.start]), this
201     // ensures their static objects are destroyed last, i.e. after the
202     // singleton CLScheduler is destroyed.
203     //
204     // When OpenCL is not available, this call results in CL_OUT_OF_RESOURCES,
205     // which is equally harmless.
206     (void)clGetPlatformIDs(0, nullptr, nullptr);
207 
208     return CLSymbols::get().clBuildProgram_ptr != nullptr;
209 }
210 } // namespace arm_compute
211 
clEnqueueMarker(cl_command_queue command_queue,cl_event * event)212 cl_int clEnqueueMarker(cl_command_queue command_queue,
213                        cl_event        *event)
214 {
215     arm_compute::CLSymbols::get().load_default();
216     auto func = arm_compute::CLSymbols::get().clEnqueueMarker_ptr;
217     if(func != nullptr)
218     {
219         return func(command_queue, event);
220     }
221     else
222     {
223         return CL_OUT_OF_RESOURCES;
224     }
225 }
226 
clWaitForEvents(cl_uint num_events,const cl_event * event_list)227 cl_int clWaitForEvents(cl_uint         num_events,
228                        const cl_event *event_list)
229 {
230     arm_compute::CLSymbols::get().load_default();
231     auto func = arm_compute::CLSymbols::get().clWaitForEvents_ptr;
232     if(func != nullptr)
233     {
234         return func(num_events, event_list);
235     }
236     else
237     {
238         return CL_OUT_OF_RESOURCES;
239     }
240 }
241 
clEnqueueSVMMap(cl_command_queue command_queue,cl_bool blocking_map,cl_map_flags flags,void * svm_ptr,size_t size,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event)242 cl_int clEnqueueSVMMap(cl_command_queue command_queue, cl_bool blocking_map, cl_map_flags flags, void *svm_ptr,
243                        size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
244 {
245     arm_compute::CLSymbols::get().load_default();
246     auto func = arm_compute::CLSymbols::get().clEnqueueSVMMap_ptr;
247     if(func != nullptr)
248     {
249         return func(command_queue, blocking_map, flags, svm_ptr, size, num_events_in_wait_list, event_wait_list, event);
250     }
251     else
252     {
253         return CL_OUT_OF_RESOURCES;
254     }
255 }
256 
clEnqueueSVMUnmap(cl_command_queue command_queue,void * svm_ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event)257 cl_int clEnqueueSVMUnmap(cl_command_queue command_queue, void *svm_ptr, cl_uint num_events_in_wait_list,
258                          const cl_event *event_wait_list, cl_event *event)
259 {
260     arm_compute::CLSymbols::get().load_default();
261     auto func = arm_compute::CLSymbols::get().clEnqueueSVMUnmap_ptr;
262     if(func != nullptr)
263     {
264         return func(command_queue, svm_ptr, num_events_in_wait_list, event_wait_list, event);
265     }
266     else
267     {
268         return CL_OUT_OF_RESOURCES;
269     }
270 }
271 
clSVMAlloc(cl_context context,cl_svm_mem_flags_arm flags,size_t size,cl_uint alignment)272 void *clSVMAlloc(cl_context context, cl_svm_mem_flags_arm flags, size_t size, cl_uint alignment)
273 {
274     arm_compute::CLSymbols::get().load_default();
275     auto func = arm_compute::CLSymbols::get().clSVMAlloc_ptr;
276     if(func != nullptr)
277     {
278         return func(context, flags, size, alignment);
279     }
280     else
281     {
282         return nullptr;
283     }
284 }
285 
clSVMFree(cl_context context,void * svm_pointer)286 void clSVMFree(cl_context context, void *svm_pointer)
287 {
288     arm_compute::CLSymbols::get().load_default();
289     auto func = arm_compute::CLSymbols::get().clSVMFree_ptr;
290     if(func != nullptr)
291     {
292         func(context, svm_pointer);
293     }
294 }
295 
clGetContextInfo(cl_context context,cl_context_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)296 cl_int clGetContextInfo(cl_context      context,
297                         cl_context_info param_name,
298                         size_t          param_value_size,
299                         void           *param_value,
300                         size_t         *param_value_size_ret)
301 {
302     arm_compute::CLSymbols::get().load_default();
303     auto func = arm_compute::CLSymbols::get().clGetContextInfo_ptr;
304     if(func != nullptr)
305     {
306         return func(context, param_name, param_value_size, param_value, param_value_size_ret);
307     }
308     else
309     {
310         return CL_OUT_OF_RESOURCES;
311     }
312 }
313 
clCreateCommandQueue(cl_context context,cl_device_id device,cl_command_queue_properties properties,cl_int * errcode_ret)314 cl_command_queue clCreateCommandQueue(cl_context                  context,
315                                       cl_device_id                device,
316                                       cl_command_queue_properties properties,
317                                       cl_int                     *errcode_ret)
318 {
319     arm_compute::CLSymbols::get().load_default();
320     auto func = arm_compute::CLSymbols::get().clCreateCommandQueue_ptr;
321     if(func != nullptr)
322     {
323         return func(context, device, properties, errcode_ret);
324     }
325     else
326     {
327         return nullptr;
328     }
329 }
330 
clCreateCommandQueueWithProperties(cl_context context,cl_device_id device,const cl_queue_properties * properties,cl_int * errcode_ret)331 cl_command_queue clCreateCommandQueueWithProperties(cl_context                 context,
332                                                     cl_device_id               device,
333                                                     const cl_queue_properties *properties,
334                                                     cl_int                    *errcode_ret)
335 {
336     arm_compute::CLSymbols::get().load_default();
337     auto func = arm_compute::CLSymbols::get().clCreateCommandQueueWithProperties_ptr;
338     if(func != nullptr)
339     {
340         return func(context, device, properties, errcode_ret);
341     }
342     else
343     {
344         return nullptr;
345     }
346 }
347 
clCreateContext(const cl_context_properties * properties,cl_uint num_devices,const cl_device_id * devices,void (* pfn_notify)(const char *,const void *,size_t,void *),void * user_data,cl_int * errcode_ret)348 cl_context clCreateContext(
349     const cl_context_properties *properties,
350     cl_uint                      num_devices,
351     const cl_device_id          *devices,
352     void (*pfn_notify)(const char *, const void *, size_t, void *),
353     void   *user_data,
354     cl_int *errcode_ret)
355 {
356     arm_compute::CLSymbols::get().load_default();
357     auto func = arm_compute::CLSymbols::get().clCreateContext_ptr;
358     if(func != nullptr)
359     {
360         return func(properties, num_devices, devices, pfn_notify, user_data, errcode_ret);
361     }
362     else
363     {
364         return nullptr;
365     }
366 }
367 
clCreateContextFromType(const cl_context_properties * properties,cl_device_type device_type,void (* pfn_notify)(const char *,const void *,size_t,void *),void * user_data,cl_int * errcode_ret)368 cl_context clCreateContextFromType(const cl_context_properties *properties,
369                                    cl_device_type               device_type,
370                                    void (*pfn_notify)(const char *, const void *, size_t, void *),
371                                    void   *user_data,
372                                    cl_int *errcode_ret)
373 {
374     arm_compute::CLSymbols::get().load_default();
375     auto func = arm_compute::CLSymbols::get().clCreateContextFromType_ptr;
376     if(func != nullptr)
377     {
378         return func(properties, device_type, pfn_notify, user_data, errcode_ret);
379     }
380     else
381     {
382         return nullptr;
383     }
384 }
385 
clBuildProgram(cl_program program,cl_uint num_devices,const cl_device_id * device_list,const char * options,void (CL_CALLBACK * pfn_notify)(cl_program program,void * user_data),void * user_data)386 cl_int clBuildProgram(
387     cl_program          program,
388     cl_uint             num_devices,
389     const cl_device_id *device_list,
390     const char         *options,
391     void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
392     void *user_data)
393 {
394     arm_compute::CLSymbols::get().load_default();
395     auto func = arm_compute::CLSymbols::get().clBuildProgram_ptr;
396     if(func != nullptr)
397     {
398         return func(program, num_devices, device_list, options, pfn_notify, user_data);
399     }
400     else
401     {
402         return CL_OUT_OF_RESOURCES;
403     }
404 }
405 
clEnqueueNDRangeKernel(cl_command_queue command_queue,cl_kernel kernel,cl_uint work_dim,const size_t * global_work_offset,const size_t * global_work_size,const size_t * local_work_size,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event)406 cl_int clEnqueueNDRangeKernel(
407     cl_command_queue command_queue,
408     cl_kernel        kernel,
409     cl_uint          work_dim,
410     const size_t    *global_work_offset,
411     const size_t    *global_work_size,
412     const size_t    *local_work_size,
413     cl_uint          num_events_in_wait_list,
414     const cl_event *event_wait_list,
415     cl_event        *event)
416 {
417     arm_compute::CLSymbols::get().load_default();
418     auto func = arm_compute::CLSymbols::get().clEnqueueNDRangeKernel_ptr;
419     if(func != nullptr)
420     {
421         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);
422     }
423     else
424     {
425         return CL_OUT_OF_RESOURCES;
426     }
427 }
428 
clSetKernelArg(cl_kernel kernel,cl_uint arg_index,size_t arg_size,const void * arg_value)429 cl_int clSetKernelArg(
430     cl_kernel   kernel,
431     cl_uint     arg_index,
432     size_t      arg_size,
433     const void *arg_value)
434 {
435     arm_compute::CLSymbols::get().load_default();
436     auto func = arm_compute::CLSymbols::get().clSetKernelArg_ptr;
437     if(func != nullptr)
438     {
439         return func(kernel, arg_index, arg_size, arg_value);
440     }
441     else
442     {
443         return CL_OUT_OF_RESOURCES;
444     }
445 }
446 
clRetainMemObject(cl_mem memobj)447 cl_int clRetainMemObject(cl_mem memobj)
448 {
449     arm_compute::CLSymbols::get().load_default();
450     auto func = arm_compute::CLSymbols::get().clRetainMemObject_ptr;
451     if(func != nullptr)
452     {
453         return func(memobj);
454     }
455     else
456     {
457         return CL_OUT_OF_RESOURCES;
458     }
459 }
460 
clReleaseMemObject(cl_mem memobj)461 cl_int clReleaseMemObject(cl_mem memobj)
462 {
463     arm_compute::CLSymbols::get().load_default();
464     auto func = arm_compute::CLSymbols::get().clReleaseMemObject_ptr;
465     if(func != nullptr)
466     {
467         return func(memobj);
468     }
469     else
470     {
471         return CL_OUT_OF_RESOURCES;
472     }
473 }
474 
clEnqueueUnmapMemObject(cl_command_queue command_queue,cl_mem memobj,void * mapped_ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event)475 cl_int clEnqueueUnmapMemObject(
476     cl_command_queue command_queue,
477     cl_mem           memobj,
478     void            *mapped_ptr,
479     cl_uint          num_events_in_wait_list,
480     const cl_event *event_wait_list,
481     cl_event        *event)
482 {
483     arm_compute::CLSymbols::get().load_default();
484     auto func = arm_compute::CLSymbols::get().clEnqueueUnmapMemObject_ptr;
485     if(func != nullptr)
486     {
487         return func(command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event);
488     }
489     else
490     {
491         return CL_OUT_OF_RESOURCES;
492     }
493 }
494 
clRetainCommandQueue(cl_command_queue command_queue)495 cl_int clRetainCommandQueue(cl_command_queue command_queue)
496 {
497     arm_compute::CLSymbols::get().load_default();
498     auto func = arm_compute::CLSymbols::get().clRetainCommandQueue_ptr;
499     if(func != nullptr)
500     {
501         return func(command_queue);
502     }
503     else
504     {
505         return CL_OUT_OF_RESOURCES;
506     }
507 }
508 
clReleaseContext(cl_context context)509 cl_int clReleaseContext(cl_context context)
510 {
511     arm_compute::CLSymbols::get().load_default();
512     auto func = arm_compute::CLSymbols::get().clReleaseContext_ptr;
513     if(func != nullptr)
514     {
515         return func(context);
516     }
517     else
518     {
519         return CL_OUT_OF_RESOURCES;
520     }
521 }
clReleaseEvent(cl_event event)522 cl_int clReleaseEvent(cl_event event)
523 {
524     arm_compute::CLSymbols::get().load_default();
525     auto func = arm_compute::CLSymbols::get().clReleaseEvent_ptr;
526     if(func != nullptr)
527     {
528         return func(event);
529     }
530     else
531     {
532         return CL_OUT_OF_RESOURCES;
533     }
534 }
535 
clEnqueueWriteBuffer(cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_write,size_t offset,size_t size,const void * ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event)536 cl_int clEnqueueWriteBuffer(
537     cl_command_queue command_queue,
538     cl_mem           buffer,
539     cl_bool          blocking_write,
540     size_t           offset,
541     size_t           size,
542     const void      *ptr,
543     cl_uint          num_events_in_wait_list,
544     const cl_event *event_wait_list,
545     cl_event        *event)
546 {
547     arm_compute::CLSymbols::get().load_default();
548     auto func = arm_compute::CLSymbols::get().clEnqueueWriteBuffer_ptr;
549     if(func != nullptr)
550     {
551         return func(command_queue, buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list, event);
552     }
553     else
554     {
555         return CL_OUT_OF_RESOURCES;
556     }
557 }
558 
clEnqueueReadBuffer(cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_read,size_t offset,size_t size,void * ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event)559 cl_int clEnqueueReadBuffer(
560     cl_command_queue command_queue,
561     cl_mem           buffer,
562     cl_bool          blocking_read,
563     size_t           offset,
564     size_t           size,
565     void            *ptr,
566     cl_uint          num_events_in_wait_list,
567     const cl_event *event_wait_list,
568     cl_event        *event)
569 {
570     arm_compute::CLSymbols::get().load_default();
571     auto func = arm_compute::CLSymbols::get().clEnqueueReadBuffer_ptr;
572     if(func != nullptr)
573     {
574         return func(command_queue, buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list, event);
575     }
576     else
577     {
578         return CL_OUT_OF_RESOURCES;
579     }
580 }
581 
clGetProgramBuildInfo(cl_program program,cl_device_id device,cl_program_build_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)582 cl_int clGetProgramBuildInfo(
583     cl_program            program,
584     cl_device_id          device,
585     cl_program_build_info param_name,
586     size_t                param_value_size,
587     void                 *param_value,
588     size_t               *param_value_size_ret)
589 {
590     arm_compute::CLSymbols::get().load_default();
591     auto func = arm_compute::CLSymbols::get().clGetProgramBuildInfo_ptr;
592     if(func != nullptr)
593     {
594         return func(program, device, param_name, param_value_size, param_value, param_value_size_ret);
595     }
596     else
597     {
598         return CL_OUT_OF_RESOURCES;
599     }
600 }
601 
clRetainProgram(cl_program program)602 cl_int clRetainProgram(cl_program program)
603 {
604     arm_compute::CLSymbols::get().load_default();
605     auto func = arm_compute::CLSymbols::get().clRetainProgram_ptr;
606     if(func != nullptr)
607     {
608         return func(program);
609     }
610     else
611     {
612         return CL_OUT_OF_RESOURCES;
613     }
614 }
615 
clEnqueueMapBuffer(cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_map,cl_map_flags map_flags,size_t offset,size_t size,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event,cl_int * errcode_ret)616 void *clEnqueueMapBuffer(
617     cl_command_queue command_queue,
618     cl_mem           buffer,
619     cl_bool          blocking_map,
620     cl_map_flags     map_flags,
621     size_t           offset,
622     size_t           size,
623     cl_uint          num_events_in_wait_list,
624     const cl_event *event_wait_list,
625     cl_event        *event,
626     cl_int          *errcode_ret)
627 {
628     arm_compute::CLSymbols::get().load_default();
629     auto func = arm_compute::CLSymbols::get().clEnqueueMapBuffer_ptr;
630     if(func != nullptr)
631     {
632         return func(command_queue, buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list, event, errcode_ret);
633     }
634     else
635     {
636         if(errcode_ret != nullptr)
637         {
638             *errcode_ret = CL_OUT_OF_RESOURCES;
639         }
640         return nullptr;
641     }
642 }
643 
clReleaseCommandQueue(cl_command_queue command_queue)644 cl_int clReleaseCommandQueue(cl_command_queue command_queue)
645 {
646     arm_compute::CLSymbols::get().load_default();
647     auto func = arm_compute::CLSymbols::get().clReleaseCommandQueue_ptr;
648     if(func != nullptr)
649     {
650         return func(command_queue);
651     }
652     else
653     {
654         return CL_OUT_OF_RESOURCES;
655     }
656 }
657 
clCreateProgramWithBinary(cl_context context,cl_uint num_devices,const cl_device_id * device_list,const size_t * lengths,const unsigned char ** binaries,cl_int * binary_status,cl_int * errcode_ret)658 cl_program clCreateProgramWithBinary(
659     cl_context            context,
660     cl_uint               num_devices,
661     const cl_device_id   *device_list,
662     const size_t         *lengths,
663     const unsigned char **binaries,
664     cl_int               *binary_status,
665     cl_int               *errcode_ret)
666 {
667     arm_compute::CLSymbols::get().load_default();
668     auto func = arm_compute::CLSymbols::get().clCreateProgramWithBinary_ptr;
669     if(func != nullptr)
670     {
671         return func(context, num_devices, device_list, lengths, binaries, binary_status, errcode_ret);
672     }
673     else
674     {
675         if(errcode_ret != nullptr)
676         {
677             *errcode_ret = CL_OUT_OF_RESOURCES;
678         }
679         return nullptr;
680     }
681 }
682 
clRetainContext(cl_context context)683 cl_int clRetainContext(cl_context context)
684 {
685     arm_compute::CLSymbols::get().load_default();
686     auto func = arm_compute::CLSymbols::get().clRetainContext_ptr;
687     if(func != nullptr)
688     {
689         return func(context);
690     }
691     else
692     {
693         return CL_OUT_OF_RESOURCES;
694     }
695 }
696 
clReleaseProgram(cl_program program)697 cl_int clReleaseProgram(cl_program program)
698 {
699     arm_compute::CLSymbols::get().load_default();
700     auto func = arm_compute::CLSymbols::get().clReleaseProgram_ptr;
701     if(func != nullptr)
702     {
703         return func(program);
704     }
705     else
706     {
707         return CL_OUT_OF_RESOURCES;
708     }
709 }
710 
clFlush(cl_command_queue command_queue)711 cl_int clFlush(cl_command_queue command_queue)
712 {
713     arm_compute::CLSymbols::get().load_default();
714     auto func = arm_compute::CLSymbols::get().clFlush_ptr;
715     if(func != nullptr)
716     {
717         return func(command_queue);
718     }
719     else
720     {
721         return CL_OUT_OF_RESOURCES;
722     }
723 }
724 
clFinish(cl_command_queue command_queue)725 cl_int clFinish(cl_command_queue command_queue)
726 {
727     arm_compute::CLSymbols::get().load_default();
728     auto func = arm_compute::CLSymbols::get().clFinish_ptr;
729     if(func != nullptr)
730     {
731         return func(command_queue);
732     }
733     else
734     {
735         return CL_OUT_OF_RESOURCES;
736     }
737 }
738 
clGetProgramInfo(cl_program program,cl_program_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)739 cl_int clGetProgramInfo(
740     cl_program      program,
741     cl_program_info param_name,
742     size_t          param_value_size,
743     void           *param_value,
744     size_t         *param_value_size_ret)
745 {
746     arm_compute::CLSymbols::get().load_default();
747     auto func = arm_compute::CLSymbols::get().clGetProgramInfo_ptr;
748     if(func != nullptr)
749     {
750         return func(program, param_name, param_value_size, param_value, param_value_size_ret);
751     }
752     else
753     {
754         return CL_OUT_OF_RESOURCES;
755     }
756 }
757 
clCreateKernel(cl_program program,const char * kernel_name,cl_int * errcode_ret)758 cl_kernel clCreateKernel(
759     cl_program  program,
760     const char *kernel_name,
761     cl_int     *errcode_ret)
762 {
763     arm_compute::CLSymbols::get().load_default();
764     auto func = arm_compute::CLSymbols::get().clCreateKernel_ptr;
765     if(func != nullptr)
766     {
767         return func(program, kernel_name, errcode_ret);
768     }
769     else
770     {
771         if(errcode_ret != nullptr)
772         {
773             *errcode_ret = CL_OUT_OF_RESOURCES;
774         }
775         return nullptr;
776     }
777 }
778 
clRetainKernel(cl_kernel kernel)779 cl_int clRetainKernel(cl_kernel kernel)
780 {
781     arm_compute::CLSymbols::get().load_default();
782     auto func = arm_compute::CLSymbols::get().clRetainKernel_ptr;
783     if(func != nullptr)
784     {
785         return func(kernel);
786     }
787     else
788     {
789         return CL_OUT_OF_RESOURCES;
790     }
791 }
792 
clCreateBuffer(cl_context context,cl_mem_flags flags,size_t size,void * host_ptr,cl_int * errcode_ret)793 cl_mem clCreateBuffer(
794     cl_context   context,
795     cl_mem_flags flags,
796     size_t       size,
797     void        *host_ptr,
798     cl_int      *errcode_ret)
799 {
800     arm_compute::CLSymbols::get().load_default();
801     auto func = arm_compute::CLSymbols::get().clCreateBuffer_ptr;
802     if(func != nullptr)
803     {
804         return func(context, flags, size, host_ptr, errcode_ret);
805     }
806     else
807     {
808         if(errcode_ret != nullptr)
809         {
810             *errcode_ret = CL_OUT_OF_RESOURCES;
811         }
812         return nullptr;
813     }
814 }
815 
clCreateProgramWithSource(cl_context context,cl_uint count,const char ** strings,const size_t * lengths,cl_int * errcode_ret)816 cl_program clCreateProgramWithSource(
817     cl_context    context,
818     cl_uint       count,
819     const char **strings,
820     const size_t *lengths,
821     cl_int       *errcode_ret)
822 {
823     arm_compute::CLSymbols::get().load_default();
824     auto func = arm_compute::CLSymbols::get().clCreateProgramWithSource_ptr;
825     if(func != nullptr)
826     {
827         return func(context, count, strings, lengths, errcode_ret);
828     }
829     else
830     {
831         if(errcode_ret != nullptr)
832         {
833             *errcode_ret = CL_OUT_OF_RESOURCES;
834         }
835         return nullptr;
836     }
837 }
838 
clReleaseKernel(cl_kernel kernel)839 cl_int clReleaseKernel(cl_kernel kernel)
840 {
841     arm_compute::CLSymbols::get().load_default();
842     auto func = arm_compute::CLSymbols::get().clReleaseKernel_ptr;
843     if(func != nullptr)
844     {
845         return func(kernel);
846     }
847     else
848     {
849         return CL_OUT_OF_RESOURCES;
850     }
851 }
852 
clGetDeviceIDs(cl_platform_id platform,cl_device_type device_type,cl_uint num_entries,cl_device_id * devices,cl_uint * num_devices)853 cl_int clGetDeviceIDs(cl_platform_id platform,
854                       cl_device_type device_type,
855                       cl_uint        num_entries,
856                       cl_device_id *devices,
857                       cl_uint       *num_devices)
858 {
859     arm_compute::CLSymbols::get().load_default();
860     auto func = arm_compute::CLSymbols::get().clGetDeviceIDs_ptr;
861     if(func != nullptr)
862     {
863         return func(platform, device_type, num_entries, devices, num_devices);
864     }
865     else
866     {
867         return CL_OUT_OF_RESOURCES;
868     }
869 }
870 
clGetDeviceInfo(cl_device_id device,cl_device_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)871 cl_int clGetDeviceInfo(cl_device_id   device,
872                        cl_device_info param_name,
873                        size_t         param_value_size,
874                        void          *param_value,
875                        size_t        *param_value_size_ret)
876 {
877     arm_compute::CLSymbols::get().load_default();
878     auto func = arm_compute::CLSymbols::get().clGetDeviceInfo_ptr;
879     if(func != nullptr)
880     {
881         return func(device, param_name, param_value_size, param_value, param_value_size_ret);
882     }
883     else
884     {
885         return CL_OUT_OF_RESOURCES;
886     }
887 }
888 
clGetMemObjectInfo(cl_mem memobj,cl_mem_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)889 cl_int clGetMemObjectInfo(cl_mem      memobj,
890                           cl_mem_info param_name,
891                           size_t      param_value_size,
892                           void       *param_value,
893                           size_t     *param_value_size_ret)
894 {
895     arm_compute::CLSymbols::get().load_default();
896     auto func = arm_compute::CLSymbols::get().clGetMemObjectInfo_ptr;
897     if(func != nullptr)
898     {
899         return func(memobj, param_name, param_value_size, param_value, param_value_size_ret);
900     }
901     else
902     {
903         return CL_OUT_OF_RESOURCES;
904     }
905 }
906 
clRetainEvent(cl_event event)907 cl_int clRetainEvent(cl_event event)
908 {
909     arm_compute::CLSymbols::get().load_default();
910     auto func = arm_compute::CLSymbols::get().clRetainEvent_ptr;
911     if(func != nullptr)
912     {
913         return func(event);
914     }
915     else
916     {
917         return CL_OUT_OF_RESOURCES;
918     }
919 }
920 
clGetPlatformInfo(cl_platform_id platform,cl_platform_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)921 cl_int clGetPlatformInfo(cl_platform_id   platform,
922                          cl_platform_info param_name,
923                          size_t           param_value_size,
924                          void            *param_value,
925                          size_t          *param_value_size_ret)
926 {
927     arm_compute::CLSymbols::get().load_default();
928     auto func = arm_compute::CLSymbols::get().clGetPlatformInfo_ptr;
929     if(func != nullptr)
930     {
931         return func(platform, param_name, param_value_size, param_value, param_value_size_ret);
932     }
933     else
934     {
935         return CL_OUT_OF_RESOURCES;
936     }
937 }
938 
clGetPlatformIDs(cl_uint num_entries,cl_platform_id * platforms,cl_uint * num_platforms)939 cl_int clGetPlatformIDs(cl_uint num_entries, cl_platform_id *platforms, cl_uint *num_platforms)
940 {
941     arm_compute::CLSymbols::get().load_default();
942     auto func = arm_compute::CLSymbols::get().clGetPlatformIDs_ptr;
943     if(func != nullptr)
944     {
945         return func(num_entries, platforms, num_platforms);
946     }
947     else
948     {
949         return CL_OUT_OF_RESOURCES;
950     }
951 }
952 
953 cl_int
clGetKernelWorkGroupInfo(cl_kernel kernel,cl_device_id device,cl_kernel_work_group_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)954 clGetKernelWorkGroupInfo(cl_kernel                 kernel,
955                          cl_device_id              device,
956                          cl_kernel_work_group_info param_name,
957                          size_t                    param_value_size,
958                          void                     *param_value,
959                          size_t                   *param_value_size_ret)
960 {
961     arm_compute::CLSymbols::get().load_default();
962     auto func = arm_compute::CLSymbols::get().clGetKernelWorkGroupInfo_ptr;
963     if(func != nullptr)
964     {
965         return func(kernel, device, param_name, param_value_size, param_value, param_value_size_ret);
966     }
967     else
968     {
969         return CL_OUT_OF_RESOURCES;
970     }
971 }
972 
973 cl_int
clGetCommandQueueInfo(cl_command_queue command_queue,cl_command_queue_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)974 clGetCommandQueueInfo(cl_command_queue      command_queue,
975                       cl_command_queue_info param_name,
976                       size_t                param_value_size,
977                       void                 *param_value,
978                       size_t               *param_value_size_ret)
979 {
980     arm_compute::CLSymbols::get().load_default();
981     auto func = arm_compute::CLSymbols::get().clGetCommandQueueInfo_ptr;
982     if(func != nullptr)
983     {
984         return func(command_queue, param_name, param_value_size, param_value, param_value_size_ret);
985     }
986     else
987     {
988         return CL_OUT_OF_RESOURCES;
989     }
990 }
991 
992 cl_int
clGetKernelInfo(cl_kernel kernel,cl_kernel_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)993 clGetKernelInfo(cl_kernel      kernel,
994                 cl_kernel_info param_name,
995                 size_t         param_value_size,
996                 void          *param_value,
997                 size_t        *param_value_size_ret)
998 {
999     arm_compute::CLSymbols::get().load_default();
1000     auto func = arm_compute::CLSymbols::get().clGetKernelInfo_ptr;
1001     if(func != nullptr)
1002     {
1003         return func(kernel, param_name, param_value_size, param_value, param_value_size_ret);
1004     }
1005     else
1006     {
1007         return CL_OUT_OF_RESOURCES;
1008     }
1009 }
1010 
1011 cl_int
clGetEventProfilingInfo(cl_event event,cl_profiling_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)1012 clGetEventProfilingInfo(cl_event          event,
1013                         cl_profiling_info param_name,
1014                         size_t            param_value_size,
1015                         void             *param_value,
1016                         size_t           *param_value_size_ret)
1017 {
1018     arm_compute::CLSymbols::get().load_default();
1019     auto func = arm_compute::CLSymbols::get().clGetEventProfilingInfo_ptr;
1020     if(func != nullptr)
1021     {
1022         return func(event, param_name, param_value_size, param_value, param_value_size_ret);
1023     }
1024     else
1025     {
1026         return CL_OUT_OF_RESOURCES;
1027     }
1028 }
1029 
1030 cl_mem
clCreateImage(cl_context context,cl_mem_flags flags,const cl_image_format * image_format,const cl_image_desc * image_desc,void * host_ptr,cl_int * errcode_ret)1031 clCreateImage(cl_context             context,
1032               cl_mem_flags           flags,
1033               const cl_image_format *image_format,
1034               const cl_image_desc   *image_desc,
1035               void                  *host_ptr,
1036               cl_int                *errcode_ret)
1037 {
1038     arm_compute::CLSymbols::get().load_default();
1039     auto func = arm_compute::CLSymbols::get().clCreateImage_ptr;
1040     if(func != nullptr)
1041     {
1042         return func(context, flags, image_format, image_desc, host_ptr, errcode_ret);
1043     }
1044     else
1045     {
1046         if(errcode_ret != nullptr)
1047         {
1048             *errcode_ret = CL_OUT_OF_RESOURCES;
1049         }
1050         return nullptr;
1051     }
1052 }
1053 
clSetKernelExecInfo(cl_kernel kernel,cl_kernel_exec_info param_name,size_t param_value_size,const void * param_value)1054 cl_int clSetKernelExecInfo(cl_kernel           kernel,
1055                            cl_kernel_exec_info param_name,
1056                            size_t              param_value_size,
1057                            const void         *param_value)
1058 {
1059     arm_compute::CLSymbols::get().load_default();
1060     auto func = arm_compute::CLSymbols::get().clSetKernelExecInfo_ptr;
1061     if(func != nullptr)
1062     {
1063         return func(kernel, param_name, param_value_size, param_value);
1064     }
1065     else
1066     {
1067         return CL_OUT_OF_RESOURCES;
1068     }
1069 }
1070 
1071 cl_mem
clImportMemoryARM(cl_context context,cl_mem_flags flags,const cl_import_properties_arm * properties,void * memory,size_t size,cl_int * errcode_ret)1072 clImportMemoryARM(cl_context                      context,
1073                   cl_mem_flags                    flags,
1074                   const cl_import_properties_arm *properties,
1075                   void                           *memory,
1076                   size_t                          size,
1077                   cl_int                         *errcode_ret)
1078 {
1079     arm_compute::CLSymbols::get().load_default();
1080     auto func = arm_compute::CLSymbols::get().clImportMemoryARM_ptr;
1081     if(func != nullptr)
1082     {
1083         return func(context, flags, properties, memory, size, errcode_ret);
1084     }
1085     else
1086     {
1087         if(errcode_ret != nullptr)
1088         {
1089             *errcode_ret = CL_OUT_OF_RESOURCES;
1090         }
1091         return nullptr;
1092     }
1093 }
1094