1 /* 2 Copyright 1999-2021 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 "MagickCore/studio.h" 25 #include "MagickCore/opencl.h" 26 #include "MagickCore/thread_.h" 27 28 #if defined(__cplusplus) || defined(c_plusplus) 29 extern "C" { 30 #endif 31 32 #if !defined(MAGICKCORE_OPENCL_SUPPORT) 33 typedef void* MagickCLCacheInfo; 34 #else 35 typedef struct _MagickCLCacheInfo 36 { 37 cl_event 38 *events; 39 40 cl_mem 41 buffer; 42 43 cl_uint 44 event_count; 45 46 MagickCLDevice 47 device; 48 49 MagickSizeType 50 length; 51 52 Quantum 53 *pixels; 54 55 SemaphoreInfo 56 *events_semaphore; 57 }* MagickCLCacheInfo; 58 59 /* 60 Define declarations. 61 */ 62 #define MAGICKCORE_OPENCL_UNDEFINED_SCORE -1.0 63 #define MAGICKCORE_OPENCL_COMMAND_QUEUES 16 64 65 /* Platform APIs */ 66 typedef CL_API_ENTRY cl_int 67 (CL_API_CALL *MAGICKpfn_clGetPlatformIDs)(cl_uint num_entries, 68 cl_platform_id *platforms,cl_uint *num_platforms) CL_API_SUFFIX__VERSION_1_0; 69 70 typedef CL_API_ENTRY cl_int 71 (CL_API_CALL *MAGICKpfn_clGetPlatformInfo)(cl_platform_id platform, 72 cl_platform_info param_name,size_t param_value_size,void *param_value, 73 size_t *param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; 74 75 76 /* Device APIs */ 77 typedef CL_API_ENTRY cl_int 78 (CL_API_CALL *MAGICKpfn_clGetDeviceIDs)(cl_platform_id platform, 79 cl_device_type device_type,cl_uint num_entries,cl_device_id *devices, 80 cl_uint *num_devices) CL_API_SUFFIX__VERSION_1_0; 81 82 typedef CL_API_ENTRY cl_int 83 (CL_API_CALL *MAGICKpfn_clGetDeviceInfo)(cl_device_id device, 84 cl_device_info param_name,size_t param_value_size,void *param_value, 85 size_t *param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; 86 87 88 /* Context APIs */ 89 typedef CL_API_ENTRY cl_context 90 (CL_API_CALL *MAGICKpfn_clCreateContext)( 91 const cl_context_properties *properties,cl_uint num_devices, 92 const cl_device_id *devices,void (CL_CALLBACK *pfn_notify)(const char *, 93 const void *,size_t,void *),void *user_data,cl_int *errcode_ret) 94 CL_API_SUFFIX__VERSION_1_0; 95 96 typedef CL_API_ENTRY cl_int 97 (CL_API_CALL *MAGICKpfn_clReleaseContext)(cl_context context) 98 CL_API_SUFFIX__VERSION_1_0; 99 100 101 /* Command Queue APIs */ 102 typedef CL_API_ENTRY cl_command_queue 103 (CL_API_CALL *MAGICKpfn_clCreateCommandQueue)(cl_context context, 104 cl_device_id device,cl_command_queue_properties properties, 105 cl_int *errcode_ret) CL_API_SUFFIX__VERSION_1_0; 106 107 typedef CL_API_ENTRY cl_int 108 (CL_API_CALL *MAGICKpfn_clReleaseCommandQueue)( 109 cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_0; 110 111 typedef CL_API_ENTRY cl_int 112 (CL_API_CALL *MAGICKpfn_clFlush)(cl_command_queue command_queue) 113 CL_API_SUFFIX__VERSION_1_0; 114 115 typedef CL_API_ENTRY cl_int 116 (CL_API_CALL *MAGICKpfn_clFinish)(cl_command_queue command_queue) 117 CL_API_SUFFIX__VERSION_1_0; 118 119 120 /* Memory Object APIs */ 121 typedef CL_API_ENTRY cl_mem 122 (CL_API_CALL *MAGICKpfn_clCreateBuffer)(cl_context context, 123 cl_mem_flags flags,size_t size,void *host_ptr,cl_int *errcode_ret) 124 CL_API_SUFFIX__VERSION_1_0; 125 126 typedef CL_API_ENTRY cl_int 127 (CL_API_CALL *MAGICKpfn_clRetainMemObject)(cl_mem memobj) 128 CL_API_SUFFIX__VERSION_1_0; 129 130 typedef CL_API_ENTRY cl_int 131 (CL_API_CALL *MAGICKpfn_clReleaseMemObject)(cl_mem memobj) 132 CL_API_SUFFIX__VERSION_1_0; 133 134 135 /* Program Object APIs */ 136 typedef CL_API_ENTRY cl_program 137 (CL_API_CALL *MAGICKpfn_clCreateProgramWithSource)(cl_context context, 138 cl_uint count,const char **strings,const size_t *lengths, 139 cl_int *errcode_ret) CL_API_SUFFIX__VERSION_1_0; 140 141 typedef CL_API_ENTRY cl_program 142 (CL_API_CALL *MAGICKpfn_clCreateProgramWithBinary)(cl_context context, 143 cl_uint num_devices,const cl_device_id *device_list,const size_t *lengths, 144 const unsigned char **binaries,cl_int *binary_status,cl_int *errcode_ret) 145 CL_API_SUFFIX__VERSION_1_0; 146 147 typedef CL_API_ENTRY cl_int 148 (CL_API_CALL *MAGICKpfn_clReleaseProgram)(cl_program program) 149 CL_API_SUFFIX__VERSION_1_0; 150 151 typedef CL_API_ENTRY cl_int 152 (CL_API_CALL *MAGICKpfn_clBuildProgram)(cl_program program, 153 cl_uint num_devices,const cl_device_id *device_list,const char *options, 154 void (CL_CALLBACK *pfn_notify)(cl_program program,void * user_data), 155 void *user_data) CL_API_SUFFIX__VERSION_1_0; 156 157 typedef CL_API_ENTRY cl_int 158 (CL_API_CALL *MAGICKpfn_clGetProgramBuildInfo)(cl_program program, 159 cl_device_id device,cl_program_build_info param_name,size_t param_value_size, 160 void *param_value,size_t *param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; 161 162 typedef CL_API_ENTRY cl_int 163 (CL_API_CALL *MAGICKpfn_clGetProgramInfo)(cl_program program, 164 cl_program_info param_name,size_t param_value_size,void *param_value, 165 size_t *param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; 166 167 168 /* Kernel Object APIs */ 169 typedef CL_API_ENTRY cl_kernel 170 (CL_API_CALL *MAGICKpfn_clCreateKernel)(cl_program program, 171 const char *kernel_name,cl_int *errcode_ret) CL_API_SUFFIX__VERSION_1_0; 172 173 typedef CL_API_ENTRY cl_int 174 (CL_API_CALL *MAGICKpfn_clReleaseKernel)(cl_kernel kernel) 175 CL_API_SUFFIX__VERSION_1_0; 176 177 typedef CL_API_ENTRY cl_int 178 (CL_API_CALL *MAGICKpfn_clSetKernelArg)(cl_kernel kernel,cl_uint arg_index, 179 size_t arg_size,const void * arg_value) CL_API_SUFFIX__VERSION_1_0; 180 181 typedef CL_API_ENTRY cl_int 182 (CL_API_CALL *MAGICKpfn_clGetKernelInfo)(cl_kernel kernel, 183 cl_kernel_info param_name,size_t param_value_size,void *param_value, 184 size_t *param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; 185 186 187 /* Enqueued Commands APIs */ 188 typedef CL_API_ENTRY cl_int 189 (CL_API_CALL *MAGICKpfn_clEnqueueReadBuffer)(cl_command_queue command_queue, 190 cl_mem buffer,cl_bool blocking_read,size_t offset,size_t cb,void *ptr, 191 cl_uint num_events_in_wait_list,const cl_event *event_wait_list, 192 cl_event *event) CL_API_SUFFIX__VERSION_1_0; 193 194 typedef CL_API_ENTRY void 195 *(CL_API_CALL *MAGICKpfn_clEnqueueMapBuffer)(cl_command_queue command_queue, 196 cl_mem buffer,cl_bool blocking_map,cl_map_flags map_flags,size_t offset, 197 size_t cb,cl_uint num_events_in_wait_list,const cl_event *event_wait_list, 198 cl_event *event,cl_int *errcode_ret) CL_API_SUFFIX__VERSION_1_0; 199 200 typedef CL_API_ENTRY cl_int 201 (CL_API_CALL *MAGICKpfn_clEnqueueUnmapMemObject)( 202 cl_command_queue command_queue,cl_mem memobj,void *mapped_ptr, 203 cl_uint num_events_in_wait_list,const cl_event *event_wait_list, 204 cl_event *event) CL_API_SUFFIX__VERSION_1_0; 205 206 typedef CL_API_ENTRY cl_int 207 (CL_API_CALL *MAGICKpfn_clEnqueueNDRangeKernel)( 208 cl_command_queue command_queue,cl_kernel kernel,cl_uint work_dim, 209 const size_t *global_work_offset,const size_t *global_work_size, 210 const size_t *local_work_size,cl_uint num_events_in_wait_list, 211 const cl_event * event_wait_list,cl_event *event) 212 CL_API_SUFFIX__VERSION_1_0; 213 214 215 /* Events APIs */ 216 typedef CL_API_ENTRY cl_int 217 (CL_API_CALL *MAGICKpfn_clGetEventInfo)(cl_event event, 218 cl_profiling_info param_name,size_t param_value_size,void *param_value, 219 size_t *param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; 220 221 typedef CL_API_ENTRY cl_int 222 (CL_API_CALL *MAGICKpfn_clWaitForEvents)(cl_uint num_events, 223 const cl_event *event_list) CL_API_SUFFIX__VERSION_1_0; 224 225 typedef CL_API_ENTRY cl_int 226 (CL_API_CALL *MAGICKpfn_clReleaseEvent)(cl_event event) 227 CL_API_SUFFIX__VERSION_1_0; 228 229 typedef CL_API_ENTRY cl_int 230 (CL_API_CALL *MAGICKpfn_clRetainEvent)(cl_event event) 231 CL_API_SUFFIX__VERSION_1_0; 232 233 typedef CL_API_ENTRY cl_int 234 (CL_API_CALL *MAGICKpfn_clSetEventCallback)(cl_event event, 235 cl_int command_exec_callback_type,void (CL_CALLBACK *MAGICKpfn_notify)( 236 cl_event,cl_int,void *),void *user_data) CL_API_SUFFIX__VERSION_1_1; 237 238 239 /* Profiling APIs */ 240 typedef CL_API_ENTRY cl_int 241 (CL_API_CALL *MAGICKpfn_clGetEventProfilingInfo)(cl_event event, 242 cl_profiling_info param_name,size_t param_value_size,void *param_value, 243 size_t *param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; 244 245 typedef struct MagickLibraryRec MagickLibrary; 246 247 struct MagickLibraryRec 248 { 249 void *library; 250 251 MAGICKpfn_clGetPlatformIDs clGetPlatformIDs; 252 MAGICKpfn_clGetPlatformInfo clGetPlatformInfo; 253 254 MAGICKpfn_clGetDeviceIDs clGetDeviceIDs; 255 MAGICKpfn_clGetDeviceInfo clGetDeviceInfo; 256 257 MAGICKpfn_clCreateContext clCreateContext; 258 MAGICKpfn_clReleaseContext clReleaseContext; 259 260 MAGICKpfn_clCreateCommandQueue clCreateCommandQueue; 261 MAGICKpfn_clReleaseCommandQueue clReleaseCommandQueue; 262 MAGICKpfn_clFlush clFlush; 263 MAGICKpfn_clFinish clFinish; 264 265 MAGICKpfn_clCreateBuffer clCreateBuffer; 266 MAGICKpfn_clRetainMemObject clRetainMemObject; 267 MAGICKpfn_clReleaseMemObject clReleaseMemObject; 268 269 MAGICKpfn_clCreateProgramWithSource clCreateProgramWithSource; 270 MAGICKpfn_clCreateProgramWithBinary clCreateProgramWithBinary; 271 MAGICKpfn_clReleaseProgram clReleaseProgram; 272 MAGICKpfn_clBuildProgram clBuildProgram; 273 MAGICKpfn_clGetProgramBuildInfo clGetProgramBuildInfo; 274 MAGICKpfn_clGetProgramInfo clGetProgramInfo; 275 276 MAGICKpfn_clCreateKernel clCreateKernel; 277 MAGICKpfn_clReleaseKernel clReleaseKernel; 278 MAGICKpfn_clSetKernelArg clSetKernelArg; 279 MAGICKpfn_clGetKernelInfo clGetKernelInfo; 280 281 MAGICKpfn_clEnqueueReadBuffer clEnqueueReadBuffer; 282 MAGICKpfn_clEnqueueMapBuffer clEnqueueMapBuffer; 283 MAGICKpfn_clEnqueueUnmapMemObject clEnqueueUnmapMemObject; 284 MAGICKpfn_clEnqueueNDRangeKernel clEnqueueNDRangeKernel; 285 286 MAGICKpfn_clGetEventInfo clGetEventInfo; 287 MAGICKpfn_clWaitForEvents clWaitForEvents; 288 MAGICKpfn_clReleaseEvent clReleaseEvent; 289 MAGICKpfn_clRetainEvent clRetainEvent; 290 MAGICKpfn_clSetEventCallback clSetEventCallback; 291 292 MAGICKpfn_clGetEventProfilingInfo clGetEventProfilingInfo; 293 }; 294 295 struct _MagickCLDevice 296 { 297 char 298 *name, 299 *platform_name, 300 *version; 301 302 cl_command_queue 303 command_queues[MAGICKCORE_OPENCL_COMMAND_QUEUES]; 304 305 cl_context 306 context; 307 308 cl_device_id 309 deviceID; 310 311 cl_device_type 312 type; 313 314 cl_program 315 program; 316 317 cl_uint 318 max_clock_frequency, 319 max_compute_units; 320 321 cl_ulong 322 local_memory_size; 323 324 double 325 score; 326 327 KernelProfileRecord 328 *profile_records; 329 330 MagickBooleanType 331 enabled, 332 profile_kernels; 333 334 SemaphoreInfo 335 *lock; 336 337 size_t 338 requested; 339 340 ssize_t 341 command_queues_index; 342 343 char 344 *vendor_name; 345 }; 346 347 typedef struct _MagickCLEnv 348 { 349 cl_context 350 *contexts; 351 352 double 353 cpu_score; 354 355 MagickBooleanType 356 enabled, 357 initialized; 358 359 MagickCLDevice 360 *devices; 361 362 MagickLibrary 363 *library; 364 365 MagickThreadType 366 benchmark_thread_id; 367 368 SemaphoreInfo 369 *lock; 370 371 size_t 372 number_contexts, 373 number_devices; 374 } *MagickCLEnv; 375 376 #if defined(MAGICKCORE_HDRI_SUPPORT) 377 #define CLOptions "-cl-single-precision-constant -cl-mad-enable -DMAGICKCORE_HDRI_SUPPORT=1 "\ 378 "-DCLQuantum=float -DCLSignedQuantum=float -DCLPixelType=float4 -DQuantumRange=%ff " \ 379 "-DQuantumScale=%f -DCharQuantumScale=%f -DMagickEpsilon=%f -DMagickPI=%f "\ 380 "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u" 381 #define CLQuantum cl_float 382 #define CLPixelPacket cl_float4 383 #define CLCharQuantumScale 1.0f 384 #elif (MAGICKCORE_QUANTUM_DEPTH == 8) 385 #define CLOptions "-cl-single-precision-constant -cl-mad-enable " \ 386 "-DCLQuantum=uchar -DCLSignedQuantum=char -DCLPixelType=uchar4 -DQuantumRange=%ff " \ 387 "-DQuantumScale=%ff -DCharQuantumScale=%ff -DMagickEpsilon=%ff -DMagickPI=%ff "\ 388 "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u" 389 #define CLQuantum cl_uchar 390 #define CLPixelPacket cl_uchar4 391 #define CLCharQuantumScale 1.0f 392 #elif (MAGICKCORE_QUANTUM_DEPTH == 16) 393 #define CLOptions "-cl-single-precision-constant -cl-mad-enable " \ 394 "-DCLQuantum=ushort -DCLSignedQuantum=short -DCLPixelType=ushort4 -DQuantumRange=%ff "\ 395 "-DQuantumScale=%f -DCharQuantumScale=%f -DMagickEpsilon=%f -DMagickPI=%f "\ 396 "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u" 397 #define CLQuantum cl_ushort 398 #define CLPixelPacket cl_ushort4 399 #define CLCharQuantumScale 257.0f 400 #elif (MAGICKCORE_QUANTUM_DEPTH == 32) 401 #define CLOptions "-cl-single-precision-constant -cl-mad-enable " \ 402 "-DCLQuantum=uint -DCLSignedQuantum=int -DCLPixelType=uint4 -DQuantumRange=%ff "\ 403 "-DQuantumScale=%f -DCharQuantumScale=%f -DMagickEpsilon=%f -DMagickPI=%f "\ 404 "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u" 405 #define CLQuantum cl_uint 406 #define CLPixelPacket cl_uint4 407 #define CLCharQuantumScale 16843009.0f 408 #elif (MAGICKCORE_QUANTUM_DEPTH == 64) 409 #define CLOptions "-cl-single-precision-constant -cl-mad-enable " \ 410 "-DCLQuantum=ulong -DCLSignedQuantum=long -DCLPixelType=ulong4 -DQuantumRange=%ff "\ 411 "-DQuantumScale=%f -DCharQuantumScale=%f -DMagickEpsilon=%f -DMagickPI=%f "\ 412 "-DMaxMap=%u -DMAGICKCORE_QUANTUM_DEPTH=%u" 413 #define CLQuantum cl_ulong 414 #define CLPixelPacket cl_ulong4 415 #define CLCharQuantumScale 72340172838076673.0f 416 #endif 417 418 extern MagickPrivate cl_command_queue 419 AcquireOpenCLCommandQueue(MagickCLDevice); 420 421 extern MagickPrivate cl_int 422 SetOpenCLKernelArg(cl_kernel,size_t,size_t,const void *); 423 424 extern MagickPrivate cl_kernel 425 AcquireOpenCLKernel(MagickCLDevice,const char *); 426 427 extern MagickPrivate cl_mem 428 CreateOpenCLBuffer(MagickCLDevice,cl_mem_flags,size_t,void *); 429 430 extern MagickPrivate MagickBooleanType 431 EnqueueOpenCLKernel(cl_command_queue,cl_kernel,cl_uint,const size_t *, 432 const size_t *,const size_t *,const Image *,const Image *, 433 MagickBooleanType,ExceptionInfo *), 434 InitializeOpenCL(MagickCLEnv,ExceptionInfo *), 435 OpenCLThrowMagickException(MagickCLDevice,ExceptionInfo *, 436 const char *,const char *,const size_t,const ExceptionType,const char *, 437 const char *,...), 438 RecordProfileData(MagickCLDevice,cl_kernel,cl_event); 439 440 extern MagickPrivate MagickCLCacheInfo 441 AcquireMagickCLCacheInfo(MagickCLDevice,Quantum *,const MagickSizeType), 442 CopyMagickCLCacheInfo(MagickCLCacheInfo), 443 RelinquishMagickCLCacheInfo(MagickCLCacheInfo,const MagickBooleanType); 444 445 extern MagickPrivate MagickCLDevice 446 RequestOpenCLDevice(MagickCLEnv); 447 448 extern MagickPrivate MagickCLEnv 449 GetCurrentOpenCLEnv(void); 450 451 extern MagickPrivate unsigned long 452 GetOpenCLDeviceLocalMemorySize(const MagickCLDevice); 453 454 extern MagickPrivate void 455 DumpOpenCLProfileData(), 456 OpenCLTerminus(), 457 ReleaseOpenCLCommandQueue(MagickCLDevice,cl_command_queue), 458 ReleaseOpenCLDevice(MagickCLDevice), 459 ReleaseOpenCLKernel(cl_kernel), 460 ReleaseOpenCLMemObject(cl_mem), 461 RetainOpenCLEvent(cl_event), 462 RetainOpenCLMemObject(cl_mem); 463 464 #endif 465 466 #if defined(__cplusplus) || defined(c_plusplus) 467 } 468 #endif 469 470 #endif 471