18#ifndef MAGICKCORE_OPENCL_PRIVATE_H
19#define MAGICKCORE_OPENCL_PRIVATE_H
24#include "magick/studio.h"
25#include "magick/opencl.h"
27#if defined(MAGICKCORE_HAVE_CL_CL_H)
30#if defined(MAGICKCORE_HAVE_OPENCL_CL_H)
31# include <OpenCL/cl.h>
34#if defined(__cplusplus) || defined(c_plusplus)
38#if !defined(MAGICKCORE_OPENCL_SUPPORT)
39 typedef void* cl_event;
41 typedef void* cl_uint;
44#define MAX_COMMAND_QUEUES 16
53typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clGetPlatformIDs)(
55 cl_platform_id * platforms,
56 cl_uint * num_platforms) CL_API_SUFFIX__VERSION_1_0;
58typedef 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,
63 size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0;
66typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clGetDeviceIDs)(
67 cl_platform_id platform,
68 cl_device_type device_type,
70 cl_device_id * devices,
71 cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_0;
73typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clGetDeviceInfo)(
75 cl_device_info param_name,
76 size_t param_value_size,
78 size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0;
81typedef CL_API_ENTRY cl_context (CL_API_CALL *MAGICKpfn_clCreateContext)(
82 const cl_context_properties * properties,
84 const cl_device_id * devices,
85 void (CL_CALLBACK *pfn_notify)(
const char *,
const void *, size_t,
void *),
87 cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
89typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clReleaseContext)(
90 cl_context context) CL_API_SUFFIX__VERSION_1_0;
93typedef CL_API_ENTRY cl_command_queue (CL_API_CALL *MAGICKpfn_clCreateCommandQueue)(
96 cl_command_queue_properties properties,
97 cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
99typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clReleaseCommandQueue)(
100 cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_0;
103typedef CL_API_ENTRY cl_mem (CL_API_CALL *MAGICKpfn_clCreateBuffer)(
108 cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
110typedef CL_API_ENTRY cl_int
111 (CL_API_CALL *MAGICKpfn_clRetainMemObject)(cl_mem memobj)
112 CL_API_SUFFIX__VERSION_1_0;
114typedef CL_API_ENTRY cl_int
115 (CL_API_CALL *MAGICKpfn_clReleaseMemObject)(cl_mem memobj)
116 CL_API_SUFFIX__VERSION_1_0;
119typedef CL_API_ENTRY cl_program (CL_API_CALL *MAGICKpfn_clCreateProgramWithSource)(
122 const char ** strings,
123 const size_t * lengths,
124 cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
126typedef CL_API_ENTRY cl_program (CL_API_CALL *MAGICKpfn_clCreateProgramWithBinary)(
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;
135typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clReleaseProgram)(cl_program program) CL_API_SUFFIX__VERSION_1_0;
137typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clBuildProgram)(
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;
145typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clGetProgramInfo)(
147 cl_program_info param_name,
148 size_t param_value_size,
150 size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0;
152typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clGetProgramBuildInfo)(
155 cl_program_build_info param_name,
156 size_t param_value_size,
158 size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0;
161typedef CL_API_ENTRY cl_kernel (CL_API_CALL *MAGICKpfn_clCreateKernel)(
163 const char * kernel_name,
164 cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
166typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clReleaseKernel)(cl_kernel kernel) CL_API_SUFFIX__VERSION_1_0;
168typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clSetKernelArg)(
172 const void * arg_value) CL_API_SUFFIX__VERSION_1_0;
174typedef CL_API_ENTRY cl_int
175 (CL_API_CALL *MAGICKpfn_clFlush)(cl_command_queue command_queue)
176 CL_API_SUFFIX__VERSION_1_0;
178typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clFinish)(cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_0;
181typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clEnqueueReadBuffer)(
182 cl_command_queue command_queue,
184 cl_bool blocking_read,
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;
192typedef CL_API_ENTRY
void * (CL_API_CALL *MAGICKpfn_clEnqueueMapBuffer)(
193 cl_command_queue command_queue,
195 cl_bool blocking_map,
196 cl_map_flags map_flags,
199 cl_uint num_events_in_wait_list,
200 const cl_event * event_wait_list,
202 cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0;
204typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clEnqueueUnmapMemObject)(
205 cl_command_queue command_queue,
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;
212typedef CL_API_ENTRY cl_int (CL_API_CALL *MAGICKpfn_clEnqueueNDRangeKernel)(
213 cl_command_queue command_queue,
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;
223typedef CL_API_ENTRY cl_int(CL_API_CALL *MAGICKpfn_clGetEventProfilingInfo)(
225 cl_profiling_info param_name,
226 size_t param_value_size,
228 size_t *param_value_size_ret) CL_API_SUFFIX__VERSION_1_0;
230typedef 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;
235typedef CL_API_ENTRY cl_int(CL_API_CALL *MAGICKpfn_clWaitForEvents)(
237 const cl_event *event_list) CL_API_SUFFIX__VERSION_1_0;
239typedef CL_API_ENTRY cl_int(CL_API_CALL *MAGICKpfn_clReleaseEvent)(
240 cl_event event) CL_API_SUFFIX__VERSION_1_0;
242typedef CL_API_ENTRY cl_int(CL_API_CALL *MAGICKpfn_clRetainEvent)(
243 cl_event event) CL_API_SUFFIX__VERSION_1_0;
245typedef 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;
259typedef struct MagickLibraryRec MagickLibrary;
261struct MagickLibraryRec
265 MAGICKpfn_clGetPlatformIDs clGetPlatformIDs;
266 MAGICKpfn_clGetPlatformInfo clGetPlatformInfo;
268 MAGICKpfn_clGetDeviceIDs clGetDeviceIDs;
269 MAGICKpfn_clGetDeviceInfo clGetDeviceInfo;
271 MAGICKpfn_clCreateContext clCreateContext;
272 MAGICKpfn_clReleaseContext clReleaseContext;
274 MAGICKpfn_clCreateCommandQueue clCreateCommandQueue;
275 MAGICKpfn_clReleaseCommandQueue clReleaseCommandQueue;
276 MAGICKpfn_clFlush clFlush;
277 MAGICKpfn_clFinish clFinish;
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;
289 MAGICKpfn_clCreateKernel clCreateKernel;
290 MAGICKpfn_clReleaseKernel clReleaseKernel;
291 MAGICKpfn_clSetKernelArg clSetKernelArg;
293 MAGICKpfn_clEnqueueReadBuffer clEnqueueReadBuffer;
294 MAGICKpfn_clEnqueueMapBuffer clEnqueueMapBuffer;
295 MAGICKpfn_clEnqueueUnmapMemObject clEnqueueUnmapMemObject;
296 MAGICKpfn_clEnqueueNDRangeKernel clEnqueueNDRangeKernel;
298 MAGICKpfn_clGetEventProfilingInfo clGetEventProfilingInfo;
300 MAGICKpfn_clGetEventInfo clGetEventInfo;
301 MAGICKpfn_clWaitForEvents clWaitForEvents;
302 MAGICKpfn_clReleaseEvent clReleaseEvent;
303 MAGICKpfn_clRetainEvent clRetainEvent;
304 MAGICKpfn_clSetEventCallback clSetEventCallback;
308 MagickBooleanType OpenCLInitialized;
309 MagickBooleanType OpenCLDisabled;
311 MagickLibrary * library;
314 cl_platform_id platform;
315 cl_device_type deviceType;
319 MagickBooleanType disableProgramCache;
320 cl_program programs[MAGICK_OPENCL_NUM_PROGRAMS];
322 MagickBooleanType regenerateProfile;
326 cl_command_queue commandQueues[MAX_COMMAND_QUEUES];
327 ssize_t commandQueuesPos;
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
374 ComputeFunctionKernel,
376 ContrastStretchKernel,
383 LocalContrastBlurRowKernel,
384 LocalContrastBlurApplyColumnKernel,
388 RandomNumberGeneratorKernel,
389 ResizeHorizontalKernel,
390 ResizeVerticalKernel,
391 UnsharpMaskBlurColumnKernel,
393 WaveletDenoiseKernel,
397extern MagickPrivate cl_context
400extern MagickPrivate cl_kernel
401 AcquireOpenCLKernel(
MagickCLEnv, MagickOpenCLProgram,
const char*);
403extern MagickPrivate cl_command_queue
406extern MagickPrivate MagickBooleanType
408 const char *,
const char *,
const size_t,
409 const ExceptionType,
const char *,
const char *,...),
410 RecordProfileData(
MagickCLEnv,ProfiledKernels,cl_event),
412 RelinquishOpenCLCommandQueue(
MagickCLEnv, cl_command_queue),
416 AcquireMagickOpenCLEnv(),
419extern MagickPrivate
unsigned long
423extern MagickPrivate
const char*
424 GetOpenCLCachedFilesDirectory();
426extern MagickPrivate
void
427 OpenCLLog(
const char*),
431static inline void OpenCLLogException(
const char* function,
432 const unsigned int line,
434#ifdef OPENCLLOG_ENABLED
435 if (exception->severity!=0) {
436 char message[MaxTextExtent];
438 (void) FormatLocaleString(message,MaxTextExtent,
"%s:%d Exception(%d):%s "
439 ,function,line,exception->severity,exception->reason);
443 magick_unreferenced(function);
444 magick_unreferenced(line);
445 magick_unreferenced(exception);
450#if defined(__cplusplus) || defined(c_plusplus)