embb_mtapi_opencl_runtimelinker.c 11.5 KB
Newer Older
1
/*
2
 * Copyright (c) 2014-2016, Siemens AG. All rights reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 * 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
#include <CL/opencl.h>
28
#include <embb/base/c/internal/config.h>
29
#include <embb_mtapi_opencl_runtimelinker.h>
30 31 32 33

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

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

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

45 46 47 48 49
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);
50 51
}

52 53 54 55 56
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);
57 58
}

59 60 61 62 63
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);
64 65
}

66 67 68 69 70 71 72
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);
73 74
}

75 76 77 78 79
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);
80 81
}

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

87 88 89 90 91
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);
92 93
}

94 95 96 97 98
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);
99 100
}

101 102 103 104 105 106
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);
107 108
}

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

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

119 120 121 122 123 124
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);
125 126
}

127 128 129 130 131 132 133 134
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);
135 136
}

137 138 139 140 141 142
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);
143 144
}

145 146 147 148 149 150
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);
151 152
}

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

158
DECLARECLFUNC(cl_int, clReleaseKernel, (cl_kernel kernel)) {
159 160 161
  return clReleaseKernel_Dynamic(kernel);
}

162
DECLARECLFUNC(cl_int, clReleaseProgram, (cl_program program)) {
163 164 165
  return clReleaseProgram_Dynamic(program);
}

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

171
DECLARECLFUNC(cl_int, clReleaseContext, (cl_context context)) {
172 173 174
  return clReleaseContext_Dynamic(context);
}

175
DECLARECLFUNC(cl_int, clReleaseMemObject, (cl_mem memobj)) {
176 177 178
  return clReleaseMemObject_Dynamic(memobj);
}

179
DECLARECLFUNC(cl_int, clFlush, (cl_command_queue command_queue)) {
180 181 182
  return clFlush_Dynamic(command_queue);
}

183
DECLARECLFUNC(cl_int, clFinish, (cl_command_queue command_queue)) {
184 185 186
  return clFinish_Dynamic(command_queue);
}

187 188 189 190 191
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);
192 193
}

194
DECLARECLFUNC(cl_int, clReleaseSampler, (cl_sampler sampler)) {
195 196 197
  return clReleaseSampler_Dynamic(sampler);
}

198 199 200 201 202 203
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);
204 205
}

206 207 208 209 210 211 212
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);
213 214
}

215 216 217 218 219 220
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);
221 222
}

223 224 225 226 227 228
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);
229 230
}

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

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

239
#ifdef _WIN32
240 241 242

#include <Windows.h>

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

247 248 249 250
#else

#include <dlfcn.h>

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

#endif

257 258 259
#ifdef __cplusplus
extern "C"
#endif
260
int embb_mtapi_opencl_link_at_runtime() {
261
#ifdef _WIN32
262
  HMODULE opencl_dll_handle = LoadLibraryA("opencl.dll");
263 264 265
#else
  void * opencl_dll_handle = dlopen("libOpenCL.so", RTLD_LAZY);
#endif
266
  if (opencl_dll_handle == 0)
267
    return -1;
268

269 270 271 272
#ifdef EMBB_PLATFORM_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable: 4191)
#endif
273 274 275 276 277 278 279 280 281
  CHECKEDIMPORT(clGetPlatformIDs);
  CHECKEDIMPORT(clGetPlatformInfo);
  CHECKEDIMPORT(clGetDeviceIDs);
  CHECKEDIMPORT(clGetDeviceInfo);
  CHECKEDIMPORT(clCreateContext);
  CHECKEDIMPORT(clCreateCommandQueue);
  CHECKEDIMPORT(clCreateBuffer);
  CHECKEDIMPORT(clCreateProgramWithSource);
  CHECKEDIMPORT(clBuildProgram);
282
  CHECKEDIMPORT(clGetProgramBuildInfo);
283 284 285 286 287
  CHECKEDIMPORT(clCreateKernel);
  CHECKEDIMPORT(clSetKernelArg);
  CHECKEDIMPORT(clEnqueueWriteBuffer);
  CHECKEDIMPORT(clEnqueueNDRangeKernel);
  CHECKEDIMPORT(clEnqueueReadBuffer);
288 289
  CHECKEDIMPORT(clSetEventCallback);
  CHECKEDIMPORT(clWaitForEvents);
290 291 292 293 294
  CHECKEDIMPORT(clReleaseKernel);
  CHECKEDIMPORT(clReleaseProgram);
  CHECKEDIMPORT(clReleaseCommandQueue);
  CHECKEDIMPORT(clReleaseContext);
  CHECKEDIMPORT(clReleaseMemObject);
295
  CHECKEDIMPORT(clFlush);
296 297 298 299 300 301 302 303 304
  CHECKEDIMPORT(clFinish);
  CHECKEDIMPORT(clCreateSampler);
  CHECKEDIMPORT(clReleaseSampler);
  CHECKEDIMPORT(clCreateImage2D);
  CHECKEDIMPORT(clCreateImage3D);

  CHECKEDIMPORT(clEnqueueAcquireGLObjects);
  CHECKEDIMPORT(clEnqueueReleaseGLObjects);
  CHECKEDIMPORT(clCreateFromGLBuffer);
305 306 307
#ifdef EMBB_PLATFORM_COMPILER_MSVC
#pragma warning(pop)
#endif
308 309 310

  return 1;
}