Home | History | Annotate | Download | only in MagickCore
      1 /*
      2 Copyright 1999-2019 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