• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017-2020 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))
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     std::cerr << "Couldn't find any OpenCL library.\n";
73     return false;
74 }
75 
load(const std::string & library)76 bool CLSymbols::load(const std::string &library)
77 {
78     void *handle = dlopen(library.c_str(), RTLD_LAZY | RTLD_LOCAL);
79 
80     if(handle == nullptr)
81     {
82         std::cerr << "Can't load " << library << ": " << dlerror() << "\n";
83         // Set status of loading to failed
84         _loaded.second = false;
85         return false;
86     }
87 
88 #define LOAD_FUNCTION_PTR(func_name, handle) \
89     func_name##_ptr = reinterpret_cast<decltype(func_name) *>(dlsym(handle, #func_name));
90 
91     LOAD_FUNCTION_PTR(clCreateContext, handle);
92     LOAD_FUNCTION_PTR(clCreateContextFromType, handle);
93     LOAD_FUNCTION_PTR(clCreateCommandQueue, handle);
94     LOAD_FUNCTION_PTR(clGetContextInfo, handle);
95     LOAD_FUNCTION_PTR(clBuildProgram, handle);
96     LOAD_FUNCTION_PTR(clEnqueueNDRangeKernel, handle);
97     LOAD_FUNCTION_PTR(clSetKernelArg, handle);
98     LOAD_FUNCTION_PTR(clReleaseKernel, handle);
99     LOAD_FUNCTION_PTR(clCreateProgramWithSource, handle);
100     LOAD_FUNCTION_PTR(clCreateBuffer, handle);
101     LOAD_FUNCTION_PTR(clRetainKernel, handle);
102     LOAD_FUNCTION_PTR(clCreateKernel, handle);
103     LOAD_FUNCTION_PTR(clGetProgramInfo, handle);
104     LOAD_FUNCTION_PTR(clFlush, handle);
105     LOAD_FUNCTION_PTR(clFinish, handle);
106     LOAD_FUNCTION_PTR(clReleaseProgram, handle);
107     LOAD_FUNCTION_PTR(clRetainContext, handle);
108     LOAD_FUNCTION_PTR(clCreateProgramWithBinary, handle);
109     LOAD_FUNCTION_PTR(clReleaseCommandQueue, handle);
110     LOAD_FUNCTION_PTR(clEnqueueMapBuffer, handle);
111     LOAD_FUNCTION_PTR(clRetainProgram, handle);
112     LOAD_FUNCTION_PTR(clGetProgramBuildInfo, handle);
113     LOAD_FUNCTION_PTR(clEnqueueReadBuffer, handle);
114     LOAD_FUNCTION_PTR(clEnqueueWriteBuffer, handle);
115     LOAD_FUNCTION_PTR(clReleaseEvent, handle);
116     LOAD_FUNCTION_PTR(clReleaseContext, handle);
117     LOAD_FUNCTION_PTR(clRetainCommandQueue, handle);
118     LOAD_FUNCTION_PTR(clEnqueueUnmapMemObject, handle);
119     LOAD_FUNCTION_PTR(clRetainMemObject, handle);
120     LOAD_FUNCTION_PTR(clReleaseMemObject, handle);
121     LOAD_FUNCTION_PTR(clGetDeviceInfo, handle);
122     LOAD_FUNCTION_PTR(clGetDeviceIDs, handle);
123     LOAD_FUNCTION_PTR(clGetMemObjectInfo, handle);
124     LOAD_FUNCTION_PTR(clRetainEvent, handle);
125     LOAD_FUNCTION_PTR(clGetPlatformIDs, handle);
126     LOAD_FUNCTION_PTR(clGetKernelWorkGroupInfo, handle);
127     LOAD_FUNCTION_PTR(clGetCommandQueueInfo, handle);
128     LOAD_FUNCTION_PTR(clGetKernelInfo, handle);
129     LOAD_FUNCTION_PTR(clGetEventProfilingInfo, handle);
130     LOAD_FUNCTION_PTR(clSVMAlloc, handle);
131     LOAD_FUNCTION_PTR(clSVMFree, handle);
132     LOAD_FUNCTION_PTR(clEnqueueSVMMap, handle);
133     LOAD_FUNCTION_PTR(clEnqueueSVMUnmap, handle);
134     LOAD_FUNCTION_PTR(clEnqueueMarker, handle);
135     LOAD_FUNCTION_PTR(clWaitForEvents, handle);
136     LOAD_FUNCTION_PTR(clCreateImage, handle);
137 
138     // Third-party extensions
139     LOAD_FUNCTION_PTR(clImportMemoryARM, handle);
140 
141 #undef LOAD_FUNCTION_PTR
142 
143     //Don't call dlclose(handle) or all the symbols will be unloaded !
144 
145     // Disable default loading and set status to successful
146     _loaded = std::make_pair(true, true);
147 
148     return true;
149 }
150 
opencl_is_available()151 bool opencl_is_available()
152 {
153     CLSymbols::get().load_default();
154     return CLSymbols::get().clBuildProgram_ptr != nullptr;
155 }
156 } // namespace arm_compute
157 
clEnqueueMarker(cl_command_queue command_queue,cl_event * event)158 cl_int clEnqueueMarker(cl_command_queue command_queue,
159                        cl_event        *event)
160 {
161     arm_compute::CLSymbols::get().load_default();
162     auto func = arm_compute::CLSymbols::get().clEnqueueMarker_ptr;
163     if(func != nullptr)
164     {
165         return func(command_queue, event);
166     }
167     else
168     {
169         return CL_OUT_OF_RESOURCES;
170     }
171 }
172 
clWaitForEvents(cl_uint num_events,const cl_event * event_list)173 cl_int clWaitForEvents(cl_uint         num_events,
174                        const cl_event *event_list)
175 {
176     arm_compute::CLSymbols::get().load_default();
177     auto func = arm_compute::CLSymbols::get().clWaitForEvents_ptr;
178     if(func != nullptr)
179     {
180         return func(num_events, event_list);
181     }
182     else
183     {
184         return CL_OUT_OF_RESOURCES;
185     }
186 }
187 
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)188 cl_int clEnqueueSVMMap(cl_command_queue command_queue, cl_bool blocking_map, cl_map_flags flags, void *svm_ptr,
189                        size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
190 {
191     arm_compute::CLSymbols::get().load_default();
192     auto func = arm_compute::CLSymbols::get().clEnqueueSVMMap_ptr;
193     if(func != nullptr)
194     {
195         return func(command_queue, blocking_map, flags, svm_ptr, size, num_events_in_wait_list, event_wait_list, event);
196     }
197     else
198     {
199         return CL_OUT_OF_RESOURCES;
200     }
201 }
202 
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)203 cl_int clEnqueueSVMUnmap(cl_command_queue command_queue, void *svm_ptr, cl_uint num_events_in_wait_list,
204                          const cl_event *event_wait_list, cl_event *event)
205 {
206     arm_compute::CLSymbols::get().load_default();
207     auto func = arm_compute::CLSymbols::get().clEnqueueSVMUnmap_ptr;
208     if(func != nullptr)
209     {
210         return func(command_queue, svm_ptr, num_events_in_wait_list, event_wait_list, event);
211     }
212     else
213     {
214         return CL_OUT_OF_RESOURCES;
215     }
216 }
217 
clSVMAlloc(cl_context context,cl_svm_mem_flags_arm flags,size_t size,cl_uint alignment)218 void *clSVMAlloc(cl_context context, cl_svm_mem_flags_arm flags, size_t size, cl_uint alignment)
219 {
220     arm_compute::CLSymbols::get().load_default();
221     auto func = arm_compute::CLSymbols::get().clSVMAlloc_ptr;
222     if(func != nullptr)
223     {
224         return func(context, flags, size, alignment);
225     }
226     else
227     {
228         return nullptr;
229     }
230 }
231 
clSVMFree(cl_context context,void * svm_pointer)232 void clSVMFree(cl_context context, void *svm_pointer)
233 {
234     arm_compute::CLSymbols::get().load_default();
235     auto func = arm_compute::CLSymbols::get().clSVMFree_ptr;
236     if(func != nullptr)
237     {
238         func(context, svm_pointer);
239     }
240 }
241 
clGetContextInfo(cl_context context,cl_context_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)242 cl_int clGetContextInfo(cl_context      context,
243                         cl_context_info param_name,
244                         size_t          param_value_size,
245                         void           *param_value,
246                         size_t         *param_value_size_ret)
247 {
248     arm_compute::CLSymbols::get().load_default();
249     auto func = arm_compute::CLSymbols::get().clGetContextInfo_ptr;
250     if(func != nullptr)
251     {
252         return func(context, param_name, param_value_size, param_value, param_value_size_ret);
253     }
254     else
255     {
256         return CL_OUT_OF_RESOURCES;
257     }
258 }
259 
clCreateCommandQueue(cl_context context,cl_device_id device,cl_command_queue_properties properties,cl_int * errcode_ret)260 cl_command_queue clCreateCommandQueue(cl_context                  context,
261                                       cl_device_id                device,
262                                       cl_command_queue_properties properties,
263                                       cl_int                     *errcode_ret)
264 {
265     arm_compute::CLSymbols::get().load_default();
266     auto func = arm_compute::CLSymbols::get().clCreateCommandQueue_ptr;
267     if(func != nullptr)
268     {
269         return func(context, device, properties, errcode_ret);
270     }
271     else
272     {
273         return nullptr;
274     }
275 }
276 
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)277 cl_context clCreateContext(
278     const cl_context_properties *properties,
279     cl_uint                      num_devices,
280     const cl_device_id          *devices,
281     void (*pfn_notify)(const char *, const void *, size_t, void *),
282     void   *user_data,
283     cl_int *errcode_ret)
284 {
285     arm_compute::CLSymbols::get().load_default();
286     auto func = arm_compute::CLSymbols::get().clCreateContext_ptr;
287     if(func != nullptr)
288     {
289         return func(properties, num_devices, devices, pfn_notify, user_data, errcode_ret);
290     }
291     else
292     {
293         return nullptr;
294     }
295 }
296 
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)297 cl_context clCreateContextFromType(const cl_context_properties *properties,
298                                    cl_device_type               device_type,
299                                    void (*pfn_notify)(const char *, const void *, size_t, void *),
300                                    void   *user_data,
301                                    cl_int *errcode_ret)
302 {
303     arm_compute::CLSymbols::get().load_default();
304     auto func = arm_compute::CLSymbols::get().clCreateContextFromType_ptr;
305     if(func != nullptr)
306     {
307         return func(properties, device_type, pfn_notify, user_data, errcode_ret);
308     }
309     else
310     {
311         return nullptr;
312     }
313 }
314 
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)315 cl_int clBuildProgram(
316     cl_program          program,
317     cl_uint             num_devices,
318     const cl_device_id *device_list,
319     const char         *options,
320     void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data),
321     void *user_data)
322 {
323     arm_compute::CLSymbols::get().load_default();
324     auto func = arm_compute::CLSymbols::get().clBuildProgram_ptr;
325     if(func != nullptr)
326     {
327         return func(program, num_devices, device_list, options, pfn_notify, user_data);
328     }
329     else
330     {
331         return CL_OUT_OF_RESOURCES;
332     }
333 }
334 
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)335 cl_int clEnqueueNDRangeKernel(
336     cl_command_queue command_queue,
337     cl_kernel        kernel,
338     cl_uint          work_dim,
339     const size_t    *global_work_offset,
340     const size_t    *global_work_size,
341     const size_t    *local_work_size,
342     cl_uint          num_events_in_wait_list,
343     const cl_event *event_wait_list,
344     cl_event        *event)
345 {
346     arm_compute::CLSymbols::get().load_default();
347     auto func = arm_compute::CLSymbols::get().clEnqueueNDRangeKernel_ptr;
348     if(func != nullptr)
349     {
350         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);
351     }
352     else
353     {
354         return CL_OUT_OF_RESOURCES;
355     }
356 }
357 
clSetKernelArg(cl_kernel kernel,cl_uint arg_index,size_t arg_size,const void * arg_value)358 cl_int clSetKernelArg(
359     cl_kernel   kernel,
360     cl_uint     arg_index,
361     size_t      arg_size,
362     const void *arg_value)
363 {
364     arm_compute::CLSymbols::get().load_default();
365     auto func = arm_compute::CLSymbols::get().clSetKernelArg_ptr;
366     if(func != nullptr)
367     {
368         return func(kernel, arg_index, arg_size, arg_value);
369     }
370     else
371     {
372         return CL_OUT_OF_RESOURCES;
373     }
374 }
375 
clRetainMemObject(cl_mem memobj)376 cl_int clRetainMemObject(cl_mem memobj)
377 {
378     arm_compute::CLSymbols::get().load_default();
379     auto func = arm_compute::CLSymbols::get().clRetainMemObject_ptr;
380     if(func != nullptr)
381     {
382         return func(memobj);
383     }
384     else
385     {
386         return CL_OUT_OF_RESOURCES;
387     }
388 }
389 
clReleaseMemObject(cl_mem memobj)390 cl_int clReleaseMemObject(cl_mem memobj)
391 {
392     arm_compute::CLSymbols::get().load_default();
393     auto func = arm_compute::CLSymbols::get().clReleaseMemObject_ptr;
394     if(func != nullptr)
395     {
396         return func(memobj);
397     }
398     else
399     {
400         return CL_OUT_OF_RESOURCES;
401     }
402 }
403 
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)404 cl_int clEnqueueUnmapMemObject(
405     cl_command_queue command_queue,
406     cl_mem           memobj,
407     void            *mapped_ptr,
408     cl_uint          num_events_in_wait_list,
409     const cl_event *event_wait_list,
410     cl_event        *event)
411 {
412     arm_compute::CLSymbols::get().load_default();
413     auto func = arm_compute::CLSymbols::get().clEnqueueUnmapMemObject_ptr;
414     if(func != nullptr)
415     {
416         return func(command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event);
417     }
418     else
419     {
420         return CL_OUT_OF_RESOURCES;
421     }
422 }
423 
clRetainCommandQueue(cl_command_queue command_queue)424 cl_int clRetainCommandQueue(cl_command_queue command_queue)
425 {
426     arm_compute::CLSymbols::get().load_default();
427     auto func = arm_compute::CLSymbols::get().clRetainCommandQueue_ptr;
428     if(func != nullptr)
429     {
430         return func(command_queue);
431     }
432     else
433     {
434         return CL_OUT_OF_RESOURCES;
435     }
436 }
437 
clReleaseContext(cl_context context)438 cl_int clReleaseContext(cl_context context)
439 {
440     arm_compute::CLSymbols::get().load_default();
441     auto func = arm_compute::CLSymbols::get().clReleaseContext_ptr;
442     if(func != nullptr)
443     {
444         return func(context);
445     }
446     else
447     {
448         return CL_OUT_OF_RESOURCES;
449     }
450 }
clReleaseEvent(cl_event event)451 cl_int clReleaseEvent(cl_event event)
452 {
453     arm_compute::CLSymbols::get().load_default();
454     auto func = arm_compute::CLSymbols::get().clReleaseEvent_ptr;
455     if(func != nullptr)
456     {
457         return func(event);
458     }
459     else
460     {
461         return CL_OUT_OF_RESOURCES;
462     }
463 }
464 
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)465 cl_int clEnqueueWriteBuffer(
466     cl_command_queue command_queue,
467     cl_mem           buffer,
468     cl_bool          blocking_write,
469     size_t           offset,
470     size_t           size,
471     const void      *ptr,
472     cl_uint          num_events_in_wait_list,
473     const cl_event *event_wait_list,
474     cl_event        *event)
475 {
476     arm_compute::CLSymbols::get().load_default();
477     auto func = arm_compute::CLSymbols::get().clEnqueueWriteBuffer_ptr;
478     if(func != nullptr)
479     {
480         return func(command_queue, buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list, event);
481     }
482     else
483     {
484         return CL_OUT_OF_RESOURCES;
485     }
486 }
487 
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)488 cl_int clEnqueueReadBuffer(
489     cl_command_queue command_queue,
490     cl_mem           buffer,
491     cl_bool          blocking_read,
492     size_t           offset,
493     size_t           size,
494     void            *ptr,
495     cl_uint          num_events_in_wait_list,
496     const cl_event *event_wait_list,
497     cl_event        *event)
498 {
499     arm_compute::CLSymbols::get().load_default();
500     auto func = arm_compute::CLSymbols::get().clEnqueueReadBuffer_ptr;
501     if(func != nullptr)
502     {
503         return func(command_queue, buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list, event);
504     }
505     else
506     {
507         return CL_OUT_OF_RESOURCES;
508     }
509 }
510 
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)511 cl_int clGetProgramBuildInfo(
512     cl_program            program,
513     cl_device_id          device,
514     cl_program_build_info param_name,
515     size_t                param_value_size,
516     void                 *param_value,
517     size_t               *param_value_size_ret)
518 {
519     arm_compute::CLSymbols::get().load_default();
520     auto func = arm_compute::CLSymbols::get().clGetProgramBuildInfo_ptr;
521     if(func != nullptr)
522     {
523         return func(program, device, param_name, param_value_size, param_value, param_value_size_ret);
524     }
525     else
526     {
527         return CL_OUT_OF_RESOURCES;
528     }
529 }
530 
clRetainProgram(cl_program program)531 cl_int clRetainProgram(cl_program program)
532 {
533     arm_compute::CLSymbols::get().load_default();
534     auto func = arm_compute::CLSymbols::get().clRetainProgram_ptr;
535     if(func != nullptr)
536     {
537         return func(program);
538     }
539     else
540     {
541         return CL_OUT_OF_RESOURCES;
542     }
543 }
544 
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)545 void *clEnqueueMapBuffer(
546     cl_command_queue command_queue,
547     cl_mem           buffer,
548     cl_bool          blocking_map,
549     cl_map_flags     map_flags,
550     size_t           offset,
551     size_t           size,
552     cl_uint          num_events_in_wait_list,
553     const cl_event *event_wait_list,
554     cl_event        *event,
555     cl_int          *errcode_ret)
556 {
557     arm_compute::CLSymbols::get().load_default();
558     auto func = arm_compute::CLSymbols::get().clEnqueueMapBuffer_ptr;
559     if(func != nullptr)
560     {
561         return func(command_queue, buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list, event, errcode_ret);
562     }
563     else
564     {
565         if(errcode_ret != nullptr)
566         {
567             *errcode_ret = CL_OUT_OF_RESOURCES;
568         }
569         return nullptr;
570     }
571 }
572 
clReleaseCommandQueue(cl_command_queue command_queue)573 cl_int clReleaseCommandQueue(cl_command_queue command_queue)
574 {
575     arm_compute::CLSymbols::get().load_default();
576     auto func = arm_compute::CLSymbols::get().clReleaseCommandQueue_ptr;
577     if(func != nullptr)
578     {
579         return func(command_queue);
580     }
581     else
582     {
583         return CL_OUT_OF_RESOURCES;
584     }
585 }
586 
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)587 cl_program clCreateProgramWithBinary(
588     cl_context            context,
589     cl_uint               num_devices,
590     const cl_device_id   *device_list,
591     const size_t         *lengths,
592     const unsigned char **binaries,
593     cl_int               *binary_status,
594     cl_int               *errcode_ret)
595 {
596     arm_compute::CLSymbols::get().load_default();
597     auto func = arm_compute::CLSymbols::get().clCreateProgramWithBinary_ptr;
598     if(func != nullptr)
599     {
600         return func(context, num_devices, device_list, lengths, binaries, binary_status, errcode_ret);
601     }
602     else
603     {
604         if(errcode_ret != nullptr)
605         {
606             *errcode_ret = CL_OUT_OF_RESOURCES;
607         }
608         return nullptr;
609     }
610 }
611 
clRetainContext(cl_context context)612 cl_int clRetainContext(cl_context context)
613 {
614     arm_compute::CLSymbols::get().load_default();
615     auto func = arm_compute::CLSymbols::get().clRetainContext_ptr;
616     if(func != nullptr)
617     {
618         return func(context);
619     }
620     else
621     {
622         return CL_OUT_OF_RESOURCES;
623     }
624 }
625 
clReleaseProgram(cl_program program)626 cl_int clReleaseProgram(cl_program program)
627 {
628     arm_compute::CLSymbols::get().load_default();
629     auto func = arm_compute::CLSymbols::get().clReleaseProgram_ptr;
630     if(func != nullptr)
631     {
632         return func(program);
633     }
634     else
635     {
636         return CL_OUT_OF_RESOURCES;
637     }
638 }
639 
clFlush(cl_command_queue command_queue)640 cl_int clFlush(cl_command_queue command_queue)
641 {
642     arm_compute::CLSymbols::get().load_default();
643     auto func = arm_compute::CLSymbols::get().clFlush_ptr;
644     if(func != nullptr)
645     {
646         return func(command_queue);
647     }
648     else
649     {
650         return CL_OUT_OF_RESOURCES;
651     }
652 }
653 
clFinish(cl_command_queue command_queue)654 cl_int clFinish(cl_command_queue command_queue)
655 {
656     arm_compute::CLSymbols::get().load_default();
657     auto func = arm_compute::CLSymbols::get().clFinish_ptr;
658     if(func != nullptr)
659     {
660         return func(command_queue);
661     }
662     else
663     {
664         return CL_OUT_OF_RESOURCES;
665     }
666 }
667 
clGetProgramInfo(cl_program program,cl_program_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)668 cl_int clGetProgramInfo(
669     cl_program      program,
670     cl_program_info param_name,
671     size_t          param_value_size,
672     void           *param_value,
673     size_t         *param_value_size_ret)
674 {
675     arm_compute::CLSymbols::get().load_default();
676     auto func = arm_compute::CLSymbols::get().clGetProgramInfo_ptr;
677     if(func != nullptr)
678     {
679         return func(program, param_name, param_value_size, param_value, param_value_size_ret);
680     }
681     else
682     {
683         return CL_OUT_OF_RESOURCES;
684     }
685 }
686 
clCreateKernel(cl_program program,const char * kernel_name,cl_int * errcode_ret)687 cl_kernel clCreateKernel(
688     cl_program  program,
689     const char *kernel_name,
690     cl_int     *errcode_ret)
691 {
692     arm_compute::CLSymbols::get().load_default();
693     auto func = arm_compute::CLSymbols::get().clCreateKernel_ptr;
694     if(func != nullptr)
695     {
696         return func(program, kernel_name, errcode_ret);
697     }
698     else
699     {
700         if(errcode_ret != nullptr)
701         {
702             *errcode_ret = CL_OUT_OF_RESOURCES;
703         }
704         return nullptr;
705     }
706 }
707 
clRetainKernel(cl_kernel kernel)708 cl_int clRetainKernel(cl_kernel kernel)
709 {
710     arm_compute::CLSymbols::get().load_default();
711     auto func = arm_compute::CLSymbols::get().clRetainKernel_ptr;
712     if(func != nullptr)
713     {
714         return func(kernel);
715     }
716     else
717     {
718         return CL_OUT_OF_RESOURCES;
719     }
720 }
721 
clCreateBuffer(cl_context context,cl_mem_flags flags,size_t size,void * host_ptr,cl_int * errcode_ret)722 cl_mem clCreateBuffer(
723     cl_context   context,
724     cl_mem_flags flags,
725     size_t       size,
726     void        *host_ptr,
727     cl_int      *errcode_ret)
728 {
729     arm_compute::CLSymbols::get().load_default();
730     auto func = arm_compute::CLSymbols::get().clCreateBuffer_ptr;
731     if(func != nullptr)
732     {
733         return func(context, flags, size, host_ptr, errcode_ret);
734     }
735     else
736     {
737         if(errcode_ret != nullptr)
738         {
739             *errcode_ret = CL_OUT_OF_RESOURCES;
740         }
741         return nullptr;
742     }
743 }
744 
clCreateProgramWithSource(cl_context context,cl_uint count,const char ** strings,const size_t * lengths,cl_int * errcode_ret)745 cl_program clCreateProgramWithSource(
746     cl_context    context,
747     cl_uint       count,
748     const char **strings,
749     const size_t *lengths,
750     cl_int       *errcode_ret)
751 {
752     arm_compute::CLSymbols::get().load_default();
753     auto func = arm_compute::CLSymbols::get().clCreateProgramWithSource_ptr;
754     if(func != nullptr)
755     {
756         return func(context, count, strings, lengths, errcode_ret);
757     }
758     else
759     {
760         if(errcode_ret != nullptr)
761         {
762             *errcode_ret = CL_OUT_OF_RESOURCES;
763         }
764         return nullptr;
765     }
766 }
767 
clReleaseKernel(cl_kernel kernel)768 cl_int clReleaseKernel(cl_kernel kernel)
769 {
770     arm_compute::CLSymbols::get().load_default();
771     auto func = arm_compute::CLSymbols::get().clReleaseKernel_ptr;
772     if(func != nullptr)
773     {
774         return func(kernel);
775     }
776     else
777     {
778         return CL_OUT_OF_RESOURCES;
779     }
780 }
781 
clGetDeviceIDs(cl_platform_id platform,cl_device_type device_type,cl_uint num_entries,cl_device_id * devices,cl_uint * num_devices)782 cl_int clGetDeviceIDs(cl_platform_id platform,
783                       cl_device_type device_type,
784                       cl_uint        num_entries,
785                       cl_device_id *devices,
786                       cl_uint       *num_devices)
787 {
788     arm_compute::CLSymbols::get().load_default();
789     auto func = arm_compute::CLSymbols::get().clGetDeviceIDs_ptr;
790     if(func != nullptr)
791     {
792         return func(platform, device_type, num_entries, devices, num_devices);
793     }
794     else
795     {
796         return CL_OUT_OF_RESOURCES;
797     }
798 }
799 
clGetDeviceInfo(cl_device_id device,cl_device_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)800 cl_int clGetDeviceInfo(cl_device_id   device,
801                        cl_device_info param_name,
802                        size_t         param_value_size,
803                        void          *param_value,
804                        size_t        *param_value_size_ret)
805 {
806     arm_compute::CLSymbols::get().load_default();
807     auto func = arm_compute::CLSymbols::get().clGetDeviceInfo_ptr;
808     if(func != nullptr)
809     {
810         return func(device, param_name, param_value_size, param_value, param_value_size_ret);
811     }
812     else
813     {
814         return CL_OUT_OF_RESOURCES;
815     }
816 }
817 
clGetMemObjectInfo(cl_mem memobj,cl_mem_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret)818 cl_int clGetMemObjectInfo(cl_mem      memobj,
819                           cl_mem_info param_name,
820                           size_t      param_value_size,
821                           void       *param_value,
822                           size_t     *param_value_size_ret)
823 {
824     arm_compute::CLSymbols::get().load_default();
825     auto func = arm_compute::CLSymbols::get().clGetMemObjectInfo_ptr;
826     if(func != nullptr)
827     {
828         return func(memobj, param_name, param_value_size, param_value, param_value_size_ret);
829     }
830     else
831     {
832         return CL_OUT_OF_RESOURCES;
833     }
834 }
835 
clRetainEvent(cl_event event)836 cl_int clRetainEvent(cl_event event)
837 {
838     arm_compute::CLSymbols::get().load_default();
839     auto func = arm_compute::CLSymbols::get().clRetainEvent_ptr;
840     if(func != nullptr)
841     {
842         return func(event);
843     }
844     else
845     {
846         return CL_OUT_OF_RESOURCES;
847     }
848 }
849 
clGetPlatformIDs(cl_uint num_entries,cl_platform_id * platforms,cl_uint * num_platforms)850 cl_int clGetPlatformIDs(cl_uint num_entries, cl_platform_id *platforms, cl_uint *num_platforms)
851 {
852     arm_compute::CLSymbols::get().load_default();
853     auto func = arm_compute::CLSymbols::get().clGetPlatformIDs_ptr;
854     if(func != nullptr)
855     {
856         return func(num_entries, platforms, num_platforms);
857     }
858     else
859     {
860         return CL_OUT_OF_RESOURCES;
861     }
862 }
863 
864 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)865 clGetKernelWorkGroupInfo(cl_kernel                 kernel,
866                          cl_device_id              device,
867                          cl_kernel_work_group_info param_name,
868                          size_t                    param_value_size,
869                          void                     *param_value,
870                          size_t                   *param_value_size_ret)
871 {
872     arm_compute::CLSymbols::get().load_default();
873     auto func = arm_compute::CLSymbols::get().clGetKernelWorkGroupInfo_ptr;
874     if(func != nullptr)
875     {
876         return func(kernel, device, param_name, param_value_size, param_value, param_value_size_ret);
877     }
878     else
879     {
880         return CL_OUT_OF_RESOURCES;
881     }
882 }
883 
884 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)885 clGetCommandQueueInfo(cl_command_queue      command_queue,
886                       cl_command_queue_info param_name,
887                       size_t                param_value_size,
888                       void                 *param_value,
889                       size_t               *param_value_size_ret)
890 {
891     arm_compute::CLSymbols::get().load_default();
892     auto func = arm_compute::CLSymbols::get().clGetCommandQueueInfo_ptr;
893     if(func != nullptr)
894     {
895         return func(command_queue, param_name, param_value_size, param_value, param_value_size_ret);
896     }
897     else
898     {
899         return CL_OUT_OF_RESOURCES;
900     }
901 }
902 
903 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)904 clGetKernelInfo(cl_kernel      kernel,
905                 cl_kernel_info param_name,
906                 size_t         param_value_size,
907                 void          *param_value,
908                 size_t        *param_value_size_ret)
909 {
910     arm_compute::CLSymbols::get().load_default();
911     auto func = arm_compute::CLSymbols::get().clGetKernelInfo_ptr;
912     if(func != nullptr)
913     {
914         return func(kernel, param_name, param_value_size, param_value, param_value_size_ret);
915     }
916     else
917     {
918         return CL_OUT_OF_RESOURCES;
919     }
920 }
921 
922 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)923 clGetEventProfilingInfo(cl_event          event,
924                         cl_profiling_info param_name,
925                         size_t            param_value_size,
926                         void             *param_value,
927                         size_t           *param_value_size_ret)
928 {
929     arm_compute::CLSymbols::get().load_default();
930     auto func = arm_compute::CLSymbols::get().clGetEventProfilingInfo_ptr;
931     if(func != nullptr)
932     {
933         return func(event, param_name, param_value_size, param_value, param_value_size_ret);
934     }
935     else
936     {
937         return CL_OUT_OF_RESOURCES;
938     }
939 }
940 
941 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)942 clCreateImage(cl_context             context,
943               cl_mem_flags           flags,
944               const cl_image_format *image_format,
945               const cl_image_desc   *image_desc,
946               void                  *host_ptr,
947               cl_int                *errcode_ret)
948 {
949     arm_compute::CLSymbols::get().load_default();
950     auto func = arm_compute::CLSymbols::get().clCreateImage_ptr;
951     if(func != nullptr)
952     {
953         return func(context, flags, image_format, image_desc, host_ptr, errcode_ret);
954     }
955     else
956     {
957         if(errcode_ret != nullptr)
958         {
959             *errcode_ret = CL_OUT_OF_RESOURCES;
960         }
961         return nullptr;
962     }
963 }
964 
965 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)966 clImportMemoryARM(cl_context                      context,
967                   cl_mem_flags                    flags,
968                   const cl_import_properties_arm *properties,
969                   void                           *memory,
970                   size_t                          size,
971                   cl_int                         *errcode_ret)
972 {
973     arm_compute::CLSymbols::get().load_default();
974     auto func = arm_compute::CLSymbols::get().clImportMemoryARM_ptr;
975     if(func != nullptr)
976     {
977         return func(context, flags, properties, memory, size, errcode_ret);
978     }
979     else
980     {
981         if(errcode_ret != nullptr)
982         {
983             *errcode_ret = CL_OUT_OF_RESOURCES;
984         }
985         return nullptr;
986     }
987 }
988