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