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