embb_mtapi_opencl_runtimelinker.c 11.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * Copyright (c) 2014, Siemens AG. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

27 28 29 30 31
#include <CL/opencl.h>

//////////////////////////////////////////////////////////////////////////
// function pointer wrappers to hide runtime linking

32
#define DECLARECLFUNC(rettype, name, params) typedef CL_API_ENTRY rettype\
33
    (CL_API_CALL *name##Proc)params;\
34 35 36 37
    name##Proc name##_Dynamic = 0;\
    \
    CL_API_ENTRY rettype CL_API_CALL name params

38 39
DECLARECLFUNC(cl_int, clGetPlatformIDs, (cl_uint num_entries,
  cl_platform_id * platforms, cl_uint * num_platforms)) {
40 41 42
  return clGetPlatformIDs_Dynamic(num_entries, platforms, num_platforms);
}

43 44 45 46 47
DECLARECLFUNC(cl_int, clGetPlatformInfo, (cl_platform_id platform,
  cl_platform_info param_name, size_t param_value_size, void * param_value,
  size_t * param_value_size_ret)) {
  return clGetPlatformInfo_Dynamic(platform, param_name, param_value_size,
    param_value, param_value_size_ret);
48 49
}

50 51 52 53 54
DECLARECLFUNC(cl_int, clGetDeviceIDs, (cl_platform_id platform,
  cl_device_type device_type, cl_uint num_entries, cl_device_id * devices,
  cl_uint * num_devices)) {
  return clGetDeviceIDs_Dynamic(platform, device_type, num_entries, devices,
    num_devices);
55 56
}

57 58 59 60 61
DECLARECLFUNC(cl_int, clGetDeviceInfo, (cl_device_id device,
  cl_device_info param_name, size_t param_value_size, void * param_value,
  size_t * param_value_size_ret)) {
  return clGetDeviceInfo_Dynamic(device, param_name, param_value_size,
    param_value, param_value_size_ret);
62 63
}

64 65 66 67 68 69 70
DECLARECLFUNC(cl_context, clCreateContext,
  (const cl_context_properties * properties, cl_uint num_devices,
  const cl_device_id * devices,
  void (CL_CALLBACK * pfn_notify)(const char *, const void *, size_t, void *),
  void * user_data, cl_int * errcode_ret)) {
  return clCreateContext_Dynamic(properties, num_devices, devices, pfn_notify,
    user_data, errcode_ret);
71 72
}

73 74 75 76 77
DECLARECLFUNC(cl_command_queue, clCreateCommandQueue, (cl_context context,
  cl_device_id device, cl_command_queue_properties properties,
  cl_int * errcode_ret)) {
  return clCreateCommandQueue_Dynamic(context, device, properties,
    errcode_ret);
78 79
}

80 81
DECLARECLFUNC(cl_mem, clCreateBuffer, (cl_context context, cl_mem_flags flags,
  size_t size, void * host_ptr, cl_int * errcode_ret)) {
82 83 84
  return clCreateBuffer_Dynamic(context, flags, size, host_ptr, errcode_ret);
}

85 86 87 88 89
DECLARECLFUNC(cl_program, clCreateProgramWithSource, (cl_context context,
  cl_uint count, const char ** strings, const size_t * lengths,
  cl_int * errcode_ret)) {
  return clCreateProgramWithSource_Dynamic(context, count, strings, lengths,
    errcode_ret);
90 91
}

92 93 94 95 96
DECLARECLFUNC(cl_int, clBuildProgram, (cl_program program, cl_uint num_devices,
  const cl_device_id * device_list, const char * options,
  void (CL_CALLBACK * pfn_notify)(cl_program, void *), void * user_data)) {
  return clBuildProgram_Dynamic(program, num_devices, device_list, options,
    pfn_notify, user_data);
97 98
}

99 100 101 102 103 104
DECLARECLFUNC(cl_int, clGetProgramBuildInfo, (cl_program program,
  cl_device_id device, cl_program_build_info param_name,
  size_t param_value_size, void * param_value,
  size_t * param_value_size_ret)) {
  return clGetProgramBuildInfo_Dynamic(program, device, param_name,
    param_value_size, param_value, param_value_size_ret);
105 106
}

107 108
DECLARECLFUNC(cl_kernel, clCreateKernel, (cl_program program,
  const char * kernel_name, cl_int * errcode_ret)) {
109 110 111
  return clCreateKernel_Dynamic(program, kernel_name, errcode_ret);
}

112 113
DECLARECLFUNC(cl_int, clSetKernelArg, (cl_kernel kernel, cl_uint arg_index,
  size_t arg_size, const void * arg_value)) {
114 115 116
  return clSetKernelArg_Dynamic(kernel, arg_index, arg_size, arg_value);
}

117 118 119 120 121 122
DECLARECLFUNC(cl_int, clEnqueueWriteBuffer, (cl_command_queue command_queue,
  cl_mem buffer, cl_bool blocking_write, size_t offset, size_t cb,
  const void * ptr, cl_uint num_events_in_wait_list,
  const cl_event * event_wait_list, cl_event * event)) {
  return clEnqueueWriteBuffer_Dynamic(command_queue, buffer, blocking_write,
    offset, cb, ptr, num_events_in_wait_list, event_wait_list, event);
123 124
}

125 126 127 128 129 130 131 132
DECLARECLFUNC(cl_int, clEnqueueNDRangeKernel, (cl_command_queue command_queue,
  cl_kernel kernel, cl_uint work_dim, const size_t * global_work_offset,
  const size_t * global_work_size, const size_t * local_work_size,
  cl_uint num_events_in_wait_list, const cl_event * event_wait_list,
  cl_event * event)) {
  return clEnqueueNDRangeKernel_Dynamic(command_queue, kernel, work_dim,
    global_work_offset, global_work_size, local_work_size,
    num_events_in_wait_list, event_wait_list, event);
133 134
}

135 136 137 138 139 140
DECLARECLFUNC(cl_int, clEnqueueReadBuffer, (cl_command_queue command_queue,
  cl_mem buffer, cl_bool blocking_read, size_t offset, size_t cb, void * ptr,
  cl_uint num_events_in_wait_list, const cl_event * event_wait_list,
  cl_event * event)) {
  return clEnqueueReadBuffer_Dynamic(command_queue, buffer, blocking_read,
    offset, cb, ptr, num_events_in_wait_list, event_wait_list, event);
141 142
}

143 144 145 146 147 148
DECLARECLFUNC(cl_int, clSetEventCallback, (cl_event event,
  cl_int command_exec_callback_type,
  void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *),
  void * user_data)) {
  return clSetEventCallback_Dynamic(event, command_exec_callback_type,
    pfn_notify, user_data);
149 150
}

151 152
DECLARECLFUNC(cl_int, clWaitForEvents, (cl_uint num_events,
  const cl_event * event_list)) {
153 154 155
  return clWaitForEvents_Dynamic(num_events, event_list);
}

156
DECLARECLFUNC(cl_int, clReleaseKernel, (cl_kernel kernel)) {
157 158 159
  return clReleaseKernel_Dynamic(kernel);
}

160
DECLARECLFUNC(cl_int, clReleaseProgram, (cl_program program)) {
161 162 163
  return clReleaseProgram_Dynamic(program);
}

164 165
DECLARECLFUNC(cl_int, clReleaseCommandQueue,
  (cl_command_queue command_queue)) {
166 167 168
  return clReleaseCommandQueue_Dynamic(command_queue);
}

169
DECLARECLFUNC(cl_int, clReleaseContext, (cl_context context)) {
170 171 172
  return clReleaseContext_Dynamic(context);
}

173
DECLARECLFUNC(cl_int, clReleaseMemObject, (cl_mem memobj)) {
174 175 176
  return clReleaseMemObject_Dynamic(memobj);
}

177
DECLARECLFUNC(cl_int, clFlush, (cl_command_queue command_queue)) {
178 179 180
  return clFlush_Dynamic(command_queue);
}

181
DECLARECLFUNC(cl_int, clFinish, (cl_command_queue command_queue)) {
182 183 184
  return clFinish_Dynamic(command_queue);
}

185 186 187 188 189
DECLARECLFUNC(cl_sampler, clCreateSampler, (cl_context context,
  cl_bool normalized_coords, cl_addressing_mode addressing_mode,
  cl_filter_mode filter_mode, cl_int * errcode_ret)) {
  return clCreateSampler_Dynamic(context, normalized_coords, addressing_mode,
    filter_mode, errcode_ret);
190 191
}

192
DECLARECLFUNC(cl_int, clReleaseSampler, (cl_sampler sampler)) {
193 194 195
  return clReleaseSampler_Dynamic(sampler);
}

196 197 198 199 200 201
DECLARECLFUNC(cl_mem, clCreateImage2D, (cl_context context,
  cl_mem_flags flags, const cl_image_format * image_format, size_t image_width,
  size_t image_height, size_t image_row_pitch, void * host_ptr,
  cl_int * errcode_ret)) {
  return clCreateImage2D_Dynamic(context, flags, image_format, image_width,
    image_height, image_row_pitch, host_ptr, errcode_ret);
202 203
}

204 205 206 207 208 209 210
DECLARECLFUNC(cl_mem, clCreateImage3D, (cl_context context, cl_mem_flags flags,
  const cl_image_format * image_format, size_t image_width,
  size_t image_height, size_t image_depth, size_t image_row_pitch,
  size_t image_slice_pitch, void * host_ptr, cl_int * errcode_ret)) {
  return clCreateImage3D_Dynamic(context, flags, image_format, image_width,
    image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr,
    errcode_ret);
211 212
}

213 214 215 216 217 218
DECLARECLFUNC(cl_int, clEnqueueAcquireGLObjects,
  (cl_command_queue command_queue, cl_uint num_objects,
  const cl_mem * mem_objects, cl_uint num_events_in_wait_list,
  const cl_event * event_wait_list, cl_event * event)) {
  return clEnqueueAcquireGLObjects_Dynamic(command_queue, num_objects,
    mem_objects, num_events_in_wait_list, event_wait_list, event);
219 220
}

221 222 223 224 225 226
DECLARECLFUNC(cl_int, clEnqueueReleaseGLObjects,
  (cl_command_queue command_queue, cl_uint num_objects,
  const cl_mem * mem_objects, cl_uint num_events_in_wait_list,
  const cl_event * event_wait_list, cl_event * event)) {
  return clEnqueueReleaseGLObjects_Dynamic(command_queue, num_objects,
    mem_objects, num_events_in_wait_list, event_wait_list, event);
227 228
}

229 230
DECLARECLFUNC(cl_mem, clCreateFromGLBuffer, (cl_context context,
  cl_mem_flags flags, cl_GLuint bufobj, int * errcode_ret)) {
231 232 233 234 235 236
  return clCreateFromGLBuffer_Dynamic(context, flags, bufobj, errcode_ret);
}

//////////////////////////////////////////////////////////////////////////
// system specific functions

237
#ifdef _WIN32
238 239 240

#include <Windows.h>

241
#define CHECKEDIMPORT(name) name##_Dynamic = \
242 243
  (name##Proc)GetProcAddress(opencl_dll_handle, #name); \
  if (name##_Dynamic == 0) return 0;
244

245 246 247 248
#else

#include <dlfcn.h>

249
#define CHECKEDIMPORT(name) name##_Dynamic = \
250 251
  (name##Proc)dlsym(opencl_dll_handle, #name); \
  if (name##_Dynamic == 0) return 0;
252 253 254

#endif

255
int embb_mtapi_opencl_link_at_runtime() {
256
#ifdef _WIN32
257
  HMODULE opencl_dll_handle = LoadLibraryA("opencl.dll");
258 259 260
#else
  void * opencl_dll_handle = dlopen("libOpenCL.so", RTLD_LAZY);
#endif
261 262 263 264 265 266 267 268 269 270 271 272
  if (opencl_dll_handle == 0)
    return 0;

  CHECKEDIMPORT(clGetPlatformIDs);
  CHECKEDIMPORT(clGetPlatformInfo);
  CHECKEDIMPORT(clGetDeviceIDs);
  CHECKEDIMPORT(clGetDeviceInfo);
  CHECKEDIMPORT(clCreateContext);
  CHECKEDIMPORT(clCreateCommandQueue);
  CHECKEDIMPORT(clCreateBuffer);
  CHECKEDIMPORT(clCreateProgramWithSource);
  CHECKEDIMPORT(clBuildProgram);
273
  CHECKEDIMPORT(clGetProgramBuildInfo);
274 275 276 277 278
  CHECKEDIMPORT(clCreateKernel);
  CHECKEDIMPORT(clSetKernelArg);
  CHECKEDIMPORT(clEnqueueWriteBuffer);
  CHECKEDIMPORT(clEnqueueNDRangeKernel);
  CHECKEDIMPORT(clEnqueueReadBuffer);
279 280
  CHECKEDIMPORT(clSetEventCallback);
  CHECKEDIMPORT(clWaitForEvents);
281 282 283 284 285
  CHECKEDIMPORT(clReleaseKernel);
  CHECKEDIMPORT(clReleaseProgram);
  CHECKEDIMPORT(clReleaseCommandQueue);
  CHECKEDIMPORT(clReleaseContext);
  CHECKEDIMPORT(clReleaseMemObject);
286
  CHECKEDIMPORT(clFlush);
287 288 289 290 291 292 293 294 295 296 297 298
  CHECKEDIMPORT(clFinish);
  CHECKEDIMPORT(clCreateSampler);
  CHECKEDIMPORT(clReleaseSampler);
  CHECKEDIMPORT(clCreateImage2D);
  CHECKEDIMPORT(clCreateImage3D);

  CHECKEDIMPORT(clEnqueueAcquireGLObjects);
  CHECKEDIMPORT(clEnqueueReleaseGLObjects);
  CHECKEDIMPORT(clCreateFromGLBuffer);

  return 1;
}