opencl-private.h revision be04cd4a903ac006a2d6f9607cad24aa4fe491bf
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 CLQuantum  cl_float
322#define CLPixelPacket  cl_float4
323#define CLCharQuantumScale 1.0f
324#elif (MAGICKCORE_QUANTUM_DEPTH == 8)
325#define CLOptions "-cl-single-precision-constant -cl-mad-enable " \
326  "-DCLQuantum=uchar -DCLSignedQuantum=char -DCLPixelType=uchar4 -DQuantumRange=%ff " \
327  "-DQuantumScale=%ff -DCharQuantumScale=%ff -DMagickEpsilon=%ff -DMagickPI=%ff "\
328  "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u"
329#define CLQuantum  cl_uchar
330#define CLPixelPacket  cl_uchar4
331#define CLCharQuantumScale 1.0f
332#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
333#define CLOptions "-cl-single-precision-constant -cl-mad-enable " \
334  "-DCLQuantum=ushort -DCLSignedQuantum=short -DCLPixelType=ushort4 -DQuantumRange=%f "\
335  "-DQuantumScale=%f -DCharQuantumScale=%f -DMagickEpsilon=%f -DMagickPI=%f "\
336  "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u"
337#define CLQuantum  cl_ushort
338#define CLPixelPacket  cl_ushort4
339#define CLCharQuantumScale 257.0f
340#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
341#define CLOptions "-cl-single-precision-constant -cl-mad-enable " \
342  "-DCLQuantum=uint -DCLSignedQuantum=int -DCLPixelType=uint4 -DQuantumRange=%f "\
343  "-DQuantumScale=%f -DCharQuantumScale=%f -DMagickEpsilon=%f -DMagickPI=%f "\
344  "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u"
345#define CLQuantum  cl_uint
346#define CLPixelPacket  cl_uint4
347#define CLCharQuantumScale 16843009.0f
348#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
349#define CLOptions "-cl-single-precision-constant -cl-mad-enable " \
350  "-DCLQuantum=ulong -DCLSignedQuantum=long -DCLPixelType=ulong4 -DQuantumRange=%f "\
351  "-DQuantumScale=%f -DCharQuantumScale=%f -DMagickEpsilon=%f -DMagickPI=%f "\
352  "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u"
353#define CLQuantum  cl_ulong
354#define CLPixelPacket  cl_ulong4
355#define CLCharQuantumScale 72340172838076673.0f
356#endif
357
358typedef enum {
359  AddNoiseKernel,
360  BlurRowKernel,
361  BlurColumnKernel,
362  CompositeKernel,
363  ComputeFunctionKernel,
364  ContrastKernel,
365  ContrastStretchKernel,
366  ConvolveKernel,
367  EqualizeKernel,
368  GrayScaleKernel,
369  HistogramKernel,
370  HullPass1Kernel,
371  HullPass2Kernel,
372  LocalContrastBlurRowKernel,
373  LocalContrastBlurApplyColumnKernel,
374  ModulateKernel,
375  MotionBlurKernel,
376  RandomNumberGeneratorKernel,
377  ResizeHorizontalKernel,
378  ResizeVerticalKernel,
379  RotationalBlurKernel,
380  UnsharpMaskBlurColumnKernel,
381  UnsharpMaskKernel,
382  WaveletDenoiseKernel,
383  KERNEL_COUNT
384} ProfiledKernels;
385
386extern MagickPrivate cl_context
387  GetOpenCLContext(MagickCLEnv);
388
389extern MagickPrivate cl_kernel
390  AcquireOpenCLKernel(MagickCLEnv, MagickOpenCLProgram, const char*);
391
392extern MagickPrivate cl_command_queue
393  AcquireOpenCLCommandQueue(MagickCLEnv);
394
395extern MagickPrivate MagickBooleanType
396  OpenCLThrowMagickException(ExceptionInfo *,
397    const char *,const char *,const size_t,
398    const ExceptionType,const char *,const char *,...),
399  RelinquishOpenCLCommandQueue(MagickCLEnv, cl_command_queue),
400  RelinquishOpenCLKernel(MagickCLEnv, cl_kernel);
401
402extern MagickPrivate unsigned long
403  GetOpenCLDeviceLocalMemorySize(MagickCLEnv),
404  GetOpenCLDeviceMaxMemAllocSize(MagickCLEnv);
405
406extern MagickPrivate const char*
407  GetOpenCLCachedFilesDirectory();
408
409extern MagickPrivate void
410  OpenCLLog(const char*),
411  UnlockRandSeedBuffer(MagickCLEnv);
412
413extern MagickPrivate cl_mem
414  GetAndLockRandSeedBuffer(MagickCLEnv);
415
416extern MagickPrivate unsigned int
417  GetNumRandGenerators(MagickCLEnv);
418
419extern MagickPrivate float
420  GetRandNormalize(MagickCLEnv);
421
422extern MagickPrivate void
423  OpenCLTerminus(),
424  RecordProfileData(MagickCLEnv,ProfiledKernels,cl_event);
425
426/* #define OPENCLLOG_ENABLED 1 */
427static inline void OpenCLLogException(const char* function,
428                        const unsigned int line,
429                        ExceptionInfo* exception) {
430#ifdef OPENCLLOG_ENABLED
431  if (exception->severity!=0) {
432    char message[MagickPathExtent];
433    /*  dump the source into a file */
434    (void) FormatLocaleString(message,MagickPathExtent,"%s:%d Exception(%d):%s "
435        ,function,line,exception->severity,exception->reason);
436    OpenCLLog(message);
437  }
438#else
439  magick_unreferenced(function);
440  magick_unreferenced(line);
441  magick_unreferenced(exception);
442#endif
443}
444
445
446#if defined(__cplusplus) || defined(c_plusplus)
447}
448#endif
449
450#endif
451