opencl-bindings 1.0.0pre

Sign up to get free protection for your applications and to get access to all the features.
data/sample/hello.cl ADDED
@@ -0,0 +1,19 @@
1
+ #pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
2
+ /* Ref.: http://www.fixstars.com/en/opencl/book/sample/ */
3
+ __kernel void hello(__global char* string)
4
+ {
5
+ string[0] = 'H';
6
+ string[1] = 'e';
7
+ string[2] = 'l';
8
+ string[3] = 'l';
9
+ string[4] = 'o';
10
+ string[5] = ',';
11
+ string[6] = ' ';
12
+ string[7] = 'W';
13
+ string[8] = 'o';
14
+ string[9] = 'r';
15
+ string[10] = 'l';
16
+ string[11] = 'd';
17
+ string[12] = '!';
18
+ string[13] = '\0';
19
+ }
data/sample/hello.rb ADDED
@@ -0,0 +1,69 @@
1
+ # An example using raw OpenCL API.
2
+ # For more samples, visit https://github.com/vaiorabbit/ruby-opencl/tree/master/sample .
3
+ #
4
+ # Usage : $ ruby hello.rb
5
+ # Hello, World!
6
+ #
7
+ # Ref.: http://www.fixstars.com/en/opencl/book/sample/
8
+
9
+ require_relative '../lib/opencl'
10
+
11
+ # Load DLL
12
+ begin
13
+ OpenCL.load_lib('c:/Windows/System32/OpenCL.dll') # For Windows
14
+ rescue
15
+ OpenCL.load_lib('/System/Library/Frameworks/OpenCL.framework/OpenCL') # For Mac OS X
16
+ end
17
+ include OpenCL
18
+
19
+ # Platform
20
+ cl_platforms_buf = ' ' * 4
21
+ cl_platforms_count_buf = ' ' * 4
22
+ clGetPlatformIDs(1, cl_platforms_buf, cl_platforms_count_buf)
23
+ cl_platform = cl_platforms_buf.unpack("L")[0]
24
+
25
+ # Devices
26
+ cl_devices_buf_writable_count = 32
27
+ cl_devices_buf = ' ' * 4 * cl_devices_buf_writable_count
28
+ cl_devices_entry_count_buf = ' ' * 4
29
+
30
+ clGetDeviceIDs(cl_platform, CL_DEVICE_TYPE_DEFAULT, cl_devices_buf_writable_count, cl_devices_buf, cl_devices_entry_count_buf)
31
+ cl_devices_entry_count = cl_devices_entry_count_buf.unpack("L")[0]
32
+ cl_device_ids = cl_devices_buf.unpack("Q#{cl_devices_entry_count}")
33
+
34
+ # Context
35
+ errcode_ret_buf = ' ' * 4
36
+ cl_ctx = OpenCL.clCreateContext(nil, 1, cl_devices_buf, nil, nil, errcode_ret_buf)
37
+
38
+ # Command Queues
39
+ cl_cq = clCreateCommandQueue(cl_ctx, cl_device_ids[0], 0, errcode_ret_buf)
40
+
41
+ # Memory Buffer
42
+ MEM_SIZE = 128
43
+ cl_memobj = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE, MEM_SIZE * Fiddle:: SIZEOF_CHAR, nil, errcode_ret_buf)
44
+
45
+ # Program
46
+ source_str = File.read("hello.cl")
47
+ cl_prog = clCreateProgramWithSource(cl_ctx, 1, [source_str].pack("p"), [source_str.bytesize].pack("Q"), errcode_ret_buf)
48
+ clBuildProgram(cl_prog, 1, [cl_device_ids[0]].pack("Q"), nil, nil, nil)
49
+
50
+ # Kernel
51
+ cl_kern = clCreateKernel(cl_prog, "hello", errcode_ret_buf)
52
+
53
+ # Execute
54
+ clSetKernelArg(cl_kern, 0, Fiddle::SIZEOF_VOIDP, [cl_memobj.to_i].pack("Q"))
55
+ clEnqueueTask(cl_cq, cl_kern, 0, nil, nil)
56
+
57
+ # Result
58
+ result_buf = ' ' * MEM_SIZE
59
+ clEnqueueReadBuffer(cl_cq, cl_memobj, CL_TRUE, 0, MEM_SIZE * Fiddle::SIZEOF_CHAR, result_buf, 0, nil, nil)
60
+ puts result_buf # => Hello, World!
61
+
62
+ # End
63
+ clFlush(cl_cq)
64
+ clFinish(cl_cq)
65
+ clReleaseKernel(cl_kern)
66
+ clReleaseProgram(cl_prog)
67
+ clReleaseMemObject(cl_memobj)
68
+ clReleaseCommandQueue(cl_cq)
69
+ clReleaseContext(cl_ctx)
@@ -0,0 +1,59 @@
1
+ # An example using simple wrapper.
2
+ # For more samples, visit https://github.com/vaiorabbit/ruby-opencl/tree/master/sample .
3
+ #
4
+ # Usage : $ ruby hello_clu.rb
5
+ # Hello, World!
6
+ #
7
+ # Ref.: http://www.fixstars.com/en/opencl/book/sample/
8
+
9
+ require_relative 'util/clu'
10
+
11
+ # Load DLL
12
+ begin
13
+ OpenCL.load_lib('c:/Windows/System32/OpenCL.dll') # For Windows
14
+ rescue
15
+ OpenCL.load_lib('/System/Library/Frameworks/OpenCL.framework/OpenCL') # For Mac OS X
16
+ end
17
+ include OpenCL
18
+
19
+ # Platform
20
+ clu_platform = CLUPlatform.new
21
+
22
+ # Devices
23
+ clu_device = CLUDevice.new(clu_platform.platforms[0], CL_DEVICE_TYPE_DEFAULT)
24
+
25
+ # Context
26
+ clu_ctx = CLUContext.newContext(nil, clu_device.devices)
27
+
28
+ # Command Queues
29
+ clu_cq = CLUCommandQueue.newCommandQueue(clu_ctx.context, clu_device.devices[0])
30
+
31
+ # Memory Buffer
32
+ MEM_SIZE = 128
33
+ clu_memobj = CLUMemory.newBuffer(clu_ctx.context, CL_MEM_READ_WRITE, MEM_SIZE * Fiddle:: SIZEOF_CHAR)
34
+
35
+ # Program
36
+ source_str = File.read("hello.cl")
37
+ clu_prog = CLUProgram.newProgramWithSource(clu_ctx.context, [source_str])
38
+ clu_prog.buildProgram(clu_device.devices)
39
+
40
+ # Kernel
41
+ clu_kern = CLUKernel.newKernel(clu_prog.program, "hello")
42
+
43
+ # Execute
44
+ clu_kern.setKernelArg(0, Fiddle::TYPE_VOIDP, [clu_memobj.mem.to_i])
45
+ clu_cq.enqueueTask(clu_kern.kernel)
46
+
47
+ # Result
48
+ result_buf = ' ' * MEM_SIZE
49
+ clu_cq.enqueueReadBuffer(clu_memobj.mem, CL_TRUE, 0, MEM_SIZE * Fiddle::SIZEOF_CHAR, result_buf)
50
+ puts result_buf # => Hello, World!
51
+
52
+ # End
53
+ clu_cq.flush
54
+ clu_cq.finish
55
+ clu_kern.releaseKernel
56
+ clu_prog.releaseProgram
57
+ clu_memobj.releaseMemObject
58
+ clu_cq.releaseCommandQueue
59
+ clu_ctx.releaseContext
@@ -0,0 +1,1470 @@
1
+ require 'rbconfig'
2
+ require_relative '../../lib/opencl'
3
+ require_relative '../../lib/opencl_ext'
4
+ require_relative '../../lib/opencl_gl'
5
+ require_relative '../../lib/opencl_gl_ext'
6
+
7
+ ################################################################################
8
+
9
+ class CLUPlatform
10
+ def initialize
11
+ @platforms = nil # Array of cl_platform_id
12
+ end
13
+
14
+ def platforms
15
+ if @platforms == nil
16
+ getPlatformIDs()
17
+ end
18
+ return @platforms
19
+ end
20
+
21
+ def getPlatformIDs(error_info: nil)
22
+ # cl_uint : num_entries
23
+ # cl_platform_id* : platforms
24
+ # cl_uint* : num_platforms
25
+ num_entries = 32
26
+ platforms_buf = ' ' * 8 * num_entries
27
+ platforms_count_buf = ' ' * 4
28
+
29
+ err = OpenCL.clGetPlatformIDs(num_entries, platforms_buf, platforms_count_buf)
30
+ error_info << err if error_info != nil
31
+
32
+ num_platforms = platforms_count_buf.unpack("L")[0]
33
+ @platforms = platforms_buf.unpack("Q#{num_platforms}")
34
+
35
+ return @platforms
36
+ end
37
+
38
+ # cl_platform_id : platform
39
+ # cl_platform_info : param_name
40
+ def getPlatformInfo(param_name, platform: @platforms[0], error_info: nil)
41
+ param_value_buf_size = 1024
42
+ param_value_buf = ' ' * param_value_buf_size
43
+ param_value_size_ret_buf = ' ' * 4
44
+
45
+ err = OpenCL.clGetPlatformInfo(platform, param_name, param_value_buf_size, param_value_buf, param_value_size_ret_buf)
46
+ error_info << err if error_info != nil
47
+
48
+ param_value_size_ret = param_value_size_ret_buf.unpack("L")[0]
49
+
50
+ return param_value_buf[0...(param_value_size_ret-1)]
51
+ end
52
+ end
53
+
54
+ ################################################################################
55
+
56
+ class CLUDevice
57
+ attr_reader :devices # Array of cl_device_id
58
+
59
+ # cl_platform_id : platform
60
+ # cl_device_type : device_type
61
+ def initialize(platform = nil, device_type = OpenCL::CL_DEVICE_TYPE_DEFAULT)
62
+ @devices = nil
63
+ if platform != nil
64
+ getDeviceIDs(platform, device_type)
65
+ end
66
+ end
67
+
68
+ # cl_platform_id : platform
69
+ # cl_device_type : device_type
70
+ def getDeviceIDs(platform, device_type, error_info: nil)
71
+ # cl_uint : num_entries
72
+ # cl_device_id * : devices
73
+ # cl_uint * : num_devices
74
+ num_entries = 32
75
+ devices_buf = ' ' * 4 * num_entries
76
+ num_devices_buf = ' ' * 4
77
+
78
+ err = OpenCL.clGetDeviceIDs(platform, device_type, num_entries, devices_buf, num_devices_buf)
79
+ error_info << err if error_info != nil
80
+
81
+ num_devices = num_devices_buf.unpack("L")[0]
82
+ @devices = devices_buf.unpack("Q#{num_devices}")
83
+
84
+ return @devices
85
+ end
86
+
87
+ # cl_device_id : device
88
+ def retainDevice(device: @devices[0], error_info: nil)
89
+ return OpenCL.clRetainDevice(device)
90
+ end
91
+
92
+ def retainDevices(error_info: nil)
93
+ @devices.each do |device|
94
+ err = OpenCL.clRetainDevice(device)
95
+ error_info << err if error_info != nil
96
+ end
97
+ end
98
+
99
+ # cl_device_id : device
100
+ def releaseDevice(device: @devices[0], error_info: nil)
101
+ return OpenCL.clReleaseDevice(device)
102
+ end
103
+
104
+ def releaseDevices(error_info: nil)
105
+ @devices.each do |device|
106
+ err = OpenCL.clReleaseDevice(device)
107
+ error_info << err if error_info != nil
108
+ end
109
+ end
110
+
111
+ # cl_device_id : device
112
+ # cl_device_info : param_name
113
+ def getDeviceInfo(param_name, device: @devices[0], error_info: nil)
114
+ # size_t : param_value_size
115
+ # void * : param_value
116
+ # size_t * : param_value_size_ret
117
+ param_value_buf_length = 1024
118
+ param_value_buf = ' ' * param_value_buf_length
119
+ param_value_size_ret_buf = ' ' * 4
120
+
121
+ err = OpenCL.clGetDeviceInfo(device, param_name, param_value_buf_length, param_value_buf, param_value_size_ret_buf)
122
+ error_info << err if error_info != nil
123
+
124
+ param_value_size_ret = param_value_size_ret_buf.unpack("L")[0]
125
+
126
+ if param_name == OpenCL::CL_DEVICE_MAX_WORK_ITEM_SIZES
127
+ # Ref.: https://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clGetDeviceInfo.html
128
+ # CL_DEVICE_MAX_WORK_ITEM_SIZES returns n size_t entries, where n is the value returned by the query for CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS.
129
+ work_item_dimensions_buf = ' ' * 4
130
+ err = OpenCL.clGetDeviceInfo(device, OpenCL::CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, 4, work_item_dimensions_buf, nil)
131
+ error_info << err if error_info != nil
132
+ work_item_dimensions = work_item_dimensions_buf.unpack("L")[0]
133
+ end
134
+
135
+ unpack_format = @@param2unpack[param_name]
136
+ case unpack_format
137
+ when "char[]"
138
+ return param_value_buf[0...(param_value_size_ret-1)]
139
+ when "cl_bool"
140
+ return param_value_buf.unpack("L")[0] == 0 ? false : true
141
+ when "size_t[]"
142
+ if param_name == OpenCL::CL_DEVICE_MAX_WORK_ITEM_SIZES
143
+ return param_value_buf.unpack("Q#{work_item_dimensions}")
144
+ else
145
+ return param_value_buf.unpack("Q")
146
+ end
147
+ when "intptr_t[]"
148
+ if param_name == OpenCL::CL_DEVICE_PARTITION_PROPERTIES
149
+ # This is an array of cl_device_partition_property values...
150
+ # If the device does not support any partition types, a value of 0 will be returned.
151
+ return param_value_buf.unpack("Q#{param_value_size_ret / 8}")
152
+ else
153
+ return param_value_buf.unpack("Q")
154
+ end
155
+ when "cl_bitfield"
156
+ return param_value_buf.unpack("L")[0]
157
+ else
158
+ return param_value_buf.unpack(unpack_format)[0]
159
+ end
160
+ end
161
+
162
+ @@param2unpack = {
163
+ OpenCL::CL_DEVICE_TYPE => "L",
164
+ OpenCL::CL_DEVICE_VENDOR_ID => "L",
165
+ OpenCL::CL_DEVICE_MAX_COMPUTE_UNITS => "L",
166
+ OpenCL::CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS => "L",
167
+ OpenCL::CL_DEVICE_MAX_WORK_GROUP_SIZE => "Q",
168
+ OpenCL::CL_DEVICE_MAX_WORK_ITEM_SIZES => "size_t[]",
169
+ OpenCL::CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR => "L",
170
+ OpenCL::CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT => "L",
171
+ OpenCL::CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT => "L",
172
+ OpenCL::CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG => "L",
173
+ OpenCL::CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT => "L",
174
+ OpenCL::CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE => "L",
175
+ OpenCL::CL_DEVICE_MAX_CLOCK_FREQUENCY => "L",
176
+ OpenCL::CL_DEVICE_ADDRESS_BITS => "L",
177
+ OpenCL::CL_DEVICE_MAX_READ_IMAGE_ARGS => "L",
178
+ OpenCL::CL_DEVICE_MAX_WRITE_IMAGE_ARGS => "L",
179
+ OpenCL::CL_DEVICE_MAX_MEM_ALLOC_SIZE => "Q",
180
+ OpenCL::CL_DEVICE_IMAGE2D_MAX_WIDTH => "L",
181
+ OpenCL::CL_DEVICE_IMAGE2D_MAX_HEIGHT => "L",
182
+ OpenCL::CL_DEVICE_IMAGE3D_MAX_WIDTH => "L",
183
+ OpenCL::CL_DEVICE_IMAGE3D_MAX_HEIGHT => "L",
184
+ OpenCL::CL_DEVICE_IMAGE3D_MAX_DEPTH => "L",
185
+ OpenCL::CL_DEVICE_IMAGE_SUPPORT => "cl_bool",
186
+ OpenCL::CL_DEVICE_MAX_PARAMETER_SIZE => "L",
187
+ OpenCL::CL_DEVICE_MAX_SAMPLERS => "L",
188
+ OpenCL::CL_DEVICE_MEM_BASE_ADDR_ALIGN => "L",
189
+ OpenCL::CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE => "L",
190
+ OpenCL::CL_DEVICE_SINGLE_FP_CONFIG => "cl_bitfield",
191
+ OpenCL::CL_DEVICE_GLOBAL_MEM_CACHE_TYPE => "L",
192
+ OpenCL::CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE => "L",
193
+ OpenCL::CL_DEVICE_GLOBAL_MEM_CACHE_SIZE => "L",
194
+ OpenCL::CL_DEVICE_GLOBAL_MEM_SIZE => "Q",
195
+ OpenCL::CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE => "Q",
196
+ OpenCL::CL_DEVICE_MAX_CONSTANT_ARGS => "L",
197
+ OpenCL::CL_DEVICE_LOCAL_MEM_TYPE => "L",
198
+ OpenCL::CL_DEVICE_LOCAL_MEM_SIZE => "Q",
199
+ OpenCL::CL_DEVICE_ERROR_CORRECTION_SUPPORT => "cl_bool",
200
+ OpenCL::CL_DEVICE_PROFILING_TIMER_RESOLUTION => "L",
201
+ OpenCL::CL_DEVICE_ENDIAN_LITTLE => "cl_bool",
202
+ OpenCL::CL_DEVICE_AVAILABLE => "cl_bool",
203
+ OpenCL::CL_DEVICE_COMPILER_AVAILABLE => "cl_bool",
204
+ OpenCL::CL_DEVICE_EXECUTION_CAPABILITIES => "L",
205
+ OpenCL::CL_DEVICE_QUEUE_PROPERTIES => "cl_bitfield",
206
+ OpenCL::CL_DEVICE_NAME => "char[]",
207
+ OpenCL::CL_DEVICE_VENDOR => "char[]",
208
+ OpenCL::CL_DRIVER_VERSION => "char[]",
209
+ OpenCL::CL_DEVICE_PROFILE => "char[]",
210
+ OpenCL::CL_DEVICE_VERSION => "char[]",
211
+ OpenCL::CL_DEVICE_EXTENSIONS => "char[]",
212
+ OpenCL::CL_DEVICE_PLATFORM => "Q",
213
+ OpenCL::CL_DEVICE_DOUBLE_FP_CONFIG => "cl_bitfield",
214
+ OpenCL::CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF => "L",
215
+ OpenCL::CL_DEVICE_HOST_UNIFIED_MEMORY => "cl_bool",
216
+ OpenCL::CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR => "L",
217
+ OpenCL::CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT => "L",
218
+ OpenCL::CL_DEVICE_NATIVE_VECTOR_WIDTH_INT => "L",
219
+ OpenCL::CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG => "L",
220
+ OpenCL::CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT => "L",
221
+ OpenCL::CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE => "L",
222
+ OpenCL::CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF => "L",
223
+ OpenCL::CL_DEVICE_OPENCL_C_VERSION => "L",
224
+ OpenCL::CL_DEVICE_LINKER_AVAILABLE => "cl_bool",
225
+ OpenCL::CL_DEVICE_BUILT_IN_KERNELS => "char[]",
226
+ OpenCL::CL_DEVICE_IMAGE_MAX_BUFFER_SIZE => "L",
227
+ OpenCL::CL_DEVICE_IMAGE_MAX_ARRAY_SIZE => "L",
228
+ OpenCL::CL_DEVICE_PARENT_DEVICE => "Q",
229
+ OpenCL::CL_DEVICE_PARTITION_MAX_SUB_DEVICES => "L",
230
+ OpenCL::CL_DEVICE_PARTITION_PROPERTIES => "intptr_t[]",
231
+ OpenCL::CL_DEVICE_PARTITION_AFFINITY_DOMAIN => "cl_bitfield",
232
+ OpenCL::CL_DEVICE_PARTITION_TYPE => "L",
233
+ OpenCL::CL_DEVICE_REFERENCE_COUNT => "L",
234
+ OpenCL::CL_DEVICE_PREFERRED_INTEROP_USER_SYNC => "L",
235
+ OpenCL::CL_DEVICE_PRINTF_BUFFER_SIZE => "L",
236
+ OpenCL::CL_DEVICE_IMAGE_PITCH_ALIGNMENT => "L",
237
+ OpenCL::CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT => "L"
238
+ }
239
+ end
240
+
241
+ ################################################################################
242
+
243
+ class CLUContext
244
+ attr_reader :context
245
+
246
+ def initialize
247
+ @context = nil # cl_context
248
+ end
249
+
250
+ # cl_context_properties * : properties
251
+ # cl_device_id * : devices
252
+ # void * : pfn_notify(char *, void *, size_t, void *),
253
+ # void * : user_data
254
+ def createContext(properties, devices, pfn_notify: nil, user_data: nil, error_info: nil)
255
+ packed_properties = properties == nil ? nil : properties.pack("Q*")
256
+ num_devices = devices.length
257
+ errcode_ret_buf = ' ' * 4
258
+
259
+ cl_ctx = OpenCL.clCreateContext(packed_properties, num_devices, devices.pack("Q*"), pfn_notify, user_data, errcode_ret_buf)
260
+ errcode_ret = errcode_ret_buf.unpack("l")[0]
261
+ error_info << errcode_ret if error_info != nil
262
+
263
+ if errcode_ret == OpenCL::CL_SUCCESS
264
+ @context = cl_ctx
265
+ return @context
266
+ else
267
+ return nil
268
+ end
269
+ end
270
+
271
+ def self.newContext(properties, devices, pfn_notify: nil, user_data: nil, error_info: nil)
272
+ obj = CLUContext.new
273
+ ret = obj.createContext(properties, devices, pfn_notify: pfn_notify, user_data: user_data, error_info: error_info)
274
+ return ret == nil ? nil : obj
275
+ end
276
+
277
+ # Prerequisite : opengl-bindings 1.5.2 or later ( https://github.com/vaiorabbit/ruby-opengl )
278
+ # You need to "require 'opengl'" before using this method.
279
+ def createContextWithGLInterop(properties, devices, platform, pfn_notify: nil, user_data: nil, error_info: nil)
280
+
281
+ properties.pop if properties.last == 0
282
+
283
+ case RbConfig::CONFIG['host_os']
284
+
285
+ when /mswin|msys|mingw|cygwin/
286
+ # for Windows
287
+ hGLRC = wglGetCurrentContext()
288
+ hDC = wglGetCurrentDC()
289
+ props = [ OpenCL::CL_GL_CONTEXT_KHR, hGLRC,
290
+ OpenCL::CL_WGL_HDC_KHR, hDC,
291
+ OpenCL::CL_CONTEXT_PLATFORM, platform,
292
+ 0 ]
293
+ properties.concat(props)
294
+
295
+ when /darwin/
296
+ # for Mac OS X
297
+ hCGLContext = CGLGetCurrentContext()
298
+ hCGLShareGroup = CGLGetShareGroup(hCGLContext)
299
+ props = [ OpenCL::CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, hCGLShareGroup,
300
+ 0 ]
301
+ properties.concat(props)
302
+
303
+ when /linux/
304
+ # for Linux (X Window)
305
+ hGLXContext = glXGetCurrentContext()
306
+ hDisplay = glXGetCurrentDisplay()
307
+ props = [ OpenCL::CL_GL_CONTEXT_KHR, hGLXContext,
308
+ OpenCL::CL_GLX_DISPLAY_KHR, hDisplay,
309
+ OpenCL::CL_CONTEXT_PLATFORM, platform,
310
+ 0 ]
311
+ properties.concat(props)
312
+
313
+ else
314
+ raise RuntimeError, "OpenCL : Unknown OS: #{host_os.inspect}"
315
+ end
316
+
317
+ return createContext(properties, devices, pfn_notify: pfn_notify, user_data: user_data, error_info: error_info)
318
+ end
319
+
320
+ def self.newContextWithGLInterop(properties, devices, platform, pfn_notify: nil, user_data: nil, error_info: nil)
321
+ obj = CLUContext.new
322
+ ret = obj.createContextWithGLInterop(properties, devices, platform, pfn_notify: pfn_notify, user_data: user_data, error_info: error_info)
323
+ return ret == nil ? nil : obj
324
+ end
325
+
326
+ # cl_context : context
327
+ def retainContext(context: @context)
328
+ return OpenCL.clRetainContext(context)
329
+ end
330
+
331
+ # cl_context : context
332
+ def releaseContext(context: @context)
333
+ return OpenCL.clReleaseContext(context)
334
+ end
335
+
336
+ # cl_context : context
337
+ # cl_context_info : param_name
338
+ def getContextInfo(param_name, context: @context, error_info: nil)
339
+ # size_t : param_value_size
340
+ # void * : param_value
341
+ # size_t * : param_value_size_ret
342
+ param_value_buf_length = 1024
343
+ param_value_buf = ' ' * param_value_buf_length
344
+ param_value_size_ret_buf = ' ' * 4
345
+
346
+ err = OpenCL.clGetContextInfo(context, param_name, param_value_buf_length, param_value_buf, param_value_size_ret_buf)
347
+ error_info << err if error_info != nil
348
+
349
+ param_value_size_ret = param_value_size_ret_buf.unpack("L")[0]
350
+
351
+ unpack_format = @@param2unpack[param_name]
352
+ return param_value_buf.unpack(unpack_format)[0]
353
+ end
354
+
355
+ @@param2unpack = {
356
+ OpenCL::CL_CONTEXT_REFERENCE_COUNT => "L",
357
+ OpenCL::CL_CONTEXT_DEVICES => "Q",
358
+ OpenCL::CL_CONTEXT_PROPERTIES => "Q",
359
+ OpenCL::CL_CONTEXT_NUM_DEVICES => "L",
360
+ }
361
+
362
+ # cl_context : context
363
+ # cl_mem_flags : flags
364
+ # cl_mem_object_type : image_type
365
+ def getSupportedImageFormats(flags, image_type, context: @context, error_info: nil)
366
+ # cl_uint : num_entries
367
+ # cl_image_format * : image_formats
368
+ # cl_uint * : num_image_formats
369
+
370
+ num_image_formamts_buf = ' ' * 4
371
+ err = OpenCL.clGetSupportedImageFormats(context, flags, image_type, 0, nil, num_image_formamts_buf)
372
+ error_info << err if error_info != nil
373
+ num_image_formamts = num_image_formamts_buf.unpack("L")[0]
374
+
375
+ image_formats_buf = Fiddle::Pointer.malloc(num_image_formamts * OpenCL::CL_STRUCT_IMAGE_FORMAT.size)
376
+ err = OpenCL.clGetSupportedImageFormats(context, flags, image_type, num_image_formamts, image_formats_buf, nil)
377
+ error_info << err if error_info != nil
378
+
379
+ image_formats = []
380
+ num_image_formamts.times do |i|
381
+ fmt = OpenCL::CL_STRUCT_IMAGE_FORMAT.new(image_formats_buf.to_i + i * OpenCL::CL_STRUCT_IMAGE_FORMAT.size)
382
+ image_formats << fmt
383
+ end
384
+ return image_formats
385
+ end
386
+ end
387
+
388
+ ################################################################################
389
+
390
+ class CLUMemory
391
+ attr_reader :mem # cl_mem
392
+
393
+ def initialize
394
+ @mem = nil
395
+ end
396
+
397
+ # cl_context : context
398
+ # cl_mem_flags : flags
399
+ # size_t : size
400
+ # void * : host_ptr
401
+ def createBuffer(context, flags, size, host_ptr = nil, error_info: nil)
402
+ errcode_ret_buf = ' ' * 4
403
+
404
+ mem = OpenCL.clCreateBuffer(context, flags, size, host_ptr, errcode_ret_buf)
405
+ errcode_ret = errcode_ret_buf.unpack("l")[0]
406
+ error_info << errcode_ret if error_info != nil
407
+
408
+ if errcode_ret == OpenCL::CL_SUCCESS
409
+ @mem = mem
410
+ return @mem
411
+ else
412
+ return nil
413
+ end
414
+ end
415
+
416
+ def self.newBuffer(context, flags, size, host_ptr = nil, error_info: nil)
417
+ obj = CLUMemory.new
418
+ ret = obj.createBuffer(context, flags, size, host_ptr, error_info: error_info)
419
+ return ret == nil ? nil : obj
420
+ end
421
+
422
+ # cl_context : context
423
+ # cl_mem_flags : flags
424
+ # const cl_image_format * : image_format
425
+ # const cl_image_desc * : image_desc
426
+ # void * : host_ptr
427
+ def createImage(context, flags, image_format, image_desc, host_ptr = nil, error_info: nil)
428
+ errcode_ret_buf = ' ' * 4
429
+
430
+ mem = OpenCL.clCreateImage(context, flags, image_format, image_desc, host_ptr, errcode_ret_buf)
431
+ errcode_ret = errcode_ret_buf.unpack("l")[0]
432
+ error_info << errcode_ret if error_info != nil
433
+
434
+ if errcode_ret == OpenCL::CL_SUCCESS
435
+ @mem = mem
436
+ return @mem
437
+ else
438
+ return nil
439
+ end
440
+ end
441
+
442
+ def self.newImage(context, flags, image_format, image_desc, host_ptr = nil, error_info: nil)
443
+ obj = CLUMemory.new
444
+ ret = obj.createImage(context, flags, image_format, image_desc, host_ptr, error_info: error_info)
445
+ return ret == nil ? nil : obj
446
+ end
447
+
448
+ # cl_context : context
449
+ # cl_mem_flags : flags
450
+ # cl_GLuint : bufobj
451
+ def createFromGLBuffer(context, flags, bufobj, error_info: nil)
452
+ errcode_ret_buf = ' ' * 4
453
+
454
+ mem = OpenCL.clCreateFromGLBuffer(context, flags, bufobj, errcode_ret_buf)
455
+ errcode_ret = errcode_ret_buf.unpack("l")[0]
456
+ error_info << errcode_ret if error_info != nil
457
+
458
+ if errcode_ret == OpenCL::CL_SUCCESS
459
+ @mem = mem
460
+ return @mem
461
+ else
462
+ return nil
463
+ end
464
+ end
465
+
466
+ def self.newFromGLBuffer(context, flags, bufobj, error_info: nil)
467
+ obj = CLUMemory.new
468
+ ret = obj.createFromGLBuffer(context, flags, bufobj, error_info: error_info)
469
+ return ret == nil ? nil : obj
470
+ end
471
+
472
+ # cl_context : context
473
+ # cl_mem_flags : flags
474
+ # cl_GLenum : target
475
+ # cl_GLint : miplevel
476
+ # cl_GLuint : texture
477
+ def createFromGLTexture(context, flags, target, miplevel, texture, error_info: nil)
478
+ errcode_ret_buf = ' ' * 4
479
+
480
+ mem = OpenCL.clCreateFromGLTexture(context, flags, target, miplevel, texture, errcode_ret_buf)
481
+ errcode_ret = errcode_ret_buf.unpack("l")[0]
482
+ error_info << errcode_ret if error_info != nil
483
+
484
+ if errcode_ret == OpenCL::CL_SUCCESS
485
+ @mem = mem
486
+ return @mem
487
+ else
488
+ return nil
489
+ end
490
+ end
491
+
492
+ def self.newFromGLTexture(context, flags, target, miplevel, texture, error_info: nil)
493
+ obj = CLUMemory.new
494
+ ret = obj.createFromGLTexture(context, flags, target, miplevel, texture, error_info: error_info)
495
+ return ret == nil ? nil : obj
496
+ end
497
+
498
+ # cl_context : context
499
+ # cl_mem_flags : flags
500
+ # cl_GLuint : renderbuffer
501
+ def createFromGLRenderBuffer(context, flags, renderbuffer, error_info: nil)
502
+ errcode_ret_buf = ' ' * 4
503
+
504
+ mem = OpenCL.clCreateFromGLRenderBuffer(context, flags, renderbuffer, errcode_ret_buf)
505
+ errcode_ret = errcode_ret_buf.unpack("l")[0]
506
+ error_info << errcode_ret if error_info != nil
507
+
508
+ if errcode_ret == OpenCL::CL_SUCCESS
509
+ @mem = mem
510
+ return @mem
511
+ else
512
+ return nil
513
+ end
514
+ end
515
+
516
+ def self.newFromGLRenderBuffer(context, flags, renderbuffer, error_info: nil)
517
+ obj = CLUMemory.new
518
+ ret = obj.createFromGLRenderBuffer(context, flags, renderbuffer, error_info: error_info)
519
+ return ret == nil ? nil : obj
520
+ end
521
+
522
+ # cl_mem : mem
523
+ def retainMemObject(mem: @mem)
524
+ return OpenCL.clRetainMemObject(mem)
525
+ end
526
+
527
+ # cl_mem : mem
528
+ def releaseMemObject(mem: @mem)
529
+ return OpenCL.clReleaseMemObject(mem)
530
+ end
531
+
532
+ # cl_mem : memobj
533
+ # cl_mem_info : param_name
534
+ def getMemObjectInfo(param_name, memobj: @mem, error_info: nil)
535
+ # size_t : param_value_size
536
+ # void * : param_value
537
+ # size_t * : param_value_size_ret
538
+ param_value_buf_length = 1024
539
+ param_value_buf = ' ' * param_value_buf_length
540
+ param_value_size_ret_buf = ' ' * 4
541
+
542
+ err = OpenCL.clGetMemObjectInfo(memobj, param_name, param_value_buf_length, param_value_buf, param_value_size_ret_buf)
543
+ error_info << err if error_info != nil
544
+
545
+ param_value_size_ret = param_value_size_ret_buf.unpack("L")[0]
546
+
547
+ unpack_format = @@mem_objinfo_param2unpack[param_name]
548
+ case unpack_format
549
+ when "void*" # param_name == OpenCL::CL_MEM_HOST_PTR
550
+ addr = param_value_buf.unpack("Q")[0]
551
+ # OS X (El Capitan) : Quering CL_MEM_HOST_PTR to memobj created without
552
+ # CL_MEM_USE_HOST_PTR does not return NULL, but keeps param_value_buf untouched.
553
+ if addr == 0 || param_value_buf[0, 8] == ' '
554
+ return nil
555
+ else
556
+ return Fiddle::Pointer.new(addr)
557
+ end
558
+ else
559
+ return param_value_buf.unpack(unpack_format)[0]
560
+ end
561
+ end
562
+
563
+ @@mem_objinfo_param2unpack = {
564
+ OpenCL::CL_MEM_TYPE => "L",
565
+ OpenCL::CL_MEM_FLAGS => "Q",
566
+ OpenCL::CL_MEM_SIZE => "Q",
567
+ OpenCL::CL_MEM_HOST_PTR => "void*",
568
+ OpenCL::CL_MEM_MAP_COUNT => "L",
569
+ OpenCL::CL_MEM_REFERENCE_COUNT => "L",
570
+ OpenCL::CL_MEM_CONTEXT => "Q",
571
+ OpenCL::CL_MEM_ASSOCIATED_MEMOBJECT => "Q",
572
+ OpenCL::CL_MEM_OFFSET => "Q",
573
+ }
574
+
575
+ # cl_mem : memobj
576
+ # cl_image_info : param_name
577
+ def getImageInfo(param_name, memobj: @mem, error_info: nil)
578
+ # size_t : param_value_size
579
+ # void * : param_value
580
+ # size_t * : param_value_size_ret
581
+ param_value_buf_length = 1024
582
+ param_value_buf = ' ' * param_value_buf_length
583
+ param_value_size_ret_buf = ' ' * 4
584
+
585
+ err = OpenCL.clGetImageInfo(memobj, param_name, param_value_buf_length, param_value_buf, param_value_size_ret_buf)
586
+ error_info << err if error_info != nil
587
+
588
+ param_value_size_ret = param_value_size_ret_buf.unpack("L")[0]
589
+
590
+ unpack_format = @@mem_imageinfo_param2unpack[param_name]
591
+ case unpack_format
592
+ when "cl_image_format" # param_name == OpenCL::CL_IMAGE_FORMAT
593
+ values = param_value_buf.unpack("L2") # instance of cl_image_format
594
+ fmt = OpenCL::CL_STRUCT_IMAGE_FORMAT.malloc
595
+ fmt.image_channel_order = values[0]
596
+ fmt.image_channel_data_type = values[1]
597
+ return fmt
598
+ else
599
+ return param_value_buf.unpack(unpack_format)[0]
600
+ end
601
+ end
602
+
603
+ @@mem_imageinfo_param2unpack = {
604
+ OpenCL::CL_IMAGE_FORMAT => "cl_image_format",
605
+ OpenCL::CL_IMAGE_ELEMENT_SIZE => "Q",
606
+ OpenCL::CL_IMAGE_ROW_PITCH => "Q",
607
+ OpenCL::CL_IMAGE_SLICE_PITCH => "Q",
608
+ OpenCL::CL_IMAGE_WIDTH => "Q",
609
+ OpenCL::CL_IMAGE_HEIGHT => "Q",
610
+ OpenCL::CL_IMAGE_DEPTH => "Q",
611
+ OpenCL::CL_IMAGE_ARRAY_SIZE => "Q",
612
+ OpenCL::CL_IMAGE_BUFFER => "Q",
613
+ OpenCL::CL_IMAGE_NUM_MIP_LEVELS => "L",
614
+ OpenCL::CL_IMAGE_NUM_SAMPLES => "L",
615
+ }
616
+
617
+ # cl_mem : memobj
618
+ def getGLObjectInfo(memobj: @mem, error_info: nil)
619
+ # cl_gl_object_type * : gl_object_type
620
+ # cl_GLuint * : gl_object_name
621
+ gl_object_type_buf = ' ' * 8
622
+ gl_object_name_buf = ' ' * 4
623
+
624
+ err = OpenCL.clGetGLObjectInfo(memobj, gl_object_type_buf, gl_object_name_buf)
625
+ error_info << err if error_info != nil
626
+
627
+ return gl_object_type_buf.unpack("L")[0], gl_object_name_buf.unpack("L")[0]
628
+ end
629
+
630
+ # cl_mem : memobj
631
+ # cl_image_info : param_name
632
+ def getGLTextureInfo(param_name, memobj: @mem, error_info: nil)
633
+ # size_t : param_value_size
634
+ # void * : param_value
635
+ # size_t * : param_value_size_ret
636
+ param_value_buf_length = 1024
637
+ param_value_buf = ' ' * param_value_buf_length
638
+ param_value_size_ret_buf = ' ' * 4
639
+
640
+ err = OpenCL.clGetGLTextureInfo(memobj, param_name, param_value_buf_length, param_value_buf, param_value_size_ret_buf)
641
+ error_info << err if error_info != nil
642
+
643
+ param_value_size_ret = param_value_size_ret_buf.unpack("L")[0]
644
+
645
+ unpack_format = @@mem_gltextureinfo_param2unpack[param_name]
646
+ return param_value_buf.unpack(unpack_format)[0]
647
+ end
648
+
649
+ @@mem_gltextureinfo_param2unpack = {
650
+ OpenCL::CL_GL_TEXTURE_TARGET => "L",
651
+ OpenCL::CL_GL_MIPMAP_LEVEL => "l",
652
+ }
653
+ end
654
+
655
+ ################################################################################
656
+
657
+ class CLUCommandQueue
658
+ attr_reader :command_queue # cl_command_queue
659
+
660
+ def initialize
661
+ @command_queue = nil # cl_command_queue
662
+ end
663
+
664
+ # cl_context : context
665
+ # cl_device_id : device
666
+ # cl_command_queue_properties : properties
667
+ def createCommandQueue(context, device, properties = 0, error_info: nil)
668
+ errcode_ret_buf = ' ' * 4
669
+
670
+ cl_cq = OpenCL.clCreateCommandQueue(context, device, properties, errcode_ret_buf)
671
+ errcode_ret = errcode_ret_buf.unpack("l")[0]
672
+ error_info << errcode_ret if error_info != nil
673
+
674
+ if errcode_ret == OpenCL::CL_SUCCESS
675
+ @command_queue = cl_cq
676
+ return @command_queue
677
+ else
678
+ return nil
679
+ end
680
+ end
681
+
682
+ def self.newCommandQueue(context, device, properties = 0, error_info: nil)
683
+ obj = CLUCommandQueue.new
684
+ ret = obj.createCommandQueue(context, device, 0, error_info: error_info)
685
+ return ret == nil ? nil : obj
686
+ end
687
+
688
+ # cl_command_queue : command_queue
689
+ def retainCommandQueue(command_queue: @command_queue)
690
+ return OpenCL.clRetainCommandQueue(command_queue)
691
+ end
692
+
693
+ # cl_command_queue : command_queue
694
+ def releaseCommandQueue(command_queue: @command_queue)
695
+ return OpenCL.clReleaseCommandQueue(command_queue)
696
+ end
697
+
698
+ # cl_command_queue : command_queue
699
+ def flush(command_queue: @command_queue)
700
+ return OpenCL.clFlush(command_queue)
701
+ end
702
+
703
+ # cl_command_queue : command_queue
704
+ def finish(command_queue: @command_queue)
705
+ return OpenCL.clFinish(command_queue)
706
+ end
707
+
708
+ # cl_command_queue : command_queue
709
+ # cl_command_queue_info : param_name
710
+ def getCommandQueueInfo(param_name, command_queue: @command_queue, error_info: nil)
711
+ # size_t : param_value_size
712
+ # void * : param_value
713
+ # size_t * : param_value_size_ret
714
+ param_value_buf_length = 1024
715
+ param_value_buf = ' ' * param_value_buf_length
716
+ param_value_size_ret_buf = ' ' * 4
717
+
718
+ err = OpenCL.clGetCommandQueueInfo(command_queue, param_name, param_value_buf_length, param_value_buf, param_value_size_ret_buf)
719
+ error_info << err if error_info != nil
720
+
721
+ param_value_size_ret = param_value_size_ret_buf.unpack("L")[0]
722
+
723
+ unpack_format = @@param2unpack[param_name]
724
+ return param_value_buf.unpack(unpack_format)[0]
725
+ end
726
+
727
+ @@param2unpack = {
728
+ OpenCL::CL_QUEUE_CONTEXT => "Q",
729
+ OpenCL::CL_QUEUE_DEVICE => "Q",
730
+ OpenCL::CL_QUEUE_REFERENCE_COUNT => "L",
731
+ OpenCL::CL_QUEUE_PROPERTIES => "L",
732
+ }
733
+
734
+ # cl_command_queue : command_queue
735
+ # cl_mem : buffer
736
+ # cl_bool : blocking_read
737
+ # size_t : offset
738
+ # size_t : size
739
+ # void * : ptr
740
+ # const cl_event * : event_wait_list
741
+ # cl_event * : event
742
+ def enqueueReadBuffer(buffer, blocking_read, offset, size, ptr, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
743
+ event_buf = event == nil ? nil : ' ' * 8
744
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
745
+
746
+ err = OpenCL.clEnqueueReadBuffer(command_queue, buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
747
+ error_info << err if error_info != nil
748
+
749
+ event << event_buf.unpack("Q")[0] if event != nil
750
+ return err
751
+ end
752
+
753
+ # cl_command_queue : command_queue
754
+ # cl_mem : buffer
755
+ # cl_bool : blocking_write
756
+ # size_t : offset
757
+ # size_t : size
758
+ # const void * : ptr
759
+ # const cl_event * : event_wait_list
760
+ # cl_event * : event
761
+ def enqueueWriteBuffer(buffer, blocking_write, offset, size, ptr, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
762
+ event_buf = event == nil ? nil : ' ' * 8
763
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
764
+
765
+ err = OpenCL.clEnqueueWriteBuffer(command_queue, buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
766
+ error_info << err if error_info != nil
767
+
768
+ event << event_buf.unpack("Q")[0] if event != nil
769
+ return err
770
+ end
771
+
772
+ # cl_command_queue : command_queue
773
+ # cl_mem : buffer
774
+ # const void * : pattern
775
+ # size_t : offset
776
+ # size_t : size
777
+ # const cl_event * : event_wait_list
778
+ # cl_event * : event
779
+ def enqueueFillBuffer(buffer, pattern, offset, size, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
780
+ event_buf = event == nil ? nil : ' ' * 8
781
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
782
+ # size_t : pattern_size
783
+ pattern_size = pattern.size
784
+
785
+ err = OpenCL.clEnqueueFillBuffer(command_queue, buffer, pattern, pattern_size, offset, size, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
786
+ error_info << err if error_info != nil
787
+
788
+ event << event_buf.unpack("Q")[0] if event != nil
789
+ return err
790
+ end
791
+
792
+ # cl_command_queue : command_queue
793
+ # cl_mem : src_buffer
794
+ # cl_mem : dst_buffer
795
+ # size_t : src_offset
796
+ # size_t : dst_offset
797
+ # size_t : size
798
+ # const cl_event * : event_wait_list
799
+ # cl_event * : event
800
+ def enqueueCopyBuffer(src_buffer, dst_buffer, src_offset, dst_offset, size, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
801
+ event_buf = event == nil ? nil : ' ' * 8
802
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
803
+
804
+ err = OpenCL.clEnqueueCopyBuffer(command_queue, src_buffer, dst_buffer, src_offset, dst_offset, size, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
805
+ error_info << err if error_info != nil
806
+
807
+ event << event_buf.unpack("Q")[0] if event != nil
808
+ return err
809
+ end
810
+
811
+ # cl_command_queue : command_queue
812
+ # cl_mem : image
813
+ # cl_bool : blocking_read
814
+ # const size_t * : origin[3]
815
+ # const size_t * : region[3]
816
+ # size_t : row_pitch
817
+ # size_t : slice_pitch
818
+ # void * : ptr
819
+ # const cl_event * : event_wait_list
820
+ # cl_event * : event
821
+ def enqueueReadImage(image, blocking_read, origin, region, row_pitch, slice_pitch, ptr, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
822
+ event_buf = event == nil ? nil : ' ' * 8
823
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
824
+
825
+ err = OpenCL.clEnqueueReadImage(command_queue, image, blocking_read, origin.pack("Q3"), region.pack("Q3"), row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
826
+ error_info << err if error_info != nil
827
+
828
+ event << event_buf.unpack("Q")[0] if event != nil
829
+ return err
830
+ end
831
+
832
+ # cl_command_queue : command_queue
833
+ # cl_mem : image
834
+ # cl_bool : blocking_write
835
+ # const size_t * : origin[3]
836
+ # const size_t * : region[3]
837
+ # size_t : row_pitch
838
+ # size_t : slice_pitch
839
+ # void * : ptr
840
+ # const cl_event * : event_wait_list
841
+ # cl_event * : event
842
+ def enqueueWriteImage(image, blocking_write, origin, region, row_pitch, slice_pitch, ptr, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
843
+ event_buf = event == nil ? nil : ' ' * 8
844
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
845
+
846
+ err = OpenCL.clEnqueueWriteImage(command_queue, image, blocking_write, origin.pack("Q3"), region.pack("Q3"), row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
847
+ error_info << err if error_info != nil
848
+
849
+ event << event_buf.unpack("Q")[0] if event != nil
850
+ return err
851
+ end
852
+
853
+ # cl_command_queue : command_queue
854
+ # cl_mem : image
855
+ # const void * : fill_color
856
+ # const size_t * : origin[3]
857
+ # const size_t * : region[3]
858
+ # const cl_event * : event_wait_list
859
+ # cl_event * : event
860
+ def enqueueFillImage(image, fill_color, origin, region, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
861
+ event_buf = event == nil ? nil : ' ' * 8
862
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
863
+
864
+ err = OpenCL.clEnqueueFillImage(command_queue, image, fill_color, origin.pack("Q3"), region.pack("Q3"), num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
865
+ error_info << err if error_info != nil
866
+
867
+ event << event_buf.unpack("Q")[0] if event != nil
868
+ return err
869
+ end
870
+
871
+ # cl_command_queue : command_queue
872
+ # cl_mem : src_image
873
+ # cl_mem : dst_image
874
+ # const size_t * : src_origin[3]
875
+ # const size_t * : dst_origin[3]
876
+ # const size_t * : region[3]
877
+ # const cl_event * : event_wait_list
878
+ # cl_event * : event
879
+ def enqueueCopyImage(src_image, dst_image, src_origin, dst_origin, region, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
880
+ event_buf = event == nil ? nil : ' ' * 8
881
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
882
+
883
+ err = OpenCL.clEnqueueCopyImage(command_queue, src_image, dst_image, src_origin.pack("Q3"), dst_origin.pack("Q3"), region.pack("Q3"), num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
884
+ error_info << err if error_info != nil
885
+
886
+ event << event_buf.unpack("Q")[0] if event != nil
887
+ return err
888
+ end
889
+
890
+ # cl_command_queue : command_queue
891
+ # cl_mem : src_image
892
+ # cl_mem : dst_buffer
893
+ # const size_t * : src_origin[3]
894
+ # const size_t * : region[3]
895
+ # size_t : dst_offset
896
+ # const cl_event * : event_wait_list
897
+ # cl_event * : event
898
+ def enqueueCopyImageToBuffer(src_image, dst_buffer, src_origin, region, dst_offset, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
899
+ event_buf = event == nil ? nil : ' ' * 8
900
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
901
+
902
+ err = OpenCL.clEnqueueCopyImageToBuffer(command_queue, src_image, dst_buffer, src_origin.pack("Q3"), region.pack("Q3"), dst_offset, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
903
+ error_info << err if error_info != nil
904
+
905
+ event << event_buf.unpack("Q")[0] if event != nil
906
+ return err
907
+ end
908
+
909
+ # cl_command_queue : command_queue
910
+ # cl_mem : src_buffer
911
+ # cl_mem : dst_image
912
+ # size_t : src_offset
913
+ # const size_t * : dst_origin[3]
914
+ # const size_t * : region[3]
915
+ # const cl_event * : event_wait_list
916
+ # cl_event * : event
917
+ def enqueueCopyBufferToImage(src_buffer, dst_image, src_offset, dst_origin, region, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
918
+ event_buf = event == nil ? nil : ' ' * 8
919
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
920
+
921
+ err = OpenCL.clEnqueueCopyBufferToImage(command_queue, src_buffer, dst_image, src_offset, dst_origin.pack("Q3"), region.pack("Q3"), num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
922
+ error_info << err if error_info != nil
923
+
924
+ event << event_buf.unpack("Q")[0] if event != nil
925
+ return err
926
+ end
927
+
928
+ # cl_command_queue : command_queue
929
+ # cl_mem : buffer
930
+ # cl_bool : blocking_map
931
+ # cl_map_flags : map_flags
932
+ # size_t : offset
933
+ # size_t : size
934
+ # const cl_event * : event_wait_list
935
+ # cl_event * : event
936
+ def enqueueMapBuffer(buffer, blocking_map, map_flags, offset, size, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
937
+ event_buf = event == nil ? nil : ' ' * 8
938
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
939
+ errcode_ret_buf = ' ' * 4
940
+
941
+ mapped_ptr = OpenCL.clEnqueueMapBuffer(command_queue, buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf, errcode_ret_buf)
942
+ errcode_ret = errcode_ret_buf.unpack("l")[0]
943
+ error_info << errcode_ret if error_info != nil
944
+
945
+ event << event_buf.unpack("Q")[0] if event != nil
946
+ if errcode_ret == OpenCL::CL_SUCCESS
947
+ return mapped_ptr
948
+ else
949
+ return nil
950
+ end
951
+ end
952
+
953
+ # cl_command_queue : command_queue
954
+ # cl_mem : image
955
+ # cl_bool : blocking_map
956
+ # cl_map_flags : map_flags
957
+ # const size_t * : origin[3]
958
+ # const size_t * : region[3]
959
+ # const cl_event * : event_wait_list
960
+ # cl_event * : event
961
+ def enqueueMapImage(buffer, blocking_map, map_flags, origin, region, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
962
+ event_buf = event == nil ? nil : ' ' * 8
963
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
964
+ errcode_ret_buf = ' ' * 4
965
+
966
+ image_row_pitch_buf = ' ' * 8
967
+ image_slice_pitch_buf = ' ' * 8
968
+
969
+ mapped_ptr = OpenCL.clEnqueueMapImage(command_queue, buffer, blocking_map, map_flags, origin.pack("Q3"), region.pack("Q3"), image_row_pitch_buf, image_slice_pitch_buf, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf, errcode_ret_buf)
970
+ errcode_ret = errcode_ret_buf.unpack("l")[0]
971
+ error_info << errcode_ret if error_info != nil
972
+
973
+ image_row_pitch = image_row_pitch_buf.unpack("Q")[0]
974
+ image_slice_pitch = image_slice_pitch_buf.unpack("Q")[0]
975
+
976
+ event << event_buf.unpack("Q")[0] if event != nil
977
+ if errcode_ret == OpenCL::CL_SUCCESS
978
+ return mapped_ptr, image_row_pitch, image_slice_pitch
979
+ else
980
+ return nil, image_row_pitch, image_slice_pitch
981
+ end
982
+ end
983
+
984
+ # cl_command_queue : command_queue
985
+ # cl_mem : memobj
986
+ # void * : mapped_ptr
987
+ # const cl_event * : event_wait_list
988
+ # cl_event * : event
989
+ def enqueueUnmapMemObject(memobj, mapped_ptr, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
990
+ event_buf = event == nil ? nil : ' ' * 8
991
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
992
+
993
+ err = OpenCL.clEnqueueUnmapMemObject(command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
994
+ error_info << err if error_info != nil
995
+
996
+ event << event_buf.unpack("Q")[0] if event != nil
997
+ return err
998
+ end
999
+
1000
+ # cl_command_queue : command_queue
1001
+ # cl_kernel : kernel
1002
+ # cl_uint : work_dim
1003
+ # const size_t * : global_work_offset
1004
+ # const size_t * : global_work_size
1005
+ # const size_t * : local_work_size
1006
+ # const cl_event * : event_wait_list
1007
+ # cl_event * : event
1008
+ def enqueueNDRangeKernel(kernel, work_dim, global_work_offset, global_work_size, local_work_size, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
1009
+ event_buf = event == nil ? nil : ' ' * 8
1010
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
1011
+
1012
+ global_work_offset_buf = global_work_offset == nil ? nil : global_work_offset.pack("Q*")
1013
+ local_work_size_buf = local_work_size == nil ? nil : local_work_size.pack("Q*")
1014
+
1015
+ err = OpenCL.clEnqueueNDRangeKernel(command_queue, kernel, work_dim, global_work_offset_buf, global_work_size.pack("Q*"), local_work_size_buf, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
1016
+ error_info << err if error_info != nil
1017
+
1018
+ event << event_buf.unpack("Q")[0] if event != nil
1019
+ return err
1020
+ end
1021
+
1022
+ # cl_command_queue : command_queue
1023
+ # cl_kernel : kernel
1024
+ # const cl_event * : event_wait_list
1025
+ # cl_event * : event
1026
+ def enqueueTask(kernel, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
1027
+ event_buf = event == nil ? nil : ' ' * 8
1028
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
1029
+
1030
+ err = OpenCL.clEnqueueTask(command_queue, kernel, num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
1031
+ error_info << err if error_info != nil
1032
+
1033
+ event << event_buf.unpack("Q")[0] if event != nil
1034
+ return err
1035
+ end
1036
+
1037
+ # cl_command_queue : command_queue
1038
+ # const cl_mem * : mem_objects
1039
+ # const cl_event * : event_wait_list
1040
+ # cl_event * : event
1041
+ def enqueueAcquireGLObjects(mem_objects, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
1042
+ event_buf = event == nil ? nil : ' ' * 8
1043
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
1044
+
1045
+ err = OpenCL.clEnqueueAcquireGLObjects(command_queue, mem_objects.length, mem_objects.pack("Q*"), num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
1046
+ error_info << err if error_info != nil
1047
+
1048
+ event << event_buf.unpack("Q")[0] if event != nil
1049
+ return err
1050
+ end
1051
+
1052
+ # cl_command_queue : command_queue
1053
+ # const cl_mem * : mem_objects
1054
+ # const cl_event * : event_wait_list
1055
+ # cl_event * : event
1056
+ def enqueueReleaseGLObjects(mem_objects, command_queue: @command_queue, event_wait_list: nil, event: nil, error_info: nil)
1057
+ event_buf = event == nil ? nil : ' ' * 8
1058
+ num_events_in_wait_list = event_wait_list == nil ? 0 : event_wait_list.length
1059
+
1060
+ err = OpenCL.clEnqueueReleaseGLObjects(command_queue, mem_objects.length, mem_objects.pack("Q*"), num_events_in_wait_list, event_wait_list == nil ? nil : event_wait_list.pack("Q"), event_buf)
1061
+ error_info << err if error_info != nil
1062
+
1063
+ event << event_buf.unpack("Q")[0] if event != nil
1064
+ return err
1065
+ end
1066
+ end
1067
+
1068
+ ################################################################################
1069
+
1070
+ class CLUProgram
1071
+ attr_reader :program # cl_program
1072
+
1073
+ def initialize
1074
+ @program = nil
1075
+ end
1076
+
1077
+ # cl_context : context
1078
+ # const char ** : strings
1079
+ def createProgramWithSource(context, strings, error_info: nil)
1080
+ # cl_uint : count
1081
+ # const size_t * : lengths
1082
+ # cl_int * : errcode_ret
1083
+ errcode_ret_buf = ' ' * 4
1084
+ count = strings.length
1085
+ lengthes = strings.collect {|src| src.length}
1086
+
1087
+ program = OpenCL.clCreateProgramWithSource(context, count, strings.pack("p*"), lengthes.pack("Q*"), errcode_ret_buf)
1088
+ errcode_ret = errcode_ret_buf.unpack("l")[0]
1089
+ error_info << errcode_ret if error_info != nil
1090
+
1091
+ if errcode_ret == OpenCL::CL_SUCCESS
1092
+ @program = program
1093
+ return @program
1094
+ else
1095
+ return nil
1096
+ end
1097
+ end
1098
+
1099
+ def self.newProgramWithSource(context, strings, error_info: nil)
1100
+ obj = CLUProgram.new
1101
+ ret = obj.createProgramWithSource(context, strings, error_info: error_info)
1102
+ return ret == nil ? nil : obj
1103
+ end
1104
+
1105
+ # cl_program : program
1106
+ def retainProgram(program: @program)
1107
+ return OpenCL.clRetainProgram(program)
1108
+ end
1109
+
1110
+ # cl_program : program
1111
+ def releaseProgram(program: @program)
1112
+ return OpenCL.clReleaseProgram(program)
1113
+ end
1114
+
1115
+ # cl_program : program
1116
+ # const cl_device_id * : device_list
1117
+ # const char * : options
1118
+ # void * : pfn_notify(cl_program, void*)
1119
+ # void * : user_data
1120
+ def buildProgram(device_list, program: @program, options: nil, pfn_notify: nil, user_data: nil, error_info: nil)
1121
+ num_devices = device_list.length
1122
+ err = OpenCL.clBuildProgram(program, num_devices, device_list.pack("Q*"), options, pfn_notify, user_data)
1123
+
1124
+ if err < 0 && error_info != nil
1125
+ log_size_buf = ' ' * 4
1126
+ OpenCL.clGetProgramBuildInfo(program, device_list[0], OpenCL::CL_PROGRAM_BUILD_LOG, 0, nil, log_size_buf)
1127
+ log_size = log_size_buf.unpack("L")[0]
1128
+ program_log = ' ' * log_size
1129
+ OpenCL.clGetProgramBuildInfo(program, device_list[0], OpenCL::CL_PROGRAM_BUILD_LOG, log_size, program_log, nil)
1130
+
1131
+ error_info << program_log
1132
+ end
1133
+
1134
+ return err
1135
+ end
1136
+ end
1137
+
1138
+ ################################################################################
1139
+
1140
+ class CLUKernel
1141
+ attr_reader :kernel, :name # cl_kernel and the name of '__kernel' entry point
1142
+
1143
+ def initialize
1144
+ @kernel = nil
1145
+ @name = nil
1146
+ end
1147
+
1148
+ # cl_program : program
1149
+ # const char * : kernel_name
1150
+ def createKernel(program, kernel_name, error_info: nil)
1151
+ errcode_ret_buf = ' ' * 4
1152
+ kernel = OpenCL.clCreateKernel(program, kernel_name, errcode_ret_buf)
1153
+ errcode_ret = errcode_ret_buf.unpack("l")[0]
1154
+ error_info << errcode_ret if error_info != nil
1155
+
1156
+ if errcode_ret == OpenCL::CL_SUCCESS
1157
+ @kernel = kernel
1158
+ @name = kernel_name
1159
+ return @kernel
1160
+ else
1161
+ return nil
1162
+ end
1163
+ end
1164
+
1165
+ def self.newKernel(program, kernel_name, error_info: nil)
1166
+ obj = CLUKernel.new
1167
+ ret = obj.createKernel(program, kernel_name, error_info: error_info)
1168
+ return ret == nil ? nil : obj
1169
+ end
1170
+
1171
+ # cl_kernel : kernel
1172
+ # cl_kernel_info : param_name
1173
+ def getKernelInfo(param_name, kernel: @kernel, error_info: nil)
1174
+ # size_t : param_value_size
1175
+ # void * : param_value
1176
+ # size_t * : param_value_size_ret
1177
+ param_value_buf_length = 1024
1178
+ param_value_buf = ' ' * param_value_buf_length
1179
+ param_value_size_ret_buf = ' ' * 4
1180
+
1181
+ err = OpenCL.clGetKernelInfo(kernel, param_name, param_value_buf_length, param_value_buf, param_value_size_ret_buf)
1182
+ error_info << err if error_info != nil
1183
+
1184
+ param_value_size_ret = param_value_size_ret_buf.unpack("L")[0]
1185
+
1186
+ unpack_format = @@kernel_info_param2unpack[param_name]
1187
+ case unpack_format
1188
+ when "char[]"
1189
+ return param_value_buf[0...(param_value_size_ret-1)]
1190
+ else
1191
+ return param_value_buf.unpack(unpack_format)[0]
1192
+ end
1193
+ end
1194
+
1195
+ @@kernel_info_param2unpack = {
1196
+ OpenCL::CL_KERNEL_FUNCTION_NAME => "char[]",
1197
+ OpenCL::CL_KERNEL_NUM_ARGS => "L",
1198
+ OpenCL::CL_KERNEL_REFERENCE_COUNT => "L",
1199
+ OpenCL::CL_KERNEL_CONTEXT => "Q",
1200
+ OpenCL::CL_KERNEL_PROGRAM => "Q",
1201
+ OpenCL::CL_KERNEL_ATTRIBUTES => "char[]",
1202
+ }
1203
+
1204
+ # cl_kernel : kernel
1205
+ def retainKernel(kernel: @kernel)
1206
+ return OpenCL.clRetainKernel(kernel)
1207
+ end
1208
+
1209
+ # cl_kernel : kernel
1210
+ def releaseKernel(kernel: @kernel)
1211
+ return OpenCL.clReleaseKernel(kernel)
1212
+ end
1213
+
1214
+ def sizeof_type(fiddle_type)
1215
+ size = 0
1216
+
1217
+ case fiddle_type
1218
+ when Fiddle::TYPE_VOIDP
1219
+ size = Fiddle::SIZEOF_VOIDP
1220
+ when Fiddle::TYPE_CHAR, -Fiddle::TYPE_CHAR
1221
+ size = Fiddle::SIZEOF_CHAR
1222
+ when Fiddle::TYPE_SHORT, -Fiddle::TYPE_SHORT
1223
+ size = Fiddle::SIZEOF_SHORT
1224
+ when Fiddle::TYPE_INT, -Fiddle::TYPE_INT
1225
+ size = Fiddle::SIZEOF_INT
1226
+ when Fiddle::TYPE_LONG, -Fiddle::TYPE_LONG
1227
+ size = Fiddle::SIZEOF_LONG
1228
+ when Fiddle::TYPE_FLOAT
1229
+ size = Fiddle::SIZEOF_FLOAT
1230
+ when Fiddle::TYPE_DOUBLE
1231
+ size = Fiddle::SIZEOF_DOUBLE
1232
+ when Fiddle::TYPE_SIZE_T
1233
+ size = Fiddle::SIZEOF_SIZE_T
1234
+ when Fiddle::TYPE_SSIZE_T
1235
+ size = Fiddle::SIZEOF_SSIZE_T
1236
+ when Fiddle::TYPE_PTRDIFF_T
1237
+ size = Fiddle::SIZEOF_PTRDIFF_T
1238
+ when Fiddle::TYPE_INTPTR_T
1239
+ size = Fiddle::SIZEOF_INTPTR_T
1240
+ when Fiddle::TYPE_UINTPTR_T
1241
+ size = Fiddle::SIZEOF_UINTPTR_T
1242
+ end
1243
+
1244
+ if Fiddle.const_defined?(:TYPE_LONG_LONG) && (fiddle_type == Fiddle::TYPE_LONG_LONG || fiddle_type == -Fiddle::TYPE_LONG_LONG)
1245
+ size = Fiddle::SIZEOF_LONG_LONG
1246
+ end
1247
+
1248
+ return size
1249
+ end
1250
+ private :sizeof_type
1251
+
1252
+ def pack_format(fiddle_type)
1253
+ format = ""
1254
+
1255
+ case fiddle_type
1256
+ when Fiddle::TYPE_VOIDP
1257
+ format = (Fiddle.const_defined?(:TYPE_LONG_LONG) && (Fiddle::SIZEOF_VOIDP == Fiddle::SIZEOF_LONG_LONG)) ? "Q" : "L"
1258
+
1259
+ when Fiddle::TYPE_CHAR, -Fiddle::TYPE_CHAR
1260
+ format = fiddle_type > 0 ? "c" : "C"
1261
+
1262
+ when Fiddle::TYPE_SHORT, -Fiddle::TYPE_SHORT
1263
+ format = fiddle_type > 0 ? "s" : "S"
1264
+
1265
+ when Fiddle::TYPE_INT, -Fiddle::TYPE_INT
1266
+ format = fiddle_type > 0 ? "i" : "I"
1267
+
1268
+ when Fiddle::TYPE_LONG, -Fiddle::TYPE_LONG
1269
+ format = fiddle_type > 0 ? "l" : "L"
1270
+
1271
+ when Fiddle::TYPE_FLOAT
1272
+ format = "F"
1273
+
1274
+ when Fiddle::TYPE_DOUBLE
1275
+ format = "D"
1276
+
1277
+ when Fiddle::TYPE_SIZE_T, Fiddle::TYPE_UINTPTR_T
1278
+ size = sizeof_type(fiddle_type)
1279
+ case size
1280
+ when Fiddle::SIZEOF_INT
1281
+ format = "I"
1282
+ when Fiddle::SIZEOF_LONG
1283
+ format = "L"
1284
+ else
1285
+ if Fiddle.const_defined?(:TYPE_LONG_LONG) && size == Fiddle::SIZEOF_LONG_LONG
1286
+ format = "Q"
1287
+ end
1288
+ end
1289
+
1290
+ when Fiddle::TYPE_SSIZE_T, Fiddle::TYPE_PTRDIFF_T, Fiddle::TYPE_INTPTR_T
1291
+ size = sizeof_type(fiddle_type)
1292
+ case size
1293
+ when Fiddle::SIZEOF_INT
1294
+ format = "i"
1295
+ when Fiddle::SIZEOF_LONG
1296
+ format = "l"
1297
+ else
1298
+ if Fiddle.const_defined?(:TYPE_LONG_LONG) && size == Fiddle::SIZEOF_LONG_LONG
1299
+ format = "q"
1300
+ end
1301
+ end
1302
+ end
1303
+
1304
+ if Fiddle.const_defined?(:TYPE_LONG_LONG) && (fiddle_type == Fiddle::TYPE_LONG_LONG || fiddle_type == -Fiddle::TYPE_LONG_LONG)
1305
+ format = fiddle_type > 0 ? "q" : "Q"
1306
+ end
1307
+
1308
+ return format
1309
+ end
1310
+ private :sizeof_type
1311
+
1312
+ # cl_kernel : kernel
1313
+ # cl_uint : arg_index
1314
+ # Fiddle::TYPE_VOIDP, etc. : arg_type
1315
+ # const void * : arg_value
1316
+ def setKernelArg(arg_index, arg_type, arg_value, kernel: @kernel)
1317
+ num_elements = arg_value.length
1318
+ arg_size = sizeof_type(arg_type) * num_elements
1319
+ pack_arg = pack_format(arg_type) + num_elements.to_s
1320
+
1321
+ return OpenCL.clSetKernelArg(kernel, arg_index, arg_size, arg_value.pack(pack_arg))
1322
+ end
1323
+
1324
+ # cl_kernel : kernel
1325
+ # cl_uint : arg_indx
1326
+ # cl_kernel_info : param_name
1327
+ def getKernelArgInfo(arg_index, param_name, kernel: @kernel, error_info: nil)
1328
+ # size_t : param_value_size
1329
+ # void * : param_value
1330
+ # size_t * : param_value_size_ret
1331
+ param_value_buf_length = 1024
1332
+ param_value_buf = ' ' * param_value_buf_length
1333
+ param_value_size_ret_buf = ' ' * 4
1334
+
1335
+ err = OpenCL.clGetKernelArgInfo(kernel, arg_index, param_name, param_value_buf_length, param_value_buf, param_value_size_ret_buf)
1336
+ error_info << err if error_info != nil
1337
+ param_value_size_ret = param_value_size_ret_buf.unpack("L")[0]
1338
+
1339
+ unpack_format = @@kernel_arginfo_param2unpack[param_name]
1340
+ case unpack_format
1341
+ when "char[]"
1342
+ return param_value_buf[0...(param_value_size_ret-1)]
1343
+ else
1344
+ return param_value_buf.unpack(unpack_format)[0]
1345
+ end
1346
+ end
1347
+
1348
+ @@kernel_arginfo_param2unpack = {
1349
+ OpenCL::CL_KERNEL_ARG_ADDRESS_QUALIFIER => "L",
1350
+ OpenCL::CL_KERNEL_ARG_ACCESS_QUALIFIER => "L",
1351
+ OpenCL::CL_KERNEL_ARG_TYPE_NAME => "char[]",
1352
+ OpenCL::CL_KERNEL_ARG_TYPE_QUALIFIER => "L",
1353
+ OpenCL::CL_KERNEL_ARG_NAME => "char[]",
1354
+ }
1355
+
1356
+ # cl_kernel : kernel
1357
+ # cl_device_id : device
1358
+ # cl_kernel_work_group_info : param_name
1359
+ def getKernelWorkGroupInfo(param_name, device, kernel: @kernel, error_info: nil)
1360
+ # size_t : param_value_size
1361
+ # void * : param_value
1362
+ # size_t * : param_value_size_ret
1363
+ param_value_buf_length = 1024
1364
+ param_value_buf = ' ' * param_value_buf_length
1365
+ param_value_size_ret_buf = ' ' * 4
1366
+
1367
+ err = OpenCL.clGetKernelWorkGroupInfo(kernel, device, param_name, param_value_buf_length, param_value_buf, param_value_size_ret_buf)
1368
+ error_info << err if error_info != nil
1369
+ param_value_size_ret = param_value_size_ret_buf.unpack("L")[0]
1370
+
1371
+ unpack_format = @@kernel_workgroupinfo_param2unpack[param_name]
1372
+ case unpack_format
1373
+ when "Q3"
1374
+ # Ref.: https://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clGetKernelWorkGroupInfo.html
1375
+ # CL_INVALID_VALUE if param_name is CL_KERNEL_GLOBAL_WORK_SIZE and device
1376
+ # is not a custom device or kernel is not a built-in kernel.
1377
+ if param_name == OpenCL::CL_KERNEL_GLOBAL_WORK_SIZE && err == OpenCL::CL_INVALID_VALUE
1378
+ return [0, 0, 0]
1379
+ else
1380
+ return param_value_buf.unpack(unpack_format)
1381
+ end
1382
+ else
1383
+ return param_value_buf.unpack(unpack_format)[0]
1384
+ end
1385
+ end
1386
+
1387
+ @@kernel_workgroupinfo_param2unpack = {
1388
+ OpenCL::CL_KERNEL_GLOBAL_WORK_SIZE => "Q3",
1389
+ OpenCL::CL_KERNEL_WORK_GROUP_SIZE => "Q",
1390
+ OpenCL::CL_KERNEL_COMPILE_WORK_GROUP_SIZE => "Q3",
1391
+ OpenCL::CL_KERNEL_LOCAL_MEM_SIZE => "Q",
1392
+ OpenCL::CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE => "Q",
1393
+ OpenCL::CL_KERNEL_PRIVATE_MEM_SIZE => "Q",
1394
+ }
1395
+ end
1396
+
1397
+ ################################################################################
1398
+
1399
+ class CLU
1400
+
1401
+ @@image_format = {
1402
+ # cl_channel_order
1403
+ OpenCL::CL_R => "CL_R",
1404
+ OpenCL::CL_A => "CL_A",
1405
+ OpenCL::CL_RG => "CL_RG",
1406
+ OpenCL::CL_RA => "CL_RA",
1407
+ OpenCL::CL_RGB => "CL_RGB",
1408
+ OpenCL::CL_RGBA => "CL_RGBA",
1409
+ OpenCL::CL_BGRA => "CL_BGRA",
1410
+ OpenCL::CL_ARGB => "CL_ARGB",
1411
+ OpenCL::CL_INTENSITY => "CL_INTENSITY",
1412
+ OpenCL::CL_LUMINANCE => "CL_LUMINANCE",
1413
+ OpenCL::CL_Rx => "CL_Rx",
1414
+ OpenCL::CL_RGx => "CL_RGx",
1415
+ OpenCL::CL_RGBx => "CL_RGBx",
1416
+ OpenCL::CL_DEPTH => "CL_DEPTH",
1417
+ OpenCL::CL_DEPTH_STENCIL => "CL_DEPTH_STENCIL",
1418
+
1419
+ # cl_channel_type
1420
+ OpenCL::CL_SNORM_INT8 => "CL_SNORM_INT8",
1421
+ OpenCL::CL_SNORM_INT16 => "CL_SNORM_INT16",
1422
+ OpenCL::CL_UNORM_INT8 => "CL_UNORM_INT8",
1423
+ OpenCL::CL_UNORM_INT16 => "CL_UNORM_INT16",
1424
+ OpenCL::CL_UNORM_SHORT_565 => "CL_UNORM_SHORT_565",
1425
+ OpenCL::CL_UNORM_SHORT_555 => "CL_UNORM_SHORT_555",
1426
+ OpenCL::CL_UNORM_INT_101010 => "CL_UNORM_INT_101010",
1427
+ OpenCL::CL_SIGNED_INT8 => "CL_SIGNED_INT8",
1428
+ OpenCL::CL_SIGNED_INT16 => "CL_SIGNED_INT16",
1429
+ OpenCL::CL_SIGNED_INT32 => "CL_SIGNED_INT32",
1430
+ OpenCL::CL_UNSIGNED_INT8 => "CL_UNSIGNED_INT8",
1431
+ OpenCL::CL_UNSIGNED_INT16 => "CL_UNSIGNED_INT16",
1432
+ OpenCL::CL_UNSIGNED_INT32 => "CL_UNSIGNED_INT32",
1433
+ OpenCL::CL_HALF_FLOAT => "CL_HALF_FLOAT",
1434
+ OpenCL::CL_FLOAT => "CL_FLOAT",
1435
+ OpenCL::CL_UNORM_INT24 => "CL_UNORM_INT24",
1436
+
1437
+ # 0x10000012 : ABGR and xBGR formats for CoreImage CL-GPU support (from /OpenCL.framework/Headers/cl_ext.h)
1438
+ OpenCL::CL_ABGR_APPLE => "CL_ABGR_APPLE"
1439
+ }
1440
+
1441
+ def self.getImageFormatString(image_channel)
1442
+ return @@image_format.has_key?(image_channel) ? @@image_format[image_channel] : image_channel.to_s
1443
+ end
1444
+ end
1445
+
1446
+ ################################################################################
1447
+
1448
+ =begin
1449
+ Ruby-OpenCL : Yet another OpenCL wrapper for Ruby
1450
+ Copyright (c) 2015 vaiorabbit <http://twitter.com/vaiorabbit>
1451
+
1452
+ This software is provided 'as-is', without any express or implied
1453
+ warranty. In no event will the authors be held liable for any damages
1454
+ arising from the use of this software.
1455
+
1456
+ Permission is granted to anyone to use this software for any purpose,
1457
+ including commercial applications, and to alter it and redistribute it
1458
+ freely, subject to the following restrictions:
1459
+
1460
+ 1. The origin of this software must not be misrepresented; you must not
1461
+ claim that you wrote the original software. If you use this software
1462
+ in a product, an acknowledgment in the product documentation would be
1463
+ appreciated but is not required.
1464
+
1465
+ 2. Altered source versions must be plainly marked as such, and must not be
1466
+ misrepresented as being the original software.
1467
+
1468
+ 3. This notice may not be removed or altered from any source
1469
+ distribution.
1470
+ =end