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