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