MagickCore  6.9.13-18
Convert, Edit, Or Compose Bitmap Images
opencl-private.h
1 /*
2 Copyright 1999 ImageMagick Studio LLC, a non-profit organization
3 dedicated to making software imaging solutions freely available.
4 
5 You may not use this file except in compliance with the License. You may
6 obtain a copy of the License at
7 
8 https://imagemagick.org/script/license.php
9 
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 
16 MagickCore OpenCL private methods.
17 */
18 #ifndef MAGICKCORE_OPENCL_PRIVATE_H
19 #define MAGICKCORE_OPENCL_PRIVATE_H
20 
21 /*
22 Include declarations.
23 */
24 #include "magick/studio.h"
25 #include "magick/opencl.h"
26 
27 #if defined(MAGICKCORE_HAVE_CL_CL_H)
28 # include <CL/cl.h>
29 #endif
30 #if defined(MAGICKCORE_HAVE_OPENCL_CL_H)
31 # include <OpenCL/cl.h>
32 #endif
33 
34 #if defined(__cplusplus) || defined(c_plusplus)
35 extern "C" {
36 #endif
37 
38 #if !defined(MAGICKCORE_OPENCL_SUPPORT)
39  typedef void* cl_event;
40  typedef void* cl_mem;
41  typedef void* cl_uint;
42 #else
43 
44 #define MAX_COMMAND_QUEUES 16
45 
46 /*
47  *
48  * function pointer typedefs
49  *
50  */
51 
52 /* Platform APIs */
53 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clGetPlatformIDs)(
54  cl_uint num_entries,
55  cl_platform_id * platforms,
56  cl_uint * num_platforms) CL_API_SUFFIX__VERSION_1_0;
57 
58 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clGetPlatformInfo)(
59  cl_platform_id platform,
60  cl_platform_info param_name,
61  size_t param_value_size,
62  void * param_value,
63  size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0;
64 
65 /* Device APIs */
66 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clGetDeviceIDs)(
67  cl_platform_id platform,
68  cl_device_type device_type,
69  cl_uint num_entries,
70  cl_device_id * devices,
71  cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_0;
72 
73 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clGetDeviceInfo)(
74  cl_device_id device,
75  cl_device_info param_name,
76  size_t param_value_size,
77  void * param_value,
78  size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0;
79 
80 /* Context APIs */
81 typedef CL_API_ENTRY cl_context (CL_API_CALL *MAGICKpfn_clCreateContext)(
82  const cl_context_properties * properties,
83  cl_uint num_devices,
84  const cl_device_id * devices,
85  void (CL_CALLBACK *pfn_notify)(const char *, const void *, size_t, void *),
86  void * user_data,
87  cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
88 
89 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clReleaseContext)(
90  cl_context context) CL_API_SUFFIX__VERSION_1_0;
91 
92 /* Command Queue APIs */
93 typedef CL_API_ENTRY cl_command_queue (CL_API_CALL *MAGICKpfn_clCreateCommandQueue)(
94  cl_context context,
95  cl_device_id device,
96  cl_command_queue_properties properties,
97  cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
98 
99 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clReleaseCommandQueue)(
100  cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_0;
101 
102 /* Memory Object APIs */
103 typedef CL_API_ENTRY cl_mem (CL_API_CALL *MAGICKpfn_clCreateBuffer)(
104  cl_context context,
105  cl_mem_flags flags,
106  size_t size,
107  void * host_ptr,
108  cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
109 
110 typedef CL_API_ENTRY cl_int
111  (CL_API_CALL *MAGICKpfn_clRetainMemObject)(cl_mem memobj)
112  CL_API_SUFFIX__VERSION_1_0;
113 
114 typedef CL_API_ENTRY cl_int
115  (CL_API_CALL *MAGICKpfn_clReleaseMemObject)(cl_mem memobj)
116  CL_API_SUFFIX__VERSION_1_0;
117 
118 /* Program Object APIs */
119 typedef CL_API_ENTRY cl_program (CL_API_CALL *MAGICKpfn_clCreateProgramWithSource)(
120  cl_context context,
121  cl_uint count,
122  const char ** strings,
123  const size_t * lengths,
124  cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
125 
126 typedef CL_API_ENTRY cl_program (CL_API_CALL *MAGICKpfn_clCreateProgramWithBinary)(
127  cl_context context,
128  cl_uint num_devices,
129  const cl_device_id * device_list,
130  const size_t * lengths,
131  const unsigned char ** binaries,
132  cl_int * binary_status,
133  cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
134 
135 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clReleaseProgram)(cl_program program) CL_API_SUFFIX__VERSION_1_0;
136 
137 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clBuildProgram)(
138  cl_program program,
139  cl_uint num_devices,
140  const cl_device_id * device_list,
141  const char * options,
142  void (CL_CALLBACK *pfn_notify)(cl_program program, void * user_data),
143  void * user_data) CL_API_SUFFIX__VERSION_1_0;
144 
145 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clGetProgramInfo)(
146  cl_program program,
147  cl_program_info param_name,
148  size_t param_value_size,
149  void * param_value,
150  size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0;
151 
152 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clGetProgramBuildInfo)(
153  cl_program program,
154  cl_device_id device,
155  cl_program_build_info param_name,
156  size_t param_value_size,
157  void * param_value,
158  size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0;
159 
160 /* Kernel Object APIs */
161 typedef CL_API_ENTRY cl_kernel (CL_API_CALL *MAGICKpfn_clCreateKernel)(
162  cl_program program,
163  const char * kernel_name,
164  cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
165 
166 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clReleaseKernel)(cl_kernel kernel) CL_API_SUFFIX__VERSION_1_0;
167 
168 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clSetKernelArg)(
169  cl_kernel kernel,
170  cl_uint arg_index,
171  size_t arg_size,
172  const void * arg_value) CL_API_SUFFIX__VERSION_1_0;
173 
174 typedef CL_API_ENTRY cl_int
175  (CL_API_CALL *MAGICKpfn_clFlush)(cl_command_queue command_queue)
176  CL_API_SUFFIX__VERSION_1_0;
177 
178 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clFinish)(cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_0;
179 
180 /* Enqueued Commands APIs */
181 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clEnqueueReadBuffer)(
182  cl_command_queue command_queue,
183  cl_mem buffer,
184  cl_bool blocking_read,
185  size_t offset,
186  size_t cb,
187  void * ptr,
188  cl_uint num_events_in_wait_list,
189  const cl_event * event_wait_list,
190  cl_event * event) CL_API_SUFFIX__VERSION_1_0;
191 
192 typedef CL_API_ENTRY void * (CL_API_CALL *MAGICKpfn_clEnqueueMapBuffer)(
193  cl_command_queue command_queue,
194  cl_mem buffer,
195  cl_bool blocking_map,
196  cl_map_flags map_flags,
197  size_t offset,
198  size_t cb,
199  cl_uint num_events_in_wait_list,
200  const cl_event * event_wait_list,
201  cl_event * event,
202  cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
203 
204 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clEnqueueUnmapMemObject)(
205  cl_command_queue command_queue,
206  cl_mem memobj,
207  void * mapped_ptr,
208  cl_uint num_events_in_wait_list,
209  const cl_event * event_wait_list,
210  cl_event * event) CL_API_SUFFIX__VERSION_1_0;
211 
212 typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clEnqueueNDRangeKernel)(
213  cl_command_queue command_queue,
214  cl_kernel kernel,
215  cl_uint work_dim,
216  const size_t * global_work_offset,
217  const size_t * global_work_size,
218  const size_t * local_work_size,
219  cl_uint num_events_in_wait_list,
220  const cl_event * event_wait_list,
221  cl_event * event) CL_API_SUFFIX__VERSION_1_0;
222 
223 typedef CL_API_ENTRY cl_int(CL_API_CALL *MAGICKpfn_clGetEventProfilingInfo)(
224  cl_event event,
225  cl_profiling_info param_name,
226  size_t param_value_size,
227  void *param_value,
228  size_t *param_value_size_ret) CL_API_SUFFIX__VERSION_1_0;
229 
230 typedef CL_API_ENTRY cl_int
231  (CL_API_CALL *MAGICKpfn_clGetEventInfo)(cl_event event,
232  cl_profiling_info param_name,size_t param_value_size,void *param_value,
233  size_t *param_value_size_ret) CL_API_SUFFIX__VERSION_1_0;
234 
235 typedef CL_API_ENTRY cl_int(CL_API_CALL *MAGICKpfn_clWaitForEvents)(
236  cl_uint num_events,
237  const cl_event *event_list) CL_API_SUFFIX__VERSION_1_0;
238 
239 typedef CL_API_ENTRY cl_int(CL_API_CALL *MAGICKpfn_clReleaseEvent)(
240  cl_event event) CL_API_SUFFIX__VERSION_1_0;
241 
242 typedef CL_API_ENTRY cl_int(CL_API_CALL *MAGICKpfn_clRetainEvent)(
243  cl_event event) CL_API_SUFFIX__VERSION_1_0;
244 
245 typedef CL_API_ENTRY cl_int(CL_API_CALL *MAGICKpfn_clSetEventCallback)(
246  cl_event event,cl_int command_exec_callback_type,
247  void (CL_CALLBACK *MAGICKpfn_notify)(cl_event,cl_int,void *),
248  void *user_data) CL_API_SUFFIX__VERSION_1_1;
249 
250 /*
251  *
252  * vendor dispatch table structure
253  *
254  * note that the types in the structure KHRicdVendorDispatch mirror the function
255  * names listed in the string table khrIcdVendorDispatchFunctionNames
256  *
257  */
258 
259 typedef struct MagickLibraryRec MagickLibrary;
260 
261 struct MagickLibraryRec
262 {
263  void * base;
264 
265  MAGICKpfn_clGetPlatformIDs clGetPlatformIDs;
266  MAGICKpfn_clGetPlatformInfo clGetPlatformInfo;
267 
268  MAGICKpfn_clGetDeviceIDs clGetDeviceIDs;
269  MAGICKpfn_clGetDeviceInfo clGetDeviceInfo;
270 
271  MAGICKpfn_clCreateContext clCreateContext;
272  MAGICKpfn_clReleaseContext clReleaseContext;
273 
274  MAGICKpfn_clCreateCommandQueue clCreateCommandQueue;
275  MAGICKpfn_clReleaseCommandQueue clReleaseCommandQueue;
276  MAGICKpfn_clFlush clFlush;
277  MAGICKpfn_clFinish clFinish;
278 
279  MAGICKpfn_clCreateBuffer clCreateBuffer;
280  MAGICKpfn_clRetainMemObject clRetainMemObject;
281  MAGICKpfn_clReleaseMemObject clReleaseMemObject;
282  MAGICKpfn_clCreateProgramWithSource clCreateProgramWithSource;
283  MAGICKpfn_clCreateProgramWithBinary clCreateProgramWithBinary;
284  MAGICKpfn_clReleaseProgram clReleaseProgram;
285  MAGICKpfn_clBuildProgram clBuildProgram;
286  MAGICKpfn_clGetProgramInfo clGetProgramInfo;
287  MAGICKpfn_clGetProgramBuildInfo clGetProgramBuildInfo;
288 
289  MAGICKpfn_clCreateKernel clCreateKernel;
290  MAGICKpfn_clReleaseKernel clReleaseKernel;
291  MAGICKpfn_clSetKernelArg clSetKernelArg;
292 
293  MAGICKpfn_clEnqueueReadBuffer clEnqueueReadBuffer;
294  MAGICKpfn_clEnqueueMapBuffer clEnqueueMapBuffer;
295  MAGICKpfn_clEnqueueUnmapMemObject clEnqueueUnmapMemObject;
296  MAGICKpfn_clEnqueueNDRangeKernel clEnqueueNDRangeKernel;
297 
298  MAGICKpfn_clGetEventProfilingInfo clGetEventProfilingInfo;
299 
300  MAGICKpfn_clGetEventInfo clGetEventInfo;
301  MAGICKpfn_clWaitForEvents clWaitForEvents;
302  MAGICKpfn_clReleaseEvent clReleaseEvent;
303  MAGICKpfn_clRetainEvent clRetainEvent;
304  MAGICKpfn_clSetEventCallback clSetEventCallback;
305 };
306 
307 struct _MagickCLEnv {
308  MagickBooleanType OpenCLInitialized; /* whether OpenCL environment is initialized. */
309  MagickBooleanType OpenCLDisabled; /* whether if OpenCL has been explicitely disabled. */
310 
311  MagickLibrary * library;
312 
313  /*OpenCL objects */
314  cl_platform_id platform;
315  cl_device_type deviceType;
316  cl_device_id device;
317  cl_context context;
318 
319  MagickBooleanType disableProgramCache; /* disable the OpenCL program cache */
320  cl_program programs[MAGICK_OPENCL_NUM_PROGRAMS]; /* one program object maps one kernel source file */
321 
322  MagickBooleanType regenerateProfile; /* re-run the microbenchmark in auto device selection mode */
323 
324  SemaphoreInfo* lock;
325 
326  cl_command_queue commandQueues[MAX_COMMAND_QUEUES];
327  ssize_t commandQueuesPos;
328  SemaphoreInfo* commandQueuesLock;
329 };
330 
331 
332 #if defined(MAGICKCORE_HDRI_SUPPORT)
333 #define CLOptions "-cl-single-precision-constant -cl-mad-enable -DMAGICKCORE_HDRI_SUPPORT=1 "\
334  "-DCLQuantum=float -DCLSignedQuantum=float -DCLPixelType=float4 -DQuantumRange=%f " \
335  "-DQuantumScale=%f -DCharQuantumScale=%f -DMagickEpsilon=%f -DMagickPI=%f "\
336  " -DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u"
337 #define CLPixelPacket cl_float4
338 #define CLCharQuantumScale 1.0f
339 #elif (MAGICKCORE_QUANTUM_DEPTH == 8)
340 #define CLOptions "-cl-single-precision-constant -cl-mad-enable " \
341  "-DCLQuantum=uchar -DCLSignedQuantum=char -DCLPixelType=uchar4 -DQuantumRange=%ff " \
342  "-DQuantumScale=%ff -DCharQuantumScale=%ff -DMagickEpsilon=%ff -DMagickPI=%ff "\
343  "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u"
344 #define CLPixelPacket cl_uchar4
345 #define CLCharQuantumScale 1.0f
346 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
347 #define CLOptions "-cl-single-precision-constant -cl-mad-enable " \
348  "-DCLQuantum=ushort -DCLSignedQuantum=short -DCLPixelType=ushort4 -DQuantumRange=%f "\
349  "-DQuantumScale=%f -DCharQuantumScale=%f -DMagickEpsilon=%f -DMagickPI=%f "\
350  "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u"
351 #define CLPixelPacket cl_ushort4
352 #define CLCharQuantumScale 257.0f
353 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
354 #define CLOptions "-cl-single-precision-constant -cl-mad-enable " \
355  "-DCLQuantum=uint -DCLSignedQuantum=int -DCLPixelType=uint4 -DQuantumRange=%f "\
356  "-DQuantumScale=%f -DCharQuantumScale=%f -DMagickEpsilon=%f -DMagickPI=%f "\
357  "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u"
358 #define CLPixelPacket cl_uint4
359 #define CLCharQuantumScale 16843009.0f
360 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
361 #define CLOptions "-cl-single-precision-constant -cl-mad-enable " \
362  "-DCLQuantum=ulong -DCLSignedQuantum=long -DCLPixelType=ulong4 -DQuantumRange=%f "\
363  "-DQuantumScale=%f -DCharQuantumScale=%f -DMagickEpsilon=%f -DMagickPI=%f "\
364  "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u"
365 #define CLPixelPacket cl_ulong4
366 #define CLCharQuantumScale 72340172838076673.0f
367 #endif
368 
369 typedef enum {
370  AddNoiseKernel,
371  BlurRowKernel,
372  BlurColumnKernel,
373  CompositeKernel,
374  ComputeFunctionKernel,
375  ContrastKernel,
376  ContrastStretchKernel,
377  ConvolveKernel,
378  EqualizeKernel,
379  GrayScaleKernel,
380  HistogramKernel,
381  HullPass1Kernel,
382  HullPass2Kernel,
383  LocalContrastBlurRowKernel,
384  LocalContrastBlurApplyColumnKernel,
385  ModulateKernel,
386  MotionBlurKernel,
387  RadialBlurKernel,
388  RandomNumberGeneratorKernel,
389  ResizeHorizontalKernel,
390  ResizeVerticalKernel,
391  UnsharpMaskBlurColumnKernel,
392  UnsharpMaskKernel,
393  WaveletDenoiseKernel,
394  KERNEL_COUNT
395 } ProfiledKernels;
396 
397 extern MagickPrivate cl_context
398  GetOpenCLContext(MagickCLEnv);
399 
400 extern MagickPrivate cl_kernel
401  AcquireOpenCLKernel(MagickCLEnv, MagickOpenCLProgram, const char*);
402 
403 extern MagickPrivate cl_command_queue
404  AcquireOpenCLCommandQueue(MagickCLEnv);
405 
406 extern MagickPrivate MagickBooleanType
407  OpenCLThrowMagickException(ExceptionInfo *,
408  const char *,const char *,const size_t,
409  const ExceptionType,const char *,const char *,...),
410  RecordProfileData(MagickCLEnv,ProfiledKernels,cl_event),
411  RelinquishMagickOpenCLEnv(MagickCLEnv),
412  RelinquishOpenCLCommandQueue(MagickCLEnv, cl_command_queue),
413  RelinquishOpenCLKernel(MagickCLEnv, cl_kernel);
414 
415 extern MagickPrivate MagickCLEnv
416  AcquireMagickOpenCLEnv(),
417  SetDefaultOpenCLEnv(MagickCLEnv);
418 
419 extern MagickPrivate unsigned long
420  GetOpenCLDeviceLocalMemorySize(MagickCLEnv),
421  GetOpenCLDeviceMaxMemAllocSize(MagickCLEnv);
422 
423 extern MagickPrivate const char*
424  GetOpenCLCachedFilesDirectory();
425 
426 extern MagickPrivate void
427  OpenCLLog(const char*),
428  OpenCLTerminus();
429 
430 /* #define OPENCLLOG_ENABLED 1 */
431 static inline void OpenCLLogException(const char* function,
432  const unsigned int line,
433  ExceptionInfo* exception) {
434 #ifdef OPENCLLOG_ENABLED
435  if (exception->severity!=0) {
436  char message[MaxTextExtent];
437  /* dump the source into a file */
438  (void) FormatLocaleString(message,MaxTextExtent,"%s:%d Exception(%d):%s "
439  ,function,line,exception->severity,exception->reason);
440  OpenCLLog(message);
441  }
442 #else
443  magick_unreferenced(function);
444  magick_unreferenced(line);
445  magick_unreferenced(exception);
446 #endif
447 }
448 #endif
449 
450 #if defined(__cplusplus) || defined(c_plusplus)
451 }
452 #endif
453 
454 #endif