opencl_ruby_ffi 1.3.4 → 1.3.9

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,
@@ -284,27 +376,156 @@ module OpenCL
284
376
  include InnerInterface
285
377
  end
286
378
 
379
+ module ExtensionInnerGenerator
380
+
381
+ private
382
+
383
+ # @!macro [attach] get_info_ext
384
+ # @!method $3
385
+ # Returns the OpenCL::$1::$3 info
386
+ # @return $2
387
+ def get_info_ext(klass, type, name, function, memoizable = false)
388
+ if memoizable
389
+ s = <<EOF
390
+ def #{name.downcase}
391
+ return @_#{name.downcase} if @_#{name.downcase}
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
+ @_#{name.downcase} = convert_type(:#{type})::new(ptr2.read_#{type})
403
+ else
404
+ @_#{name.downcase} = ptr2.read_#{type}
405
+ end
406
+ return @_#{name.downcase}
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])
413
+ error_check(OpenCL::INVALID_OPERATION) unless f
414
+
415
+ ptr1 = MemoryPointer::new(:size_t, 1)
416
+ error = f.call(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
417
+ error_check(error)
418
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
419
+ error = f.call(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
420
+ error_check(error)
421
+ if(convert_type(:#{type})) then
422
+ return convert_type(:#{type})::new(ptr2.read_#{type})
423
+ else
424
+ return ptr2.read_#{type}
425
+ end
426
+ end
427
+ EOF
428
+ end
429
+ if type == :cl_bool then
430
+ s += <<EOF
431
+ def #{name.downcase}?
432
+ #{name.downcase} == 0 ? false : true
433
+ end
434
+ EOF
435
+ end
436
+ module_eval s
437
+ end
438
+
439
+ # @!macro [attach] get_info_array_ext
440
+ # @!method $3
441
+ # Returns the OpenCL::$1::$3 info
442
+ # @return an Array of $2
443
+ def get_info_array_ext(klass, type, name, function, memoizable = false)
444
+ if memoizable
445
+ s = <<EOF
446
+ def #{name.downcase}
447
+ return @_#{name.downcase} if @_#{name.downcase}
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
+ @_#{name.downcase} = arr.collect { |e| convert_type(:#{type})::new(e) }
460
+ else
461
+ @_#{name.downcase} = arr
462
+ end
463
+ return @_#{name.downcase}
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])
470
+ error_check(OpenCL::INVALID_OPERATION) unless f
471
+
472
+ ptr1 = MemoryPointer::new(:size_t, 1)
473
+ error = f.call(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
474
+ error_check(error)
475
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
476
+ error = f.call(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
477
+ error_check(error)
478
+ arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t / OpenCL.find_type(:#{type}).size)
479
+ if(convert_type(:#{type})) then
480
+ return arr.collect { |e| convert_type(:#{type})::new(e) }
481
+ else
482
+ return arr
483
+ end
484
+ end
485
+ EOF
486
+ end
487
+ module_eval s
488
+ end
489
+
490
+ end
491
+ private_constant :ExtensionInnerGenerator
492
+
287
493
  module InnerGenerator
288
494
 
289
495
  private
290
496
 
291
- # 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.
292
- # @param [String] klass the property is to be found
293
- # @param [Symbol] type of the property
294
- # @param [String] name of the property
295
497
  # @!macro [attach] get_info
296
498
  # @!method $3
297
499
  # Returns the OpenCL::$1::$3 info
298
500
  # @return $2
299
- def get_info(klass, type, name)
501
+ def get_info(klass, type, name, memoizable = false)
300
502
  klass_name = klass
301
503
  klass_name = "MemObject" if klass == "Mem"
504
+ if memoizable
505
+ s = <<EOF
506
+ def #{name.downcase}
507
+ return @_#{name.downcase} if @_#{name.downcase}
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
+ @_#{name.downcase} = convert_type(:#{type})::new(ptr2.read_#{type})
516
+ else
517
+ @_#{name.downcase} = ptr2.read_#{type}
518
+ end
519
+ return @_#{name.downcase}
520
+ end
521
+ EOF
522
+ else
302
523
  s = <<EOF
303
524
  def #{name.downcase}
304
- ptr1 = MemoryPointer::new( :size_t, 1)
525
+ ptr1 = MemoryPointer::new(:size_t, 1)
305
526
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
306
527
  error_check(error)
307
- ptr2 = MemoryPointer::new( ptr1.read_size_t )
528
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
308
529
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
309
530
  error_check(error)
310
531
  if(convert_type(:#{type})) then
@@ -314,6 +535,7 @@ module OpenCL
314
535
  end
315
536
  end
316
537
  EOF
538
+ end
317
539
  if type == :cl_bool then
318
540
  s += <<EOF
319
541
  def #{name.downcase}?
@@ -324,26 +546,42 @@ EOF
324
546
  module_eval s
325
547
  end
326
548
 
327
- # 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.
328
- # @param [String] klass the property is to be found
329
- # @param [Symbol] type of the property
330
- # @param [String] name of the property
331
549
  # @!macro [attach] get_info_array
332
550
  # @!method $3
333
551
  # Returns the OpenCL::$1::$3 info
334
552
  # @return an Array of $2
335
- def get_info_array(klass, type, name)
553
+ def get_info_array(klass, type, name, memoizable = false)
336
554
  klass_name = klass
337
555
  klass_name = "MemObject" if klass == "Mem"
338
- s = <<EOF
556
+ if memoizable
557
+ s = <<EOF
339
558
  def #{name.downcase}
340
- ptr1 = MemoryPointer::new( :size_t, 1)
559
+ return @_#{name.downcase} if @_#{name.downcase}
560
+ ptr1 = MemoryPointer::new(:size_t, 1)
341
561
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
342
562
  error_check(error)
343
- ptr2 = MemoryPointer::new( ptr1.read_size_t )
563
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
344
564
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
345
565
  error_check(error)
346
- arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t/ OpenCL.find_type(:#{type}).size)
566
+ arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t / OpenCL.find_type(:#{type}).size)
567
+ if(convert_type(:#{type})) then
568
+ @_#{name.downcase} = arr.collect { |e| convert_type(:#{type})::new(e) }
569
+ else
570
+ @_#{name.downcase} = arr
571
+ end
572
+ return @_#{name.downcase}
573
+ end
574
+ EOF
575
+ else
576
+ s = <<EOF
577
+ def #{name.downcase}
578
+ ptr1 = MemoryPointer::new(:size_t, 1)
579
+ error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, 0, nil, ptr1)
580
+ error_check(error)
581
+ ptr2 = MemoryPointer::new(ptr1.read_size_t)
582
+ error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name.upcase}, ptr1.read_size_t, ptr2, nil)
583
+ error_check(error)
584
+ arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t / OpenCL.find_type(:#{type}).size)
347
585
  if(convert_type(:#{type})) then
348
586
  return arr.collect { |e| convert_type(:#{type})::new(e) }
349
587
  else
@@ -351,6 +589,7 @@ EOF
351
589
  end
352
590
  end
353
591
  EOF
592
+ end
354
593
  module_eval s
355
594
  end
356
595