opencl-bindings 1.0.0pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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