opencl_ruby_ffi 1.3.6 → 1.3.11

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.
@@ -0,0 +1,95 @@
1
+ if RUBY_VERSION.scan(/\d+/).collect(&:to_i).first >= 2
2
+ using OpenCLRefinements
3
+ end
4
+
5
+ module OpenCL
6
+
7
+ # Unofficial kernel profiling extension
8
+ CONTEXT_KERNEL_PROFILING_MODES_COUNT_INTEL = 0x407A
9
+ CONTEXT_KERNEL_PROFILING_MODE_INFO_INTEL = 0x407B
10
+ KERNEL_IL_SYMBOLS_INTEL = 0x407C
11
+ KERNEL_BINARY_PROGRAM_INTEL = 0x407D
12
+ # Unofficial VTune Debug Info extension
13
+ PROGRAM_DEBUG_INFO_INTEL = 0x4100
14
+ PROGRAM_DEBUG_INFO_SIZES_INTEL = 0x4101
15
+ KERNEL_BINARIES_INTEL = 0x4102
16
+ KERNEL_BINARY_SIZES_INTEL = 0x4103
17
+
18
+ class Kernel
19
+ IL_SYMBOLS_INTEL = 0x407C
20
+ BINARY_PROGRAM_INTEL = 0x407D
21
+ BINARIES_INTEL = 0x4102
22
+ BINARY_SIZES_INTEL = 0x4103
23
+
24
+ def binary_program_intel(device = program.devices.first)
25
+ sz = MemoryPointer::new( :size_t )
26
+ begin
27
+ error = OpenCL.clGetKernelWorkGroupInfo(self, device, BINARY_PROGRAM_INTEL, 0, nil, sz)
28
+ error_check(error)
29
+ sz = sz.read_size_t
30
+ bin = MemoryPointer::new(sz)
31
+ error = OpenCL.clGetKernelWorkGroupInfo(self, device, BINARY_PROGRAM_INTEL, sz, bin, nil)
32
+ error_check(error)
33
+ return bin.read_bytes(sz)
34
+ rescue
35
+ error = OpenCL.clGetKernelInfo(self, BINARY_PROGRAM_INTEL, 0, nil, sz)
36
+ error_check(error)
37
+ sz = sz.read_size_t
38
+ bin = MemoryPointer::new(sz)
39
+ error = OpenCL.clGetKernelInfo(self, BINARY_PROGRAM_INTEL, sz, bin, nil)
40
+ error_check(error)
41
+ return bin.read_bytes(sz)
42
+ end
43
+ end
44
+
45
+ get_info_array("Kernel", :size_t, "binary_sizes_intel")
46
+
47
+ def binaries_intel
48
+ sizes = self.binary_sizes_intel
49
+ bin_array = MemoryPointer::new( :pointer, sizes.length )
50
+ total_size = 0
51
+ pointers = []
52
+ sizes.each_with_index { |s, i|
53
+ total_size += s
54
+ pointers[i] = MemoryPointer::new(s)
55
+ bin_array[i].write_pointer(pointers[i])
56
+ }
57
+ error = OpenCL.clGetKernelInfo(self, BINARIES_INTEL, total_size, bin_array, nil)
58
+ error_check(error)
59
+ bins = []
60
+ devs = self.program.devices
61
+ sizes.each_with_index { |s, i|
62
+ bins.push [devs[i], pointers[i].read_bytes(s)]
63
+ }
64
+ return bins
65
+ end
66
+
67
+ end
68
+
69
+ class Program
70
+ DEBUG_INFO_INTEL = 0x4100
71
+ DEBUG_INFO_SIZES_INTEL = 0x4101
72
+
73
+ get_info_array("Program", :size_t, "debug_info_sizes_intel")
74
+
75
+ def debug_info_intel
76
+ sizes = self.debug_info_sizes_intel
77
+ bin_array = MemoryPointer::new( :pointer, sizes.length )
78
+ total_size = 0
79
+ sizes.each_with_index { |s, i|
80
+ total_size += s
81
+ pointers[i] = MemoryPointer::new(s)
82
+ bin_array[i].write_pointer(pointers[i])
83
+ }
84
+ error = OpenCL.clGetProgramInfo(self, DEBUG_INFO_INTEL, total_size, bin_array, nil)
85
+ error_check(error)
86
+ bins = []
87
+ devs = self.devices
88
+ sizes.each_with_index { |s, i|
89
+ bins.push [devs[i], pointers[i].read_bytes(s)]
90
+ }
91
+ return bins
92
+ end
93
+ end
94
+
95
+ end
@@ -0,0 +1,119 @@
1
+ using OpenCLRefinements if RUBY_VERSION.scan(/\d+/).collect(&:to_i).first >= 2
2
+
3
+ module OpenCL
4
+
5
+ UUID_SIZE_KHR = 16
6
+ LUID_SIZE_KHR = 8
7
+
8
+ DEVICE_UUID_KHR = 0x106A
9
+ DRIVER_UUID_KHR = 0x106B
10
+ DEVICE_LUID_VALID_KHR = 0x106C
11
+ DEVICE_LUID_KHR = 0x106D
12
+ DEVICE_NODE_MASK_KHR = 0x106E
13
+
14
+ class UUID < Struct
15
+ layout :id, [ OpenCL.find_type(:cl_uchar), UUID_SIZE_KHR ]
16
+ def to_s
17
+ a = self[:id].to_a
18
+ s = ""
19
+ s << "%02x" % a[15]
20
+ s << "%02x" % a[14]
21
+ s << "%02x" % a[13]
22
+ s << "%02x" % a[12]
23
+ s << "-"
24
+ s << "%02x" % a[11]
25
+ s << "%02x" % a[10]
26
+ s << "-"
27
+ s << "%02x" % a[9]
28
+ s << "%02x" % a[8]
29
+ s << "-"
30
+ s << "%02x" % a[7]
31
+ s << "%02x" % a[6]
32
+ s << "-"
33
+ s << "%02x" % a[5]
34
+ s << "%02x" % a[4]
35
+ s << "%02x" % a[3]
36
+ s << "%02x" % a[2]
37
+ s << "%02x" % a[1]
38
+ s << "%02x" % a[0]
39
+ end
40
+
41
+ def self.from_string(uuid)
42
+ new.from_string(uuid)
43
+ end
44
+
45
+ def from_string(uuid)
46
+ m = uuid.match(/(\h\h)(\h\h)(\h\h)(\h\h)-(\h\h)(\h\h)-(\h\h)(\h\h)-(\h\h)(\h\h)-(\h\h)(\h\h)(\h\h)(\h\h)(\h\h)(\h\h)/)
47
+ raise "invalid format" unless m
48
+ UUID_SIZE_KHR.times { |i|
49
+ self[:id][UUID_SIZE_KHR-1-i] = m[i+1].to_i(16)
50
+ }
51
+ self
52
+ end
53
+ end
54
+
55
+ class LUID < Struct
56
+ layout :id, [ OpenCL.find_type(:cl_uchar), LUID_SIZE_KHR ]
57
+ def to_s
58
+ a = self[:id].to_a
59
+ s = ""
60
+ s << "%02x" % a[7]
61
+ s << "%02x" % a[6]
62
+ s << "%02x" % a[5]
63
+ s << "%02x" % a[4]
64
+ s << "%02x" % a[3]
65
+ s << "%02x" % a[2]
66
+ s << "%02x" % a[1]
67
+ s << "%02x" % a[0]
68
+ end
69
+
70
+ def self.from_string(uuid)
71
+ new.from_string(uuid)
72
+ end
73
+
74
+ def from_string(uuid)
75
+ m = uuid.match(/(\h\h)(\h\h)(\h\h)(\h\h)(\h\h)(\h\h)(\h\h)(\h\h)/)
76
+ raise "invalid format" unless m
77
+ LUID_SIZE_KHR.times { |i|
78
+ self[:id][LUID_SIZE_KHR-1-i] = m[i+1].to_i(16)
79
+ }
80
+ self
81
+ end
82
+ end
83
+
84
+ class Device
85
+ UUID_KHR = 0x106A
86
+ LUID_VALID_KHR = 0x106C
87
+ LUID_KHR = 0x106D
88
+ NODE_MASK_KHR = 0x106E
89
+
90
+ module KHRDeviceUUID
91
+ extend InnerGenerator
92
+ get_info("Device", :cl_bool, "luid_valid_khr")
93
+ get_info("Device", :cl_uint, "node_mask_khr")
94
+
95
+ def uuid_khr
96
+ id = UUID.new
97
+ error = OpenCL.clGetDeviceInfo( self, UUID_KHR, UUID_SIZE_KHR, id, nil)
98
+ error_check(error)
99
+ return id
100
+ end
101
+
102
+ def driver_uuid_khr
103
+ id = UUID.new
104
+ error = OpenCL.clGetDeviceInfo( self, DRIVER_UUID_KHR, UUID_SIZE_KHR, id, nil)
105
+ error_check(error)
106
+ return id
107
+ end
108
+
109
+ def luid_khr
110
+ id = LUID.new
111
+ error = OpenCL.clGetDeviceInfo( self, LUID_KHR, LUID_SIZE_KHR, id, nil)
112
+ error_check(error)
113
+ return id
114
+ end
115
+ end
116
+ register_extension( :cl_khr_device_uuid, KHRDeviceUUID, "extensions.include?(\"cl_khr_device_uuid\")" )
117
+ end
118
+
119
+ end
@@ -35,7 +35,7 @@ module OpenCL
35
35
  class Union < FFI::Union
36
36
  end
37
37
 
38
- @@callbacks = []
38
+ @@callbacks = {}
39
39
 
40
40
  # Maps the :cl_image_fomat type of OpenCL
41
41
  class ImageFormat < Struct
@@ -47,13 +47,13 @@ module OpenCL
47
47
  end
48
48
 
49
49
  # Creates a new ImageFormat from an image channel order and data type
50
- def initialize( image_channel_order, image_channel_data_type = nil )
51
- if image_channel_order.is_a?(FFI::Pointer) and image_channel_data_type.nil? then
50
+ def initialize( image_channel_order = nil, image_channel_data_type = nil )
51
+ if image_channel_order.is_a?(FFI::Pointer) then
52
52
  super(image_channel_order)
53
53
  else
54
54
  super()
55
- self[:image_channel_order] = image_channel_order
56
- self[:image_channel_data_type] = image_channel_data_type
55
+ self[:image_channel_order] = image_channel_order if image_channel_order
56
+ self[:image_channel_data_type] = image_channel_data_type if image_channel_data_type
57
57
  end
58
58
  end
59
59
 
@@ -98,18 +98,22 @@ module OpenCL
98
98
  :buffer, Mem.ptr
99
99
 
100
100
  # Creates anew ImageDesc using the values provided by the user
101
- def initialize( image_type, image_width, image_height, image_depth, image_array_size, image_row_pitch, image_slice_pitch, num_mip_levels, num_samples, buffer )
102
- super()
103
- self[:image_type] = image_type
104
- self[:image_width] = image_width
105
- self[:image_height] = image_height
106
- self[:image_depth] = image_depth
107
- self[:image_array_size] = image_array_size
108
- self[:image_row_pitch] = image_row_pitch
109
- self[:image_slice_pitch] = image_slice_pitch
110
- self[:num_mip_levels] = num_mip_levels
111
- self[:num_samples] = num_samples
112
- self[:buffer] = buffer
101
+ def initialize( image_type = nil, image_width = nil, image_height = nil, image_depth = nil, image_array_size = nil, image_row_pitch = nil, image_slice_pitch = nil, num_mip_levels = nil, num_samples = nil, buffer = nil )
102
+ if (image_type.is_a?(FFI::Pointer))
103
+ super(image_type)
104
+ else
105
+ super()
106
+ self[:image_type] = image_type if image_type
107
+ self[:image_width] = image_width if image_width
108
+ self[:image_height] = image_height if image_height
109
+ self[:image_depth] = image_depth if image_depth
110
+ self[:image_array_size] = image_array_size if image_array_size
111
+ self[:image_row_pitch] = image_row_pitch if image_row_pitch
112
+ self[:image_slice_pitch] = image_slice_pitch if image_slice_pitch
113
+ self[:num_mip_levels] = num_mip_levels if num_mip_levels
114
+ self[:num_samples] = num_samples if num_samples
115
+ self[:buffer] = buffer if buffer
116
+ end
113
117
  end
114
118
  end
115
119
 
@@ -119,10 +123,84 @@ module OpenCL
119
123
  :size, :size_t
120
124
 
121
125
  # Creates a new BufferRegion using the value provided by the user
122
- def initialize( origin, sz )
123
- super()
124
- self[:origin] = origin
125
- self[:size] = sz
126
+ def initialize( origin = nil, sz = nil )
127
+ if (origin.is_a?(FFI::Pointer))
128
+ super(origin)
129
+ else
130
+ super()
131
+ self[:origin] = origin if origin
132
+ self[:size] = sz if sz
133
+ end
134
+ end
135
+ end
136
+
137
+ class Version
138
+ include Comparable
139
+ MAJOR_BITS = 10
140
+ MINOR_BITS = 10
141
+ PATCH_BITS = 12
142
+ MAJOR_MASK = (1 << MAJOR_BITS) - 1
143
+ MINOR_MASK = (1 << MINOR_BITS) - 1
144
+ PATCH_MASK = (1 << PATCH_BITS) - 1
145
+
146
+ attr_reader :major, :minor, :patch
147
+ def initialize(major, minor = 0, patch = 0)
148
+ @major = major
149
+ @minor = minor
150
+ @patch = patch
151
+ end
152
+
153
+ def to_int
154
+ Version.make(@major, @minor, @patch)
155
+ end
156
+ alias to_i to_int
157
+
158
+ def <=>(other)
159
+ res = (@major <=> other.major)
160
+ res = (@minor <=> other.minor) if res == 0
161
+ res = (@patch <=> other.patch) if res == 0
162
+ res
163
+ end
164
+
165
+ def to_s
166
+ "#{@major}.#{@minor}.#{@patch}"
167
+ end
168
+
169
+ def self.major(v)
170
+ v >> (MINOR_BITS + PATCH_BITS)
171
+ end
172
+
173
+ def self.minor(v)
174
+ (v >> (PATCH_BITS)) & MINOR_MASK
175
+ end
176
+
177
+ def self.patch(v)
178
+ v & PATCH_MASK
179
+ end
180
+
181
+ def self.make(major, minor = 0, patch = 0)
182
+ ((major & MAJOR_MASK) << (MINOR_BITS + PATCH_BITS)) +
183
+ ((minor & MINOR_MASK) << PATCH_BITS) +
184
+ (patch & PATCH_MASK)
185
+ end
186
+
187
+ def self.from_int(v)
188
+ self.new(major(v), minor(v), patch(v))
189
+ end
190
+ end
191
+
192
+ # Maps the :cl_name_version type of OpenCL
193
+ class NameVersion < Struct
194
+ MAX_NAME_SIZE = 64
195
+ layout :version, :cl_version,
196
+ :name, [:char, MAX_NAME_SIZE]
197
+
198
+ def version
199
+ Version.from_int(self[:version])
200
+ end
201
+
202
+ def name
203
+ self[:name].to_s
126
204
  end
127
205
  end
128
206
 
@@ -169,7 +247,7 @@ module OpenCL
169
247
  end
170
248
  return properties
171
249
  end
172
-
250
+
173
251
  # Extracts the origin_symbol and region_symbol named options for image from the given hash. Returns the read (or detemined suitable) origin and region in a tuple
174
252
  def get_origin_region( image, options, origin_symbol, region_symbol )
175
253
  origin = MemoryPointer::new( :size_t, 3 )
@@ -214,6 +292,19 @@ module OpenCL
214
292
  return properties
215
293
  end
216
294
 
295
+ # EXtracts the :properties named option (for a Mem) from the hash given and returns the properties values
296
+ def get_mem_properties( options )
297
+ properties = nil
298
+ if options[:properties] then
299
+ properties = MemoryPointer::new( :cl_mem_properties, options[:properties].length + 1 )
300
+ options[:properties].each_with_index { |e,i|
301
+ properties[i].write_cl_mem_properties(e.respond_to?(:to_ptr) ? e : e.to_i)
302
+ }
303
+ properties[options[:properties].length].write_cl_mem_properties(0)
304
+ end
305
+ return properties
306
+ end
307
+
217
308
  # Extracts the :device_list named option from the hash given and returns [ number of devices, an Pointer to the list of Device or nil ]
218
309
  def get_device_list( options )
219
310
  devices = options[:device_list]
@@ -248,6 +339,7 @@ module OpenCL
248
339
  :cl_command_queue_properties => CommandQueue::Properties,
249
340
  :cl_device_affinity_domain => Device::AffinityDomain,
250
341
  :cl_device_svm_capabilities => Device::SVMCapabilities,
342
+ :cl_device_atomic_capabilities => Device::AtomicCapabilities,
251
343
  :cl_channel_order => ChannelOrder,
252
344
  :cl_channel_type => ChannelType,
253
345
  :cl_mem_flags => Mem::Flags,
@@ -287,26 +379,43 @@ module OpenCL
287
379
  module ExtensionInnerGenerator
288
380
 
289
381
  private
290
- # Generates a new method for klass that use the given clGetKlassInfo on the object platform, to read an info of the given type. The info queried is specified by name.
291
- # @param [String] klass the property is to be found
292
- # @param [Symbol] type of the property
293
- # @param [String] name of the property
294
- # @!macro [attach] get_info
382
+
383
+ # @!macro [attach] get_info_ext
295
384
  # @!method $3
296
385
  # Returns the OpenCL::$1::$3 info
297
386
  # @return $2
298
- def get_info_ext(klass, type, name, function)
299
- klass_name = klass
300
- klass_name = "MemObject" if klass == "Mem"
387
+ def get_info_ext(klass, type, name, function, memoizable = false)
388
+ if memoizable
301
389
  s = <<EOF
302
390
  def #{name.downcase}
303
- f = platform.get_extension_function("#{function}", :cl_int, [#{klass_name}, :cl_uint, :size_t, :pointer, :pointer])
391
+ @_#{name.downcase} ||= begin
392
+ f = platform.get_extension_function("#{function}", :cl_int, [#{klass}, :cl_uint, :size_t, :pointer, :pointer])
393
+ error_check(OpenCL::INVALID_OPERATION) unless f
394
+
395
+ ptr1 = MemoryPointer::new(:size_t, 1)
396
+ error = f.call(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
397
+ error_check(error)
398
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
399
+ error = f.call(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
400
+ error_check(error)
401
+ if(convert_type(:#{type})) then
402
+ convert_type(:#{type})::new(ptr2.read_#{type})
403
+ else
404
+ ptr2.read_#{type}
405
+ end
406
+ end
407
+ end
408
+ EOF
409
+ else
410
+ s = <<EOF
411
+ def #{name.downcase}
412
+ f = platform.get_extension_function("#{function}", :cl_int, [#{klass}, :cl_uint, :size_t, :pointer, :pointer])
304
413
  error_check(OpenCL::INVALID_OPERATION) unless f
305
414
 
306
- ptr1 = MemoryPointer::new( :size_t, 1)
415
+ ptr1 = MemoryPointer::new(:size_t, 1)
307
416
  error = f.call(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
308
417
  error_check(error)
309
- ptr2 = MemoryPointer::new( ptr1.read_size_t )
418
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
310
419
  error = f.call(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
311
420
  error_check(error)
312
421
  if(convert_type(:#{type})) then
@@ -316,6 +425,7 @@ module OpenCL
316
425
  end
317
426
  end
318
427
  EOF
428
+ end
319
429
  if type == :cl_bool then
320
430
  s += <<EOF
321
431
  def #{name.downcase}?
@@ -326,29 +436,46 @@ EOF
326
436
  module_eval s
327
437
  end
328
438
 
329
- # Generates a new method for klass that use the apropriate clGetKlassInfo, to read an Array of element of the given type. The info queried is specified by name.
330
- # @param [String] klass the property is to be found
331
- # @param [Symbol] type of the property
332
- # @param [String] name of the property
333
- # @!macro [attach] get_info_array
439
+ # @!macro [attach] get_info_array_ext
334
440
  # @!method $3
335
441
  # Returns the OpenCL::$1::$3 info
336
442
  # @return an Array of $2
337
- def get_info_array_ext(klass, type, name, function)
338
- klass_name = klass
339
- klass_name = "MemObject" if klass == "Mem"
443
+ def get_info_array_ext(klass, type, name, function, memoizable = false)
444
+ if memoizable
340
445
  s = <<EOF
341
446
  def #{name.downcase}
342
- f = platform.get_extension_function("#{function}", :cl_int, [:cl_uint, :size_t, :pointer, :pointer])
447
+ @_#{name.downcase} ||= begin
448
+ f = platform.get_extension_function("#{function}", :cl_int, [#{klass}, :cl_uint, :size_t, :pointer, :pointer])
449
+ error_check(OpenCL::INVALID_OPERATION) unless f
450
+
451
+ ptr1 = MemoryPointer::new(:size_t, 1)
452
+ error = f.call(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
453
+ error_check(error)
454
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
455
+ error = f.call(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
456
+ error_check(error)
457
+ arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t / OpenCL.find_type(:#{type}).size)
458
+ if(convert_type(:#{type})) then
459
+ arr.collect { |e| convert_type(:#{type})::new(e) }
460
+ else
461
+ arr
462
+ end
463
+ end
464
+ end
465
+ EOF
466
+ else
467
+ s = <<EOF
468
+ def #{name.downcase}
469
+ f = platform.get_extension_function("#{function}", :cl_int, [#{klass}, :cl_uint, :size_t, :pointer, :pointer])
343
470
  error_check(OpenCL::INVALID_OPERATION) unless f
344
471
 
345
- ptr1 = MemoryPointer::new( :size_t, 1)
472
+ ptr1 = MemoryPointer::new(:size_t, 1)
346
473
  error = f.call(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
347
474
  error_check(error)
348
- ptr2 = MemoryPointer::new( ptr1.read_size_t )
475
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
349
476
  error = f.call(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
350
477
  error_check(error)
351
- arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t/ OpenCL.find_type(:#{type}).size)
478
+ arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t / OpenCL.find_type(:#{type}).size)
352
479
  if(convert_type(:#{type})) then
353
480
  return arr.collect { |e| convert_type(:#{type})::new(e) }
354
481
  else
@@ -356,6 +483,7 @@ EOF
356
483
  end
357
484
  end
358
485
  EOF
486
+ end
359
487
  module_eval s
360
488
  end
361
489
 
@@ -366,23 +494,38 @@ EOF
366
494
 
367
495
  private
368
496
 
369
- # Generates a new method for klass that use the apropriate clGetKlassInfo, to read an info of the given type. The info queried is specified by name.
370
- # @param [String] klass the property is to be found
371
- # @param [Symbol] type of the property
372
- # @param [String] name of the property
373
497
  # @!macro [attach] get_info
374
498
  # @!method $3
375
499
  # Returns the OpenCL::$1::$3 info
376
500
  # @return $2
377
- def get_info(klass, type, name)
501
+ def get_info(klass, type, name, memoizable = false)
378
502
  klass_name = klass
379
503
  klass_name = "MemObject" if klass == "Mem"
504
+ if memoizable
505
+ s = <<EOF
506
+ def #{name.downcase}
507
+ @_#{name.downcase} ||= begin
508
+ ptr1 = MemoryPointer::new(:size_t, 1)
509
+ error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
510
+ error_check(error)
511
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
512
+ error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
513
+ error_check(error)
514
+ if(convert_type(:#{type})) then
515
+ convert_type(:#{type})::new(ptr2.read_#{type})
516
+ else
517
+ ptr2.read_#{type}
518
+ end
519
+ end
520
+ end
521
+ EOF
522
+ else
380
523
  s = <<EOF
381
524
  def #{name.downcase}
382
- ptr1 = MemoryPointer::new( :size_t, 1)
525
+ ptr1 = MemoryPointer::new(:size_t, 1)
383
526
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
384
527
  error_check(error)
385
- ptr2 = MemoryPointer::new( ptr1.read_size_t )
528
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
386
529
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
387
530
  error_check(error)
388
531
  if(convert_type(:#{type})) then
@@ -392,6 +535,7 @@ EOF
392
535
  end
393
536
  end
394
537
  EOF
538
+ end
395
539
  if type == :cl_bool then
396
540
  s += <<EOF
397
541
  def #{name.downcase}?
@@ -402,26 +546,42 @@ EOF
402
546
  module_eval s
403
547
  end
404
548
 
405
- # Generates a new method for klass that use the apropriate clGetKlassInfo, to read an Array of element of the given type. The info queried is specified by name.
406
- # @param [String] klass the property is to be found
407
- # @param [Symbol] type of the property
408
- # @param [String] name of the property
409
549
  # @!macro [attach] get_info_array
410
550
  # @!method $3
411
551
  # Returns the OpenCL::$1::$3 info
412
552
  # @return an Array of $2
413
- def get_info_array(klass, type, name)
553
+ def get_info_array(klass, type, name, memoizable = false)
414
554
  klass_name = klass
415
555
  klass_name = "MemObject" if klass == "Mem"
416
- s = <<EOF
556
+ if memoizable
557
+ s = <<EOF
417
558
  def #{name.downcase}
418
- ptr1 = MemoryPointer::new( :size_t, 1)
559
+ @_#{name.downcase} ||= begin
560
+ ptr1 = MemoryPointer::new(:size_t, 1)
561
+ error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
562
+ error_check(error)
563
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
564
+ error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
565
+ error_check(error)
566
+ arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t / OpenCL.find_type(:#{type}).size)
567
+ if(convert_type(:#{type})) then
568
+ arr.collect { |e| convert_type(:#{type})::new(e) }
569
+ else
570
+ arr
571
+ end
572
+ end
573
+ end
574
+ EOF
575
+ else
576
+ s = <<EOF
577
+ def #{name.downcase}
578
+ ptr1 = MemoryPointer::new(:size_t, 1)
419
579
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
420
580
  error_check(error)
421
- ptr2 = MemoryPointer::new( ptr1.read_size_t )
581
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
422
582
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
423
583
  error_check(error)
424
- arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t/ OpenCL.find_type(:#{type}).size)
584
+ arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t / OpenCL.find_type(:#{type}).size)
425
585
  if(convert_type(:#{type})) then
426
586
  return arr.collect { |e| convert_type(:#{type})::new(e) }
427
587
  else
@@ -429,6 +589,7 @@ EOF
429
589
  end
430
590
  end
431
591
  EOF
592
+ end
432
593
  module_eval s
433
594
  end
434
595