opencl_ruby_ffi 1.3.4 → 1.3.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -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