• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2 
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 
16 #include "tensorflow/lite/delegates/gpu/cl/opencl_wrapper.h"
17 
18 #if defined(_WIN32)
19 #define __WINDOWS__
20 #endif
21 
22 #ifdef __WINDOWS__
23 #include <windows.h>
24 #else
25 #include <dlfcn.h>
26 #endif
27 
28 #include <string>
29 
30 #include "absl/strings/str_cat.h"
31 #include "tensorflow/lite/delegates/gpu/common/status.h"
32 
33 namespace tflite {
34 namespace gpu {
35 namespace cl {
36 
37 #ifdef __ANDROID__
38 #define LoadFunction(function)                                                 \
39   if (use_wrapper) {                                                           \
40     function = reinterpret_cast<PFN_##function>(loadOpenCLPointer(#function)); \
41   } else {                                                                     \
42     function = reinterpret_cast<PFN_##function>(dlsym(libopencl, #function));  \
43   }
44 #elif defined(__WINDOWS__)
45 #define LoadFunction(function) \
46   function =                   \
47       reinterpret_cast<PFN_##function>(GetProcAddress(libopencl, #function));
48 #else
49 #define LoadFunction(function) \
50   function = reinterpret_cast<PFN_##function>(dlsym(libopencl, #function));
51 #endif
52 
53 #ifdef __WINDOWS__
54 void LoadOpenCLFunctions(HMODULE libopencl);
55 #else
56 void LoadOpenCLFunctions(void* libopencl, bool use_wrapper);
57 #endif
58 
LoadOpenCL()59 absl::Status LoadOpenCL() {
60 #ifdef __WINDOWS__
61   HMODULE libopencl = LoadLibraryA("OpenCL.dll");
62   if (libopencl) {
63     LoadOpenCLFunctions(libopencl);
64     return absl::OkStatus();
65   } else {
66     DWORD error_code = GetLastError();
67     return absl::UnknownError(absl::StrCat(
68         "Can not open OpenCL library on this device, error code - ",
69         error_code));
70   }
71 #else
72   void* libopencl = nullptr;
73 #ifdef __ANDROID__
74   // Pixel phone or auto?
75   libopencl = dlopen("libOpenCL-pixel.so", RTLD_NOW | RTLD_LOCAL);
76   if (!libopencl) {
77     libopencl = dlopen("libOpenCL-car.so", RTLD_NOW | RTLD_LOCAL);
78   }
79   if (libopencl) {
80     typedef void (*enableOpenCL_t)();
81     enableOpenCL_t enableOpenCL =
82         reinterpret_cast<enableOpenCL_t>(dlsym(libopencl, "enableOpenCL"));
83     enableOpenCL();
84     LoadOpenCLFunctions(libopencl, true);
85     return absl::OkStatus();
86   }
87 #endif
88 #ifdef __APPLE__
89   static const char* kClLibName =
90       "/System/Library/Frameworks/OpenCL.framework/OpenCL";
91 #else
92   static const char* kClLibName = "libOpenCL.so";
93 #endif
94   libopencl = dlopen(kClLibName, RTLD_NOW | RTLD_LOCAL);
95   if (libopencl) {
96     LoadOpenCLFunctions(libopencl, false);
97     return absl::OkStatus();
98   }
99   // record error
100   std::string error(dlerror());
101   return absl::UnknownError(
102       absl::StrCat("Can not open OpenCL library on this device - ", error));
103 #endif
104 }
105 
106 #ifdef __WINDOWS__
LoadOpenCLFunctions(HMODULE libopencl)107 void LoadOpenCLFunctions(HMODULE libopencl) {
108 #else
109 void LoadOpenCLFunctions(void* libopencl, bool use_wrapper) {
110 #ifdef __ANDROID__
111   typedef void* (*loadOpenCLPointer_t)(const char* name);
112   loadOpenCLPointer_t loadOpenCLPointer;
113   if (use_wrapper) {
114     loadOpenCLPointer = reinterpret_cast<loadOpenCLPointer_t>(
115         dlsym(libopencl, "loadOpenCLPointer"));
116   }
117 #endif
118 #endif
119 
120   LoadFunction(clGetPlatformIDs);
121   LoadFunction(clGetPlatformInfo);
122   LoadFunction(clGetDeviceIDs);
123   LoadFunction(clGetDeviceInfo);
124   LoadFunction(clCreateSubDevices);
125   LoadFunction(clRetainDevice);
126   LoadFunction(clReleaseDevice);
127   LoadFunction(clCreateContext);
128   LoadFunction(clCreateContextFromType);
129   LoadFunction(clRetainContext);
130   LoadFunction(clReleaseContext);
131   LoadFunction(clGetContextInfo);
132   LoadFunction(clCreateCommandQueueWithProperties);
133   LoadFunction(clRetainCommandQueue);
134   LoadFunction(clReleaseCommandQueue);
135   LoadFunction(clGetCommandQueueInfo);
136   LoadFunction(clCreateBuffer);
137   LoadFunction(clCreateSubBuffer);
138   LoadFunction(clCreateImage);
139   LoadFunction(clCreatePipe);
140   LoadFunction(clRetainMemObject);
141   LoadFunction(clReleaseMemObject);
142   LoadFunction(clGetSupportedImageFormats);
143   LoadFunction(clGetMemObjectInfo);
144   LoadFunction(clGetImageInfo);
145   LoadFunction(clGetPipeInfo);
146   LoadFunction(clSetMemObjectDestructorCallback);
147   LoadFunction(clSVMAlloc);
148   LoadFunction(clSVMFree);
149   LoadFunction(clCreateSamplerWithProperties);
150   LoadFunction(clRetainSampler);
151   LoadFunction(clReleaseSampler);
152   LoadFunction(clGetSamplerInfo);
153   LoadFunction(clCreateProgramWithSource);
154   LoadFunction(clCreateProgramWithBinary);
155   LoadFunction(clCreateProgramWithBuiltInKernels);
156   LoadFunction(clRetainProgram);
157   LoadFunction(clReleaseProgram);
158   LoadFunction(clBuildProgram);
159   LoadFunction(clCompileProgram);
160   LoadFunction(clLinkProgram);
161   LoadFunction(clUnloadPlatformCompiler);
162   LoadFunction(clGetProgramInfo);
163   LoadFunction(clGetProgramBuildInfo);
164   LoadFunction(clCreateKernel);
165   LoadFunction(clCreateKernelsInProgram);
166   LoadFunction(clRetainKernel);
167   LoadFunction(clReleaseKernel);
168   LoadFunction(clSetKernelArg);
169   LoadFunction(clSetKernelArgSVMPointer);
170   LoadFunction(clSetKernelExecInfo);
171   LoadFunction(clGetKernelInfo);
172   LoadFunction(clGetKernelArgInfo);
173   LoadFunction(clGetKernelWorkGroupInfo);
174   LoadFunction(clWaitForEvents);
175   LoadFunction(clGetEventInfo);
176   LoadFunction(clCreateUserEvent);
177   LoadFunction(clRetainEvent);
178   LoadFunction(clReleaseEvent);
179   LoadFunction(clSetUserEventStatus);
180   LoadFunction(clSetEventCallback);
181   LoadFunction(clGetEventProfilingInfo);
182   LoadFunction(clFlush);
183   LoadFunction(clFinish);
184   LoadFunction(clEnqueueReadBuffer);
185   LoadFunction(clEnqueueReadBufferRect);
186   LoadFunction(clEnqueueWriteBuffer);
187   LoadFunction(clEnqueueWriteBufferRect);
188   LoadFunction(clEnqueueFillBuffer);
189   LoadFunction(clEnqueueCopyBuffer);
190   LoadFunction(clEnqueueCopyBufferRect);
191   LoadFunction(clEnqueueReadImage);
192   LoadFunction(clEnqueueWriteImage);
193   LoadFunction(clEnqueueFillImage);
194   LoadFunction(clEnqueueCopyImage);
195   LoadFunction(clEnqueueCopyImageToBuffer);
196   LoadFunction(clEnqueueCopyBufferToImage);
197   LoadFunction(clEnqueueMapBuffer);
198   LoadFunction(clEnqueueMapImage);
199   LoadFunction(clEnqueueUnmapMemObject);
200   LoadFunction(clEnqueueMigrateMemObjects);
201   LoadFunction(clEnqueueNDRangeKernel);
202   LoadFunction(clEnqueueNativeKernel);
203   LoadFunction(clEnqueueMarkerWithWaitList);
204   LoadFunction(clEnqueueBarrierWithWaitList);
205   LoadFunction(clEnqueueSVMFree);
206   LoadFunction(clEnqueueSVMMemcpy);
207   LoadFunction(clEnqueueSVMMemFill);
208   LoadFunction(clEnqueueSVMMap);
209   LoadFunction(clEnqueueSVMUnmap);
210   LoadFunction(clGetExtensionFunctionAddressForPlatform);
211   LoadFunction(clCreateImage2D);
212   LoadFunction(clCreateImage3D);
213   LoadFunction(clEnqueueMarker);
214   LoadFunction(clEnqueueWaitForEvents);
215   LoadFunction(clEnqueueBarrier);
216   LoadFunction(clUnloadCompiler);
217   LoadFunction(clGetExtensionFunctionAddress);
218   LoadFunction(clCreateCommandQueue);
219   LoadFunction(clCreateSampler);
220   LoadFunction(clEnqueueTask);
221 
222   // OpenGL sharing
223   LoadFunction(clCreateFromGLBuffer);
224   LoadFunction(clCreateFromGLTexture);
225   LoadFunction(clEnqueueAcquireGLObjects);
226   LoadFunction(clEnqueueReleaseGLObjects);
227 
228   // cl_khr_egl_event extension
229   LoadFunction(clCreateEventFromEGLSyncKHR);
230 
231   // EGL sharing
232   LoadFunction(clCreateFromEGLImageKHR);
233   LoadFunction(clEnqueueAcquireEGLObjectsKHR);
234   LoadFunction(clEnqueueReleaseEGLObjectsKHR);
235 
236   LoadQcomExtensionFunctions();
237 }
238 
239 // No OpenCL support, do not set function addresses
240 PFN_clGetPlatformIDs clGetPlatformIDs;
241 PFN_clGetPlatformInfo clGetPlatformInfo;
242 PFN_clGetDeviceIDs clGetDeviceIDs;
243 PFN_clGetDeviceInfo clGetDeviceInfo;
244 PFN_clCreateSubDevices clCreateSubDevices;
245 PFN_clRetainDevice clRetainDevice;
246 PFN_clReleaseDevice clReleaseDevice;
247 PFN_clCreateContext clCreateContext;
248 PFN_clCreateContextFromType clCreateContextFromType;
249 PFN_clRetainContext clRetainContext;
250 PFN_clReleaseContext clReleaseContext;
251 PFN_clGetContextInfo clGetContextInfo;
252 PFN_clCreateCommandQueueWithProperties clCreateCommandQueueWithProperties;
253 PFN_clRetainCommandQueue clRetainCommandQueue;
254 PFN_clReleaseCommandQueue clReleaseCommandQueue;
255 PFN_clGetCommandQueueInfo clGetCommandQueueInfo;
256 PFN_clCreateBuffer clCreateBuffer;
257 PFN_clCreateSubBuffer clCreateSubBuffer;
258 PFN_clCreateImage clCreateImage;
259 PFN_clCreatePipe clCreatePipe;
260 PFN_clRetainMemObject clRetainMemObject;
261 PFN_clReleaseMemObject clReleaseMemObject;
262 PFN_clGetSupportedImageFormats clGetSupportedImageFormats;
263 PFN_clGetMemObjectInfo clGetMemObjectInfo;
264 PFN_clGetImageInfo clGetImageInfo;
265 PFN_clGetPipeInfo clGetPipeInfo;
266 PFN_clSetMemObjectDestructorCallback clSetMemObjectDestructorCallback;
267 PFN_clSVMAlloc clSVMAlloc;
268 PFN_clSVMFree clSVMFree;
269 PFN_clCreateSamplerWithProperties clCreateSamplerWithProperties;
270 PFN_clRetainSampler clRetainSampler;
271 PFN_clReleaseSampler clReleaseSampler;
272 PFN_clGetSamplerInfo clGetSamplerInfo;
273 PFN_clCreateProgramWithSource clCreateProgramWithSource;
274 PFN_clCreateProgramWithBinary clCreateProgramWithBinary;
275 PFN_clCreateProgramWithBuiltInKernels clCreateProgramWithBuiltInKernels;
276 PFN_clRetainProgram clRetainProgram;
277 PFN_clReleaseProgram clReleaseProgram;
278 PFN_clBuildProgram clBuildProgram;
279 PFN_clCompileProgram clCompileProgram;
280 PFN_clLinkProgram clLinkProgram;
281 PFN_clUnloadPlatformCompiler clUnloadPlatformCompiler;
282 PFN_clGetProgramInfo clGetProgramInfo;
283 PFN_clGetProgramBuildInfo clGetProgramBuildInfo;
284 PFN_clCreateKernel clCreateKernel;
285 PFN_clCreateKernelsInProgram clCreateKernelsInProgram;
286 PFN_clRetainKernel clRetainKernel;
287 PFN_clReleaseKernel clReleaseKernel;
288 PFN_clSetKernelArg clSetKernelArg;
289 PFN_clSetKernelArgSVMPointer clSetKernelArgSVMPointer;
290 PFN_clSetKernelExecInfo clSetKernelExecInfo;
291 PFN_clGetKernelInfo clGetKernelInfo;
292 PFN_clGetKernelArgInfo clGetKernelArgInfo;
293 PFN_clGetKernelWorkGroupInfo clGetKernelWorkGroupInfo;
294 PFN_clWaitForEvents clWaitForEvents;
295 PFN_clGetEventInfo clGetEventInfo;
296 PFN_clCreateUserEvent clCreateUserEvent;
297 PFN_clRetainEvent clRetainEvent;
298 PFN_clReleaseEvent clReleaseEvent;
299 PFN_clSetUserEventStatus clSetUserEventStatus;
300 PFN_clSetEventCallback clSetEventCallback;
301 PFN_clGetEventProfilingInfo clGetEventProfilingInfo;
302 PFN_clFlush clFlush;
303 PFN_clFinish clFinish;
304 PFN_clEnqueueReadBuffer clEnqueueReadBuffer;
305 PFN_clEnqueueReadBufferRect clEnqueueReadBufferRect;
306 PFN_clEnqueueWriteBuffer clEnqueueWriteBuffer;
307 PFN_clEnqueueWriteBufferRect clEnqueueWriteBufferRect;
308 PFN_clEnqueueFillBuffer clEnqueueFillBuffer;
309 PFN_clEnqueueCopyBuffer clEnqueueCopyBuffer;
310 PFN_clEnqueueCopyBufferRect clEnqueueCopyBufferRect;
311 PFN_clEnqueueReadImage clEnqueueReadImage;
312 PFN_clEnqueueWriteImage clEnqueueWriteImage;
313 PFN_clEnqueueFillImage clEnqueueFillImage;
314 PFN_clEnqueueCopyImage clEnqueueCopyImage;
315 PFN_clEnqueueCopyImageToBuffer clEnqueueCopyImageToBuffer;
316 PFN_clEnqueueCopyBufferToImage clEnqueueCopyBufferToImage;
317 PFN_clEnqueueMapBuffer clEnqueueMapBuffer;
318 PFN_clEnqueueMapImage clEnqueueMapImage;
319 PFN_clEnqueueUnmapMemObject clEnqueueUnmapMemObject;
320 PFN_clEnqueueMigrateMemObjects clEnqueueMigrateMemObjects;
321 PFN_clEnqueueNDRangeKernel clEnqueueNDRangeKernel;
322 PFN_clEnqueueNativeKernel clEnqueueNativeKernel;
323 PFN_clEnqueueMarkerWithWaitList clEnqueueMarkerWithWaitList;
324 PFN_clEnqueueBarrierWithWaitList clEnqueueBarrierWithWaitList;
325 PFN_clEnqueueSVMFree clEnqueueSVMFree;
326 PFN_clEnqueueSVMMemcpy clEnqueueSVMMemcpy;
327 PFN_clEnqueueSVMMemFill clEnqueueSVMMemFill;
328 PFN_clEnqueueSVMMap clEnqueueSVMMap;
329 PFN_clEnqueueSVMUnmap clEnqueueSVMUnmap;
330 PFN_clGetExtensionFunctionAddressForPlatform
331     clGetExtensionFunctionAddressForPlatform;
332 PFN_clCreateImage2D clCreateImage2D;
333 PFN_clCreateImage3D clCreateImage3D;
334 PFN_clEnqueueMarker clEnqueueMarker;
335 PFN_clEnqueueWaitForEvents clEnqueueWaitForEvents;
336 PFN_clEnqueueBarrier clEnqueueBarrier;
337 PFN_clUnloadCompiler clUnloadCompiler;
338 PFN_clGetExtensionFunctionAddress clGetExtensionFunctionAddress;
339 PFN_clCreateCommandQueue clCreateCommandQueue;
340 PFN_clCreateSampler clCreateSampler;
341 PFN_clEnqueueTask clEnqueueTask;
342 
343 // OpenGL sharing
344 PFN_clCreateFromGLBuffer clCreateFromGLBuffer;
345 PFN_clCreateFromGLTexture clCreateFromGLTexture;
346 PFN_clEnqueueAcquireGLObjects clEnqueueAcquireGLObjects;
347 PFN_clEnqueueReleaseGLObjects clEnqueueReleaseGLObjects;
348 
349 // cl_khr_egl_event extension
350 PFN_clCreateEventFromEGLSyncKHR clCreateEventFromEGLSyncKHR;
351 
352 // EGL sharing
353 PFN_clCreateFromEGLImageKHR clCreateFromEGLImageKHR;
354 PFN_clEnqueueAcquireEGLObjectsKHR clEnqueueAcquireEGLObjectsKHR;
355 PFN_clEnqueueReleaseEGLObjectsKHR clEnqueueReleaseEGLObjectsKHR;
356 
357 DEFINE_QCOM_FUNCTION_PTRS
358 
359 cl_mem CreateImage2DLegacy(cl_context context, cl_mem_flags flags,
360                            const cl_image_format* image_format,
361                            const cl_image_desc* image_desc, void* host_ptr,
362                            cl_int* errcode_ret) {
363   if (clCreateImage) {  // clCreateImage available since OpenCL 1.2
364     return clCreateImage(context, flags, image_format, image_desc, host_ptr,
365                          errcode_ret);
366   } else {
367     return clCreateImage2D(context, flags, image_format,
368                            image_desc->image_width, image_desc->image_height,
369                            image_desc->image_row_pitch, host_ptr, errcode_ret);
370   }
371 }
372 
373 cl_mem CreateImage3DLegacy(cl_context context, cl_mem_flags flags,
374                            const cl_image_format* image_format,
375                            const cl_image_desc* image_desc, void* host_ptr,
376                            cl_int* errcode_ret) {
377   if (clCreateImage) {  // clCreateImage available since OpenCL 1.2
378     return clCreateImage(context, flags, image_format, image_desc, host_ptr,
379                          errcode_ret);
380   } else {
381     return clCreateImage3D(context, flags, image_format,
382                            image_desc->image_width, image_desc->image_height,
383                            image_desc->image_depth, image_desc->image_row_pitch,
384                            image_desc->image_slice_pitch, host_ptr,
385                            errcode_ret);
386   }
387 }
388 }  // namespace cl
389 }  // namespace gpu
390 }  // namespace tflite
391