1/*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#define USE_OPENCL_WRAPPER
16#ifdef USE_OPENCL_WRAPPER
17
18#include "opencl_wrapper.h"
19#include <algorithm>
20#include <dlfcn.h>
21#include <memory>
22#include <mutex>
23#include <string>
24#include <vector>
25#include <iostream>
26
27namespace OHOS {
28// default opencl library path
29static const std::vector<std::string> g_opencl_library_paths = {
30#if defined(__APPLE__) || defined(__MACOSX)
31    "libOpenCL.so", "/System/Library/Frameworks/OpenCL.framework/OpenCL"
32#else
33    "/vendor/lib64/chipsetsdk/libGLES_mali.so",
34    "/system/lib64/libGLES_mali.so",
35    "libGLES_mali.so",
36    "/vendor/lib64/chipsetsdk/libhvgr_v200.so",
37    "/vendor/lib64/chipsetsdk/libEGL_impl.so",
38#endif
39};
40
41static std::mutex g_initMutex;
42static bool g_isInit = false;
43static bool g_loadSuccess = false;
44static void *g_handle{nullptr};
45
46bool InitOpenCL()
47{
48    std::lock_guard<std::mutex> lock(g_initMutex);
49    if (g_isInit) {
50        return g_loadSuccess;
51    }
52    g_isInit = true;
53    g_loadSuccess = LoadOpenCLLibrary(&g_handle);
54    return g_loadSuccess;
55}
56
57bool UnLoadOpenCLLibrary(void *handle)
58{
59    if (handle != nullptr) {
60        if (dlclose(handle) != 0) {
61            return false;
62        }
63        return true;
64    }
65    return true;
66}
67
68bool InitOpenCLExtern(void **clSoHandle)
69{
70    if (clSoHandle == nullptr) {
71        return false;
72    }
73    return LoadOpenCLLibrary(clSoHandle);
74}
75
76bool UnLoadCLExtern(void *clSoHandle)
77{
78    if (clSoHandle == nullptr) {
79        return false;
80    }
81    if (dlclose(clSoHandle) != 0) {
82        return false;
83    }
84    return true;
85}
86
87static bool LoadLibraryFromPath(const std::string &library_path, void **handle_ptr)
88{
89    if (handle_ptr == nullptr) {
90        return false;
91    }
92
93    *handle_ptr = dlopen(library_path.c_str(), RTLD_NOW | RTLD_LOCAL);
94    if (*handle_ptr == nullptr) {
95        return false;
96    }
97
98// load function ptr use dlopen and dlsym.
99#define LOAD_OPENCL_FUNCTION_PTR(func_name)                                                    \
100    func_name = reinterpret_cast<func_name##Func>(dlsym(*handle_ptr, #func_name));             \
101    if (func_name == nullptr) {                                                                \
102        return false;                                                                          \
103    }
104
105    LOAD_OPENCL_FUNCTION_PTR(clGetPlatformIDs);
106    LOAD_OPENCL_FUNCTION_PTR(clGetPlatformInfo);
107    LOAD_OPENCL_FUNCTION_PTR(clBuildProgram);
108    LOAD_OPENCL_FUNCTION_PTR(clEnqueueNDRangeKernel);
109    LOAD_OPENCL_FUNCTION_PTR(clSetKernelArg);
110    LOAD_OPENCL_FUNCTION_PTR(clReleaseKernel);
111    LOAD_OPENCL_FUNCTION_PTR(clCreateProgramWithSource);
112    LOAD_OPENCL_FUNCTION_PTR(clCreateBuffer);
113    LOAD_OPENCL_FUNCTION_PTR(clCreateImage2D);
114    LOAD_OPENCL_FUNCTION_PTR(clCreateImage3D);
115    LOAD_OPENCL_FUNCTION_PTR(clRetainKernel);
116    LOAD_OPENCL_FUNCTION_PTR(clCreateKernel);
117    LOAD_OPENCL_FUNCTION_PTR(clGetProgramInfo);
118    LOAD_OPENCL_FUNCTION_PTR(clFlush);
119    LOAD_OPENCL_FUNCTION_PTR(clFinish);
120    LOAD_OPENCL_FUNCTION_PTR(clReleaseProgram);
121    LOAD_OPENCL_FUNCTION_PTR(clRetainContext);
122    LOAD_OPENCL_FUNCTION_PTR(clGetContextInfo);
123    LOAD_OPENCL_FUNCTION_PTR(clCreateProgramWithBinary);
124    LOAD_OPENCL_FUNCTION_PTR(clCreateCommandQueue);
125    LOAD_OPENCL_FUNCTION_PTR(clGetCommandQueueInfo);
126    LOAD_OPENCL_FUNCTION_PTR(clReleaseCommandQueue);
127    LOAD_OPENCL_FUNCTION_PTR(clEnqueueMapBuffer);
128    LOAD_OPENCL_FUNCTION_PTR(clEnqueueMapImage);
129    LOAD_OPENCL_FUNCTION_PTR(clRetainProgram);
130    LOAD_OPENCL_FUNCTION_PTR(clGetProgramBuildInfo);
131    LOAD_OPENCL_FUNCTION_PTR(clEnqueueReadBuffer);
132    LOAD_OPENCL_FUNCTION_PTR(clEnqueueReadBufferRect);
133    LOAD_OPENCL_FUNCTION_PTR(clEnqueueWriteBuffer);
134    LOAD_OPENCL_FUNCTION_PTR(clEnqueueReadImage);
135    LOAD_OPENCL_FUNCTION_PTR(clEnqueueWriteImage);
136    LOAD_OPENCL_FUNCTION_PTR(clWaitForEvents);
137    LOAD_OPENCL_FUNCTION_PTR(clReleaseEvent);
138    LOAD_OPENCL_FUNCTION_PTR(clCreateContext);
139    LOAD_OPENCL_FUNCTION_PTR(clCreateContextFromType);
140    LOAD_OPENCL_FUNCTION_PTR(clReleaseContext);
141    LOAD_OPENCL_FUNCTION_PTR(clRetainCommandQueue);
142    LOAD_OPENCL_FUNCTION_PTR(clEnqueueUnmapMemObject);
143    LOAD_OPENCL_FUNCTION_PTR(clRetainMemObject);
144    LOAD_OPENCL_FUNCTION_PTR(clReleaseMemObject);
145    LOAD_OPENCL_FUNCTION_PTR(clGetDeviceInfo);
146    LOAD_OPENCL_FUNCTION_PTR(clGetDeviceIDs);
147    LOAD_OPENCL_FUNCTION_PTR(clRetainEvent);
148    LOAD_OPENCL_FUNCTION_PTR(clGetKernelWorkGroupInfo);
149    LOAD_OPENCL_FUNCTION_PTR(clGetEventInfo);
150    LOAD_OPENCL_FUNCTION_PTR(clGetEventProfilingInfo);
151    LOAD_OPENCL_FUNCTION_PTR(clGetImageInfo);
152    LOAD_OPENCL_FUNCTION_PTR(clEnqueueCopyImage);
153    LOAD_OPENCL_FUNCTION_PTR(clEnqueueCopyBufferToImage);
154    LOAD_OPENCL_FUNCTION_PTR(clEnqueueCopyImageToBuffer);
155#if defined(CL_TARGET_OPENCL_VERSION) && CL_TARGET_OPENCL_VERSION >= 120
156    LOAD_OPENCL_FUNCTION_PTR(clRetainDevice);
157    LOAD_OPENCL_FUNCTION_PTR(clReleaseDevice);
158    LOAD_OPENCL_FUNCTION_PTR(clCreateImage);
159    LOAD_OPENCL_FUNCTION_PTR(clEnqueueFillImage);
160#endif
161#if defined(CL_TARGET_OPENCL_VERSION) && CL_TARGET_OPENCL_VERSION >= 200
162    LOAD_OPENCL_FUNCTION_PTR(clCreateCommandQueueWithProperties);
163    LOAD_OPENCL_FUNCTION_PTR(clGetExtensionFunctionAddress);
164    LOAD_OPENCL_FUNCTION_PTR(clSVMAlloc);
165    LOAD_OPENCL_FUNCTION_PTR(clSVMFree);
166    LOAD_OPENCL_FUNCTION_PTR(clEnqueueSVMMap);
167    LOAD_OPENCL_FUNCTION_PTR(clEnqueueSVMUnmap);
168    LOAD_OPENCL_FUNCTION_PTR(clSetKernelArgSVMPointer);
169#endif
170
171    return true;
172}
173// load default library path
174bool LoadOpenCLLibrary(void **handle_ptr)
175{
176    if (handle_ptr == nullptr) {
177        return false;
178    }
179    auto it =
180      std::find_if(g_opencl_library_paths.begin(), g_opencl_library_paths.end(),
181                   [&](const std::string &lib_path) { return OHOS::LoadLibraryFromPath(lib_path, handle_ptr); });
182    if (it != g_opencl_library_paths.end()) {
183        return true;
184    }
185    return false;
186}
187
188#define CL_DEFINE_FUNC_PTR(func) func##Func func = nullptr
189
190CL_DEFINE_FUNC_PTR(clGetPlatformIDs);
191CL_DEFINE_FUNC_PTR(clGetPlatformInfo);
192CL_DEFINE_FUNC_PTR(clBuildProgram);
193CL_DEFINE_FUNC_PTR(clEnqueueNDRangeKernel);
194CL_DEFINE_FUNC_PTR(clSetKernelArg);
195CL_DEFINE_FUNC_PTR(clReleaseKernel);
196CL_DEFINE_FUNC_PTR(clCreateProgramWithSource);
197CL_DEFINE_FUNC_PTR(clCreateBuffer);
198CL_DEFINE_FUNC_PTR(clCreateImage2D);
199CL_DEFINE_FUNC_PTR(clImportMemoryARM);
200CL_DEFINE_FUNC_PTR(clCreateImage3D);
201CL_DEFINE_FUNC_PTR(clRetainKernel);
202CL_DEFINE_FUNC_PTR(clCreateKernel);
203CL_DEFINE_FUNC_PTR(clGetProgramInfo);
204CL_DEFINE_FUNC_PTR(clFlush);
205CL_DEFINE_FUNC_PTR(clFinish);
206CL_DEFINE_FUNC_PTR(clReleaseProgram);
207CL_DEFINE_FUNC_PTR(clRetainContext);
208CL_DEFINE_FUNC_PTR(clGetContextInfo);
209CL_DEFINE_FUNC_PTR(clCreateProgramWithBinary);
210CL_DEFINE_FUNC_PTR(clCreateCommandQueue);
211CL_DEFINE_FUNC_PTR(clGetCommandQueueInfo);
212CL_DEFINE_FUNC_PTR(clReleaseCommandQueue);
213CL_DEFINE_FUNC_PTR(clEnqueueMapBuffer);
214CL_DEFINE_FUNC_PTR(clEnqueueMapImage);
215CL_DEFINE_FUNC_PTR(clEnqueueCopyImage);
216CL_DEFINE_FUNC_PTR(clRetainProgram);
217CL_DEFINE_FUNC_PTR(clGetProgramBuildInfo);
218CL_DEFINE_FUNC_PTR(clEnqueueReadBuffer);
219CL_DEFINE_FUNC_PTR(clEnqueueReadBufferRect);
220CL_DEFINE_FUNC_PTR(clEnqueueWriteBuffer);
221CL_DEFINE_FUNC_PTR(clEnqueueWriteImage);
222CL_DEFINE_FUNC_PTR(clEnqueueReadImage);
223CL_DEFINE_FUNC_PTR(clWaitForEvents);
224CL_DEFINE_FUNC_PTR(clReleaseEvent);
225CL_DEFINE_FUNC_PTR(clCreateContext);
226CL_DEFINE_FUNC_PTR(clCreateContextFromType);
227CL_DEFINE_FUNC_PTR(clReleaseContext);
228CL_DEFINE_FUNC_PTR(clRetainCommandQueue);
229CL_DEFINE_FUNC_PTR(clEnqueueUnmapMemObject);
230CL_DEFINE_FUNC_PTR(clRetainMemObject);
231CL_DEFINE_FUNC_PTR(clReleaseMemObject);
232CL_DEFINE_FUNC_PTR(clGetDeviceInfo);
233CL_DEFINE_FUNC_PTR(clGetDeviceIDs);
234CL_DEFINE_FUNC_PTR(clRetainEvent);
235CL_DEFINE_FUNC_PTR(clGetKernelWorkGroupInfo);
236CL_DEFINE_FUNC_PTR(clGetEventInfo);
237CL_DEFINE_FUNC_PTR(clGetEventProfilingInfo);
238CL_DEFINE_FUNC_PTR(clGetImageInfo);
239CL_DEFINE_FUNC_PTR(clEnqueueCopyBufferToImage);
240CL_DEFINE_FUNC_PTR(clEnqueueCopyImageToBuffer);
241#if defined(CL_TARGET_OPENCL_VERSION) && CL_TARGET_OPENCL_VERSION >= 120
242CL_DEFINE_FUNC_PTR(clRetainDevice);
243CL_DEFINE_FUNC_PTR(clReleaseDevice);
244CL_DEFINE_FUNC_PTR(clCreateImage);
245CL_DEFINE_FUNC_PTR(clEnqueueFillImage);
246#endif
247#if defined(CL_TARGET_OPENCL_VERSION) && CL_TARGET_OPENCL_VERSION >= 200
248CL_DEFINE_FUNC_PTR(clGetKernelSubGroupInfoKHR);
249CL_DEFINE_FUNC_PTR(clCreateCommandQueueWithProperties);
250CL_DEFINE_FUNC_PTR(clGetExtensionFunctionAddress);
251CL_DEFINE_FUNC_PTR(clCreateProgramWithIL);
252CL_DEFINE_FUNC_PTR(clSVMAlloc);
253CL_DEFINE_FUNC_PTR(clSVMFree);
254CL_DEFINE_FUNC_PTR(clEnqueueSVMMap);
255CL_DEFINE_FUNC_PTR(clEnqueueSVMUnmap);
256CL_DEFINE_FUNC_PTR(clSetKernelArgSVMPointer);
257#endif
258#undef LOAD_OPENCL_FUNCTION_PTR
259}  // namespace OHOS
260
261// clGetPlatformIDs wrapper, use OpenCLWrapper function. use OpenCLWrapper function.
262cl_int clGetPlatformIDs(cl_uint num_entries, cl_platform_id *platforms, cl_uint *num_platforms)
263{
264    OHOS::InitOpenCL();
265    auto func = OHOS::clGetPlatformIDs;
266    MS_ASSERT(func != nullptr);
267    return func(num_entries, platforms, num_platforms);
268}
269
270// clGetPlatformInfo wrapper, use OpenCLWrapper function. use OpenCLWrapper function.
271cl_int clGetPlatformInfo(cl_platform_id platform, cl_platform_info param_name, size_t param_value_size,
272                         void *param_value, size_t *param_value_size_ret)
273{
274    OHOS::InitOpenCL();
275    auto func = OHOS::clGetPlatformInfo;
276    MS_ASSERT(func != nullptr);
277    return func(platform, param_name, param_value_size, param_value, param_value_size_ret);
278}
279
280// clGetDeviceIDs wrapper, use OpenCLWrapper function.
281cl_int clGetDeviceIDs(cl_platform_id platform, cl_device_type device_type, cl_uint num_entries, cl_device_id *devices,
282                      cl_uint *num_devices)
283{
284    OHOS::InitOpenCL();
285    auto func = OHOS::clGetDeviceIDs;
286    MS_ASSERT(func != nullptr);
287    return func(platform, device_type, num_entries, devices, num_devices);
288}
289
290// clGetDeviceInfo wrapper, use OpenCLWrapper function.
291cl_int clGetDeviceInfo(cl_device_id device, cl_device_info param_name, size_t param_value_size, void *param_value,
292                       size_t *param_value_size_ret)
293{
294    OHOS::InitOpenCL();
295    auto func = OHOS::clGetDeviceInfo;
296    MS_ASSERT(func != nullptr);
297    return func(device, param_name, param_value_size, param_value, param_value_size_ret);
298}
299
300// clCreateContext wrapper, use OpenCLWrapper function.
301cl_context clCreateContext(const cl_context_properties *properties, cl_uint num_devices, const cl_device_id *devices,
302                           void(CL_CALLBACK *pfn_notify)(const char *, const void *, size_t, void *), void *user_data,
303                           cl_int *errcode_ret)
304{
305    OHOS::InitOpenCL();
306    auto func = OHOS::clCreateContext;
307    MS_ASSERT(func != nullptr);
308    return func(properties, num_devices, devices, pfn_notify, user_data, errcode_ret);
309}
310
311// clCreateContextFromType wrapper, use OpenCLWrapper function.
312cl_context clCreateContextFromType(const cl_context_properties *properties, cl_device_type device_type,
313                                   void(CL_CALLBACK *pfn_notify)(const char *, const void *, size_t, void *),
314                                   void *user_data, cl_int *errcode_ret)
315{
316    OHOS::InitOpenCL();
317    auto func = OHOS::clCreateContextFromType;
318    MS_ASSERT(func != nullptr);
319    return func(properties, device_type, pfn_notify, user_data, errcode_ret);
320}
321
322// clRetainContext wrapper, use OpenCLWrapper function.
323cl_int clRetainContext(cl_context context)
324{
325    OHOS::InitOpenCL();
326    auto func = OHOS::clRetainContext;
327    MS_ASSERT(func != nullptr);
328    return func(context);
329}
330
331// clReleaseContext wrapper, use OpenCLWrapper function.
332cl_int clReleaseContext(cl_context context)
333{
334    OHOS::InitOpenCL();
335    auto func = OHOS::clReleaseContext;
336    MS_ASSERT(func != nullptr);
337    return func(context);
338}
339
340// clGetContextInfo wrapper, use OpenCLWrapper function.
341cl_int clGetContextInfo(cl_context context, cl_context_info param_name, size_t param_value_size, void *param_value,
342                        size_t *param_value_size_ret)
343{
344    OHOS::InitOpenCL();
345    auto func = OHOS::clGetContextInfo;
346    MS_ASSERT(func != nullptr);
347    return func(context, param_name, param_value_size, param_value, param_value_size_ret);
348}
349
350// clCreateProgramWithSource wrapper, use OpenCLWrapper function.
351cl_program clCreateProgramWithSource(cl_context context, cl_uint count, const char **strings, const size_t *lengths,
352                                     cl_int *errcode_ret)
353{
354    OHOS::InitOpenCL();
355    auto func = OHOS::clCreateProgramWithSource;
356    MS_ASSERT(func != nullptr);
357    return func(context, count, strings, lengths, errcode_ret);
358}
359
360// clCreateProgramWithBinary wrapper, use OpenCLWrapper function.
361cl_program clCreateProgramWithBinary(cl_context context, cl_uint num_devices, const cl_device_id *devices_list,
362                                     const size_t *lengths, const unsigned char **binaries, cl_int *binary_status,
363                                     cl_int *errcode_ret)
364{
365    OHOS::InitOpenCL();
366    auto func = OHOS::clCreateProgramWithBinary;
367    MS_ASSERT(func != nullptr);
368    return func(context, num_devices, devices_list, lengths, binaries, binary_status, errcode_ret);
369}
370
371// clGetProgramInfo wrapper, use OpenCLWrapper function.
372cl_int clGetProgramInfo(cl_program program, cl_program_info param_name, size_t param_value_size, void *param_value,
373                        size_t *param_value_size_ret)
374{
375    OHOS::InitOpenCL();
376    auto func = OHOS::clGetProgramInfo;
377    MS_ASSERT(func != nullptr);
378    return func(program, param_name, param_value_size, param_value, param_value_size_ret);
379}
380
381// clGetProgramBuildInfo wrapper, use OpenCLWrapper function.
382cl_int clGetProgramBuildInfo(cl_program program, cl_device_id device, cl_program_build_info param_name,
383                             size_t param_value_size, void *param_value, size_t *param_value_size_ret)
384{
385    OHOS::InitOpenCL();
386    auto func = OHOS::clGetProgramBuildInfo;
387    MS_ASSERT(func != nullptr);
388    return func(program, device, param_name, param_value_size, param_value, param_value_size_ret);
389}
390
391// clRetainProgram wrapper, use OpenCLWrapper function.
392cl_int clRetainProgram(cl_program program)
393{
394    OHOS::InitOpenCL();
395    auto func = OHOS::clRetainProgram;
396    MS_ASSERT(func != nullptr);
397    return func(program);
398}
399
400// clReleaseProgram wrapper, use OpenCLWrapper function.
401cl_int clReleaseProgram(cl_program program)
402{
403    OHOS::InitOpenCL();
404    auto func = OHOS::clReleaseProgram;
405    MS_ASSERT(func != nullptr);
406    return func(program);
407}
408
409// clBuildProgram wrapper, use OpenCLWrapper function.
410cl_int clBuildProgram(cl_program program, cl_uint num_devices, const cl_device_id *device_list, const char *options,
411                      void(CL_CALLBACK *pfn_notify)(cl_program program, void *user_data), void *user_data)
412{
413    OHOS::InitOpenCL();
414    auto func = OHOS::clBuildProgram;
415    MS_ASSERT(func != nullptr);
416    return func(program, num_devices, device_list, options, pfn_notify, user_data);
417}
418
419// clCreateKernel wrapper, use OpenCLWrapper function.
420cl_kernel clCreateKernel(cl_program program, const char *kernelName, cl_int *errcode_ret)
421{
422    OHOS::InitOpenCL();
423    auto func = OHOS::clCreateKernel;
424    MS_ASSERT(func != nullptr);
425    return func(program, kernelName, errcode_ret);
426}
427
428// clRetainKernel wrapper, use OpenCLWrapper function.
429cl_int clRetainKernel(cl_kernel kernel)
430{
431    OHOS::InitOpenCL();
432    auto func = OHOS::clRetainKernel;
433    MS_ASSERT(func != nullptr);
434    return func(kernel);
435}
436
437// clReleaseKernel wrapper, use OpenCLWrapper function.
438cl_int clReleaseKernel(cl_kernel kernel)
439{
440    OHOS::InitOpenCL();
441    auto func = OHOS::clReleaseKernel;
442    MS_ASSERT(func != nullptr);
443    return func(kernel);
444}
445
446// clSetKernelArg wrapper, use OpenCLWrapper function.
447cl_int clSetKernelArg(cl_kernel kernel, cl_uint arg_index, size_t arg_size, const void *arg_value)
448{
449    OHOS::InitOpenCL();
450    auto func = OHOS::clSetKernelArg;
451    MS_ASSERT(func != nullptr);
452    return func(kernel, arg_index, arg_size, arg_value);
453}
454
455// clCreateBuffer wrapper, use OpenCLWrapper function.
456cl_mem clCreateBuffer(cl_context context, cl_mem_flags flags, size_t size, void *host_ptr, cl_int *errcode_ret)
457{
458    OHOS::InitOpenCL();
459    auto func = OHOS::clCreateBuffer;
460    MS_ASSERT(func != nullptr);
461    return func(context, flags, size, host_ptr, errcode_ret);
462}
463
464// clRetainMemObject wrapper, use OpenCLWrapper function.
465cl_int clRetainMemObject(cl_mem memobj)
466{
467    OHOS::InitOpenCL();
468    auto func = OHOS::clRetainMemObject;
469    MS_ASSERT(func != nullptr);
470    return func(memobj);
471}
472
473// clReleaseMemObject wrapper, use OpenCLWrapper function.
474cl_int clReleaseMemObject(cl_mem memobj)
475{
476    OHOS::InitOpenCL();
477    auto func = OHOS::clReleaseMemObject;
478    MS_ASSERT(func != nullptr);
479    return func(memobj);
480}
481
482// clGetImageInfo wrapper, use OpenCLWrapper function.
483cl_int clGetImageInfo(cl_mem image, cl_image_info param_name, size_t param_value_size, void *param_value,
484                      size_t *param_value_size_ret)
485{
486    OHOS::InitOpenCL();
487    auto func = OHOS::clGetImageInfo;
488    MS_ASSERT(func != nullptr);
489    return func(image, param_name, param_value_size, param_value, param_value_size_ret);
490}
491
492// clRetainCommandQueue wrapper, use OpenCLWrapper function.
493cl_int clRetainCommandQueue(cl_command_queue command_queue)
494{
495    OHOS::InitOpenCL();
496    auto func = OHOS::clRetainCommandQueue;
497    MS_ASSERT(func != nullptr);
498    return func(command_queue);
499}
500
501// clReleaseCommandQueue wrapper, use OpenCLWrapper function.
502cl_int clReleaseCommandQueue(cl_command_queue command_queue)
503{
504    OHOS::InitOpenCL();
505    auto func = OHOS::clReleaseCommandQueue;
506    MS_ASSERT(func != nullptr);
507    return func(command_queue);
508}
509
510// clEnqueueReadBuffer wrapper, use OpenCLWrapper function.
511cl_int clEnqueueReadBuffer(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, size_t offset,
512                           size_t size, void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list,
513                           cl_event *event)
514{
515    OHOS::InitOpenCL();
516    auto func = OHOS::clEnqueueReadBuffer;
517    MS_ASSERT(func != nullptr);
518    return func(command_queue, buffer, blocking_read, offset, size, ptr, num_events_in_wait_list,
519                event_wait_list, event);
520}
521
522// clEnqueueReadBufferRect wrapper, use OpenCLWrapper function.
523cl_int clEnqueueReadBufferRect(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read,
524                               const size_t *buffer_origin, const size_t *host_origin, const size_t *region,
525                               size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch,
526                               size_t host_slice_pitch, void *ptr, cl_uint num_events_in_wait_list,
527                               const cl_event *event_wait_list, cl_event *event)
528{
529    OHOS::InitOpenCL();
530    auto func = OHOS::clEnqueueReadBufferRect;
531    MS_ASSERT(func != nullptr);
532    return func(command_queue, buffer, blocking_read, buffer_origin, host_origin, region, buffer_row_pitch,
533                buffer_slice_pitch, host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list,
534                event_wait_list, event);
535}
536
537// clEnqueueWriteBuffer wrapper, use OpenCLWrapper function.
538cl_int clEnqueueWriteBuffer(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, size_t offset,
539                            size_t size, const void *ptr, cl_uint num_events_in_wait_list,
540                            const cl_event *event_wait_list, cl_event *event)
541{
542    OHOS::InitOpenCL();
543    auto func = OHOS::clEnqueueWriteBuffer;
544    MS_ASSERT(func != nullptr);
545    return func(command_queue, buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list,
546                event);
547}
548
549// clEnqueueWriteImage wrapper, use OpenCLWrapper function.
550cl_int clEnqueueWriteImage(cl_command_queue command_queue, cl_mem image, cl_bool blocking_write, const size_t *origin,
551                           const size_t *region, size_t input_row_pitch, size_t input_slice_pitch, const void *ptr,
552                           cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
553{
554    OHOS::InitOpenCL();
555    auto func = OHOS::clEnqueueWriteImage;
556    MS_ASSERT(func != nullptr);
557    return func(command_queue, image, blocking_write, origin, region, input_row_pitch, input_slice_pitch, ptr,
558                num_events_in_wait_list, event_wait_list, event);
559}
560
561// clEnqueueReadImage wrapper, use OpenCLWrapper function.
562cl_int clEnqueueReadImage(cl_command_queue command_queue, cl_mem image, cl_bool blocking_read, const size_t *origin,
563                          const size_t *region, size_t row_pitch, size_t slice_pitch, void *ptr,
564                          cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
565{
566    OHOS::InitOpenCL();
567    auto func = OHOS::clEnqueueReadImage;
568    MS_ASSERT(func != nullptr);
569    return func(command_queue, image, blocking_read, origin, region, row_pitch, slice_pitch, ptr,
570                num_events_in_wait_list, event_wait_list, event);
571}
572
573// clEnqueueMapBuffer wrapper, use OpenCLWrapper function.
574void *clEnqueueMapBuffer(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_map, cl_map_flags map_flags,
575                         size_t offset, size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list,
576                         cl_event *event, cl_int *errcode_ret)
577{
578    OHOS::InitOpenCL();
579    auto func = OHOS::clEnqueueMapBuffer;
580    MS_ASSERT(func != nullptr);
581    return func(command_queue, buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list,
582                event, errcode_ret);
583}
584
585// clEnqueueMapImage wrapper, use OpenCLWrapper function.
586void *clEnqueueMapImage(cl_command_queue command_queue, cl_mem image, cl_bool blocking_map, cl_map_flags map_flags,
587                        const size_t *origin, const size_t *region, size_t *image_row_pitch, size_t *image_slice_pitch,
588                        cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event,
589                        cl_int *errcode_ret)
590{
591    OHOS::InitOpenCL();
592    auto func = OHOS::clEnqueueMapImage;
593    MS_ASSERT(func != nullptr);
594    return func(command_queue, image, blocking_map, map_flags, origin, region, image_row_pitch, image_slice_pitch,
595                num_events_in_wait_list, event_wait_list, event, errcode_ret);
596}
597
598// clEnqueueUnmapMemObject wrapper, use OpenCLWrapper function.
599cl_int clEnqueueUnmapMemObject(cl_command_queue command_queue, cl_mem memobj, void *mapped_ptr,
600                               cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
601{
602    OHOS::InitOpenCL();
603    auto func = OHOS::clEnqueueUnmapMemObject;
604    MS_ASSERT(func != nullptr);
605    return func(command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event);
606}
607
608// clGetKernelWorkGroupInfo wrapper, use OpenCLWrapper function.
609cl_int clGetKernelWorkGroupInfo(cl_kernel kernel, cl_device_id device, cl_kernel_work_group_info param_name,
610                                size_t param_value_size, void *param_value, size_t *param_value_size_ret)
611{
612    OHOS::InitOpenCL();
613    auto func = OHOS::clGetKernelWorkGroupInfo;
614    MS_ASSERT(func != nullptr);
615    return func(kernel, device, param_name, param_value_size, param_value, param_value_size_ret);
616}
617
618// clGetEventProfilingInfo wrapper, use OpenCLWrapper function.
619cl_int clGetEventProfilingInfo(cl_event event, cl_profiling_info param_name, size_t param_value_size, void *param_value,
620                               size_t *param_value_size_ret)
621{
622    OHOS::InitOpenCL();
623    auto func = OHOS::clGetEventProfilingInfo;
624    MS_ASSERT(func != nullptr);
625    return func(event, param_name, param_value_size, param_value, param_value_size_ret);
626}
627
628// clEnqueueNDRangeKernel wrapper, use OpenCLWrapper function.
629cl_int clEnqueueNDRangeKernel(cl_command_queue command_queue, cl_kernel kernel, cl_uint work_dim,
630                              const size_t *global_work_offset, const size_t *global_work_size,
631                              const size_t *local_work_size, cl_uint num_events_in_wait_list,
632                              const cl_event *event_wait_list, cl_event *event)
633{
634    OHOS::InitOpenCL();
635    auto func = OHOS::clEnqueueNDRangeKernel;
636    MS_ASSERT(func != nullptr);
637    return func(command_queue, kernel, work_dim, global_work_offset, global_work_size, local_work_size,
638                num_events_in_wait_list, event_wait_list, event);
639}
640
641// clWaitForEvents wrapper, use OpenCLWrapper function.
642cl_int clWaitForEvents(cl_uint num_events, const cl_event *event_list)
643{
644    OHOS::InitOpenCL();
645    auto func = OHOS::clWaitForEvents;
646    MS_ASSERT(func != nullptr);
647    return func(num_events, event_list);
648}
649
650// clRetainEvent wrapper, use OpenCLWrapper function.
651cl_int clRetainEvent(cl_event event)
652{
653    OHOS::InitOpenCL();
654    auto func = OHOS::clRetainEvent;
655    MS_ASSERT(func != nullptr);
656    return func(event);
657}
658
659// clReleaseEvent wrapper, use OpenCLWrapper function.
660cl_int clReleaseEvent(cl_event event)
661{
662    OHOS::InitOpenCL();
663    auto func = OHOS::clReleaseEvent;
664    MS_ASSERT(func != nullptr);
665    return func(event);
666}
667
668// clGetEventInfo wrapper, use OpenCLWrapper function.
669cl_int clGetEventInfo(cl_event event, cl_event_info param_name, size_t param_value_size, void *param_value,
670                      size_t *param_value_size_ret)
671{
672    OHOS::InitOpenCL();
673    auto func = OHOS::clGetEventInfo;
674    MS_ASSERT(func != nullptr);
675    return func(event, param_name, param_value_size, param_value, param_value_size_ret);
676}
677
678// clFlush wrapper, use OpenCLWrapper function.
679cl_int clFlush(cl_command_queue command_queue)
680{
681    OHOS::InitOpenCL();
682    auto func = OHOS::clFlush;
683    MS_ASSERT(func != nullptr);
684    return func(command_queue);
685}
686
687// clFinish wrapper, use OpenCLWrapper function.
688cl_int clFinish(cl_command_queue command_queue)
689{
690    OHOS::InitOpenCL();
691    auto func = OHOS::clFinish;
692    MS_ASSERT(func != nullptr);
693    return func(command_queue);
694}
695
696// clCreateImage2D wrapper, use OpenCLWrapper function.
697cl_mem clCreateImage2D(cl_context context, cl_mem_flags flags, const cl_image_format *image_format, size_t imageWidth,
698                       size_t imageHeight, size_t image_row_pitch, void *host_ptr, cl_int *errcode_ret)
699{
700    OHOS::InitOpenCL();
701    auto func = OHOS::clCreateImage2D;
702    MS_ASSERT(func != nullptr);
703    return func(context, flags, image_format, imageWidth, imageHeight, image_row_pitch, host_ptr, errcode_ret);
704}
705
706// clCreateImage3D wrapper, use OpenCLWrapper function.
707cl_mem clCreateImage3D(cl_context context, cl_mem_flags flags, const cl_image_format *image_format, size_t imageWidth,
708                       size_t imageHeight, size_t imageDepth, size_t image_row_pitch, size_t image_slice_pitch,
709                       void *host_ptr, cl_int *errcode_ret)
710{
711    OHOS::InitOpenCL();
712    auto func = OHOS::clCreateImage3D;
713    MS_ASSERT(func != nullptr);
714    return func(context, flags, image_format, imageWidth, imageHeight, imageDepth, image_row_pitch, image_slice_pitch,
715                host_ptr, errcode_ret);
716}
717
718// clCreateCommandQueue wrapper, use OpenCLWrapper function.
719cl_command_queue clCreateCommandQueue(cl_context context, cl_device_id device, cl_command_queue_properties properties,
720                                      cl_int *errcode_ret)
721{
722    OHOS::InitOpenCL();
723    auto func = OHOS::clCreateCommandQueue;
724    MS_ASSERT(func != nullptr);
725    return func(context, device, properties, errcode_ret);
726}
727
728// clGetCommandQueueInfo wrapper, use OpenCLWrapper function.
729cl_int clGetCommandQueueInfo(cl_command_queue command_queue, cl_command_queue_info param_name, size_t param_value_size,
730                             void *param_value, size_t *param_value_size_ret)
731{
732    OHOS::InitOpenCL();
733    auto func = OHOS::clGetCommandQueueInfo;
734    MS_ASSERT(func != nullptr);
735    return func(command_queue, param_name, param_value_size, param_value, param_value_size_ret);
736}
737
738// clEnqueueCopyImage wrapper, use OpenCLWrapper function.
739cl_int clEnqueueCopyImage(cl_command_queue queue, cl_mem src_image, cl_mem dst_image, const size_t *src_origin,
740                          const size_t *dst_origin, const size_t *region, cl_uint num_events_in_wait_list,
741                          const cl_event *event_wait_list, cl_event *event)
742{
743    OHOS::InitOpenCL();
744    auto func = OHOS::clEnqueueCopyImage;
745    MS_ASSERT(func != nullptr);
746    return func(queue, src_image, dst_image, src_origin, dst_origin, region, num_events_in_wait_list, event_wait_list,
747                event);
748}
749
750// clEnqueueCopyBufferToImage wrapper, use OpenCLWrapper function.
751cl_int clEnqueueCopyBufferToImage(cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_image,
752                                  size_t src_offset, const size_t *dst_origin, const size_t *region,
753                                  cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
754{
755    OHOS::InitOpenCL();
756    auto func = OHOS::clEnqueueCopyBufferToImage;
757    MS_ASSERT(func != nullptr);
758    return func(command_queue, src_buffer, dst_image, src_offset, dst_origin, region, num_events_in_wait_list,
759                event_wait_list, event);
760}
761
762// clEnqueueCopyImageToBuffer wrapper, use OpenCLWrapper function.
763cl_int clEnqueueCopyImageToBuffer(cl_command_queue command_queue, cl_mem src_image, cl_mem dst_buffer,
764                                  const size_t *src_origin, const size_t *region, size_t dst_offset,
765                                  cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
766{
767    OHOS::InitOpenCL();
768    auto func = OHOS::clEnqueueCopyImageToBuffer;
769    MS_ASSERT(func != nullptr);
770    return func(command_queue, src_image, dst_buffer, src_origin, region, dst_offset, num_events_in_wait_list,
771                event_wait_list, event);
772}
773
774#if defined(CL_TARGET_OPENCL_VERSION) && CL_TARGET_OPENCL_VERSION >= 120
775
776// clRetainDevice wrapper, use OpenCLWrapper function.
777cl_int clRetainDevice(cl_device_id device)
778{
779    OHOS::InitOpenCL();
780    auto func = OHOS::clRetainDevice;
781    MS_ASSERT(func != nullptr);
782    return func(device);
783}
784
785// clReleaseDevice wrapper, use OpenCLWrapper function.
786cl_int clReleaseDevice(cl_device_id device)
787{
788    OHOS::InitOpenCL();
789    auto func = OHOS::clReleaseDevice;
790    MS_ASSERT(func != nullptr);
791    return func(device);
792}
793
794// clCreateImage wrapper, use OpenCLWrapper function.
795cl_mem clCreateImage(cl_context context, cl_mem_flags flags, const cl_image_format *image_format,
796                     const cl_image_desc *image_desc, void *host_ptr, cl_int *errcode_ret)
797{
798    OHOS::InitOpenCL();
799    auto func = OHOS::clCreateImage;
800    MS_ASSERT(func != nullptr);
801    return func(context, flags, image_format, image_desc, host_ptr, errcode_ret);
802}
803
804cl_int clEnqueueFillImage(cl_command_queue command_queue, cl_mem image, const void *fill_color, const size_t *origin,
805                          const size_t *region, cl_uint num_events_in_wait_list, const cl_event *event_wait_list,
806                          cl_event *event)
807{
808    OHOS::InitOpenCL();
809    auto func = OHOS::clEnqueueFillImage;
810    MS_ASSERT(func != nullptr);
811    return func(command_queue, image, fill_color, origin, region, num_events_in_wait_list, event_wait_list, event);
812}
813
814#endif
815
816#if defined(CL_TARGET_OPENCL_VERSION) && CL_TARGET_OPENCL_VERSION >= 200
817
818// clCreateCommandQueueWithProperties wrapper, use OpenCLWrapper function.
819cl_command_queue clCreateCommandQueueWithProperties(cl_context context, cl_device_id device,
820                                                    const cl_queue_properties *properties, cl_int *errcode_ret)
821{
822    OHOS::InitOpenCL();
823    auto func = OHOS::clCreateCommandQueueWithProperties;
824    MS_ASSERT(func != nullptr);
825    return func(context, device, properties, errcode_ret);
826}
827
828// clGetExtensionFunctionAddress wrapper, use OpenCLWrapper function.
829void *clGetExtensionFunctionAddress(const char *func_name)
830{
831    OHOS::InitOpenCL();
832    auto func = OHOS::clGetExtensionFunctionAddress;
833    MS_ASSERT(func != nullptr);
834    return func(func_name);
835}
836// clCreateProgramWithIL wrapper, use OpenCLWrapper function.
837cl_program clCreateProgramWithIL(cl_context context, const void *il, size_t length, cl_int *ret)
838{
839    OHOS::InitOpenCL();
840    auto func = OHOS::clCreateProgramWithIL;
841    MS_ASSERT(func != nullptr);
842    return func(context, il, length, ret);
843}
844
845// clSVMAlloc wrapper, use OpenCLWrapper function.
846void *clSVMAlloc(cl_context context, cl_mem_flags flags, size_t size, cl_uint align)
847{
848    OHOS::InitOpenCL();
849    auto func = OHOS::clSVMAlloc;
850    MS_ASSERT(func != nullptr);
851    return func(context, flags, size, align);
852}
853
854// clSVMFree wrapper, use OpenCLWrapper function.
855void clSVMFree(cl_context context, void *buffer)
856{
857    OHOS::InitOpenCL();
858    auto func = OHOS::clSVMFree;
859    MS_ASSERT(func != nullptr);
860    func(context, buffer);
861}
862
863// clEnqueueSVMMap wrapper, use OpenCLWrapper function.
864cl_int clEnqueueSVMMap(cl_command_queue command_queue, cl_bool blocking, cl_map_flags flags, void *host_ptr,
865                       size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event)
866{
867    OHOS::InitOpenCL();
868    auto func = OHOS::clEnqueueSVMMap;
869    MS_ASSERT(func != nullptr);
870    return func(command_queue, blocking, flags, host_ptr, size, num_events_in_wait_list, event_wait_list, event);
871}
872
873// clEnqueueSVMUnmap wrapper, use OpenCLWrapper function.
874cl_int clEnqueueSVMUnmap(cl_command_queue command_queue, void *host_ptr, cl_uint num_events_in_wait_list,
875                         const cl_event *event_wait_list, cl_event *event)
876{
877    OHOS::InitOpenCL();
878    auto func = OHOS::clEnqueueSVMUnmap;
879    MS_ASSERT(func != nullptr);
880    return func(command_queue, host_ptr, num_events_in_wait_list, event_wait_list, event);
881}
882
883// clSetKernelArgSVMPointer wrapper, use OpenCLWrapper function.
884cl_int clSetKernelArgSVMPointer(cl_kernel kernel, cl_uint index, const void *host_ptr)
885{
886    OHOS::InitOpenCL();
887    auto func = OHOS::clSetKernelArgSVMPointer;
888    MS_ASSERT(func != nullptr);
889    return func(kernel, index, host_ptr);
890}
891#endif
892
893#endif  // USE_OPENCL_WRAPPER
894