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.
@@ -77,23 +77,31 @@ module OpenCL
77
77
 
78
78
  # Returns the CommandQueue associated with the Event, if it exists
79
79
  def command_queue
80
+ return @_command_queue if @_command_queue
80
81
  ptr = MemoryPointer::new( CommandQueue )
81
82
  error = OpenCL.clGetEventInfo(self, COMMAND_QUEUE, CommandQueue.size, ptr, nil)
82
83
  error_check(error)
83
84
  pt = ptr.read_pointer
84
85
  if pt.null? then
85
- return nil
86
+ @_command_queue = nil
86
87
  else
87
- return CommandQueue::new( pt )
88
+ @_command_queue = CommandQueue::new( pt )
88
89
  end
90
+ @_command_queue
89
91
  end
90
92
 
91
- get_info("Event", :cl_command_type, "command_type")
93
+ get_info("Event", :cl_command_type, "command_type", true)
92
94
 
93
95
  def context
94
96
  return command_queue.context
95
97
  end
96
98
 
99
+ # Returns the Platform associated with the Event
100
+ def platform
101
+ return @_platform if @_platform
102
+ @_platform = self.context.platform
103
+ end
104
+
97
105
  # Returns a CommandExecutionStatus corresponding to the status of the command associtated with the Event
98
106
  def command_execution_status
99
107
  ptr = MemoryPointer::new( :cl_int )
@@ -140,10 +148,11 @@ module OpenCL
140
148
 
141
149
  # Returns the Context associated with the Event
142
150
  def context
151
+ return @_context if @_context
143
152
  ptr = MemoryPointer::new( Context )
144
153
  error = OpenCL.clGetEventInfo(self, CONTEXT, Context.size, ptr, nil)
145
154
  error_check(error)
146
- return Context::new( ptr.read_pointer )
155
+ @_context = Context::new( ptr.read_pointer )
147
156
  end
148
157
 
149
158
  # Sets the satus of Event (a user event) to the given execution status
@@ -13,11 +13,17 @@ module OpenCL
13
13
  #
14
14
  # * +:flags+ - a single or an Array of :cl_mem_flags specifying the flags to be used when creating the Image
15
15
  # * +:host_ptr+ - if provided, the Pointer (or convertible to Pointer using to_ptr) to the memory area to use
16
+ # * +:properties+ - if provided, an array of :cl_mem_properties (OpenCL 3.0)
16
17
  def self.create_image( context, format, desc, options = {} )
17
18
  flags = get_flags( options )
18
19
  host_ptr = options[:host_ptr]
19
20
  error = MemoryPointer::new( :cl_int )
20
- img_ptr = clCreateImage( context, flags, format, desc, host_ptr, error )
21
+ if context.platform.version_number < 3.0 then
22
+ img_ptr = clCreateImage( context, flags, format, desc, host_ptr, error )
23
+ else
24
+ properties = get_mem_properties( options )
25
+ img_ptr = clCreateImageWithProperties( context, properties, flags, format, desc, host_ptr, error )
26
+ end
21
27
  error_check(error.read_cl_int)
22
28
  return Image::new(img_ptr, false)
23
29
  end
@@ -18,6 +18,7 @@ module OpenCL
18
18
  # Returns the Kernel corresponding the the specified name in the given Program
19
19
  def self.create_kernel(program, name)
20
20
  error = MemoryPointer::new( :cl_int )
21
+ name = name.to_s
21
22
  kernel_ptr = clCreateKernel(program, name, error)
22
23
  error_check(error.read_cl_int)
23
24
  return Kernel::new( kernel_ptr, false )
@@ -63,6 +64,11 @@ module OpenCL
63
64
  # Returns the Kernel this Arg belongs to
64
65
  attr_reader :kernel
65
66
 
67
+ # Returns the Platform associated with this Arg
68
+ def platform
69
+ kernel.platform
70
+ end
71
+
66
72
  if ExtendedStruct::const_get(:FORCE_EXTENSIONS_LOADING) then
67
73
 
68
74
  def self.register_extension(name, mod, cond)
@@ -107,24 +113,27 @@ module OpenCL
107
113
 
108
114
  # Returns an AddressQualifier corresponding to the Arg
109
115
  def address_qualifier
116
+ return @_address_qualifier if @_address_qualifier
110
117
  error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
111
118
  ptr = MemoryPointer::new( :cl_kernel_arg_address_qualifier )
112
119
  error = OpenCL.clGetKernelArgInfo(@kernel, @index, ADDRESS_QUALIFIER, ptr.size, ptr, nil)
113
120
  error_check(error)
114
- return AddressQualifier::new( ptr.read_cl_kernel_arg_address_qualifier )
121
+ @_address_qualifier = AddressQualifier::new( ptr.read_cl_kernel_arg_address_qualifier )
115
122
  end
116
123
 
117
124
  # Returns an AccessQualifier corresponding to the Arg
118
125
  def access_qualifier
126
+ return @_access_qualifier if @_access_qualifier
119
127
  error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
120
128
  ptr = MemoryPointer::new( :cl_kernel_arg_access_qualifier )
121
129
  error = OpenCL.clGetKernelArgInfo(@kernel, @index, ACCESS_QUALIFIER, ptr.size, ptr, nil)
122
130
  error_check(error)
123
- return AccessQualifier::new( ptr.read_cl_kernel_arg_access_qualifier )
131
+ @_access_qualifier = AccessQualifier::new( ptr.read_cl_kernel_arg_access_qualifier )
124
132
  end
125
133
 
126
134
  # Returns a String corresponding to the Arg type name
127
135
  def type_name
136
+ return @_type_name if @_type_name
128
137
  error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
129
138
  ptr1 = MemoryPointer::new( :size_t, 1)
130
139
  error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_NAME, 0, nil, ptr1)
@@ -132,20 +141,22 @@ module OpenCL
132
141
  ptr2 = MemoryPointer::new( ptr1.read_size_t )
133
142
  error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_NAME, ptr1.read_size_t, ptr2, nil)
134
143
  error_check(error)
135
- return ptr2.read_string
144
+ @_type_name = ptr2.read_string
136
145
  end
137
146
 
138
147
  # Returns a TypeQualifier corresponding to the Arg
139
148
  def type_qualifier
149
+ return @_type_qualifier if @_type_qualifier
140
150
  error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
141
151
  ptr = MemoryPointer::new( :cl_kernel_arg_type_qualifier )
142
152
  error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_QUALIFIER, ptr.size, ptr, nil)
143
153
  error_check(error)
144
- return TypeQualifier::new( ptr.read_cl_kernel_arg_type_qualifier )
154
+ @_type_qualifier = TypeQualifier::new( ptr.read_cl_kernel_arg_type_qualifier )
145
155
  end
146
156
 
147
157
  # Returns a String corresponding to the Arg name
148
158
  def name
159
+ return @_name if @_name
149
160
  error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
150
161
  ptr1 = MemoryPointer::new( :size_t, 1)
151
162
  error = OpenCL.clGetKernelArgInfo(@kernel, @index, NAME, 0, nil, ptr1)
@@ -153,7 +164,7 @@ module OpenCL
153
164
  ptr2 = MemoryPointer::new( ptr1.read_size_t )
154
165
  error = OpenCL.clGetKernelArgInfo(@kernel, @index, NAME, ptr1.read_size_t, ptr2, nil)
155
166
  error_check(error)
156
- return ptr2.read_string
167
+ @_name = ptr2.read_string
157
168
  end
158
169
 
159
170
  alias to_s name
@@ -174,27 +185,35 @@ module OpenCL
174
185
  return a
175
186
  end
176
187
 
177
- get_info("Kernel", :string, "function_name")
188
+ get_info("Kernel", :string, "function_name", true)
178
189
  alias name function_name
179
190
  alias to_s name
180
191
 
181
- get_info("Kernel", :cl_uint, "num_args")
192
+ get_info("Kernel", :cl_uint, "num_args", true)
182
193
  get_info("Kernel", :cl_uint, "reference_count")
183
194
 
195
+ # Returns the Platform associated with the Kernel
196
+ def platform
197
+ return @_platform if @_platform
198
+ @_platform = self.context.platform
199
+ end
200
+
184
201
  # Returns the Context the Kernel is associated with
185
202
  def context
203
+ return @_context if @_context
186
204
  ptr = MemoryPointer::new( Context )
187
205
  error = OpenCL.clGetKernelInfo(self, CONTEXT, Context.size, ptr, nil)
188
206
  error_check(error)
189
- return Context::new( ptr.read_pointer )
207
+ @_context = Context::new( ptr.read_pointer )
190
208
  end
191
209
 
192
210
  # Returns the Program the Kernel was created from
193
211
  def program
212
+ return @_program if @_program
194
213
  ptr = MemoryPointer::new( Program )
195
214
  error = OpenCL.clGetKernelInfo(self, PROGRAM, Program.size, ptr, nil)
196
215
  error_check(error)
197
- return Program::new(ptr.read_pointer)
216
+ @_program = Program::new(ptr.read_pointer)
198
217
  end
199
218
 
200
219
  def work_group_size(device = program.devices.first)
@@ -267,6 +286,7 @@ module OpenCL
267
286
  ##
268
287
  # returns a String containing the attributes qualifier used at kernel definition
269
288
  def attributes
289
+ return @_attributes if @_attributes
270
290
  attributes_size = MemoryPointer::new( :size_t )
271
291
  error = OpenCL.clGetKernelInfo( self, ATTRIBUTES, 0, nil, attributes_size)
272
292
  error_check(error)
@@ -274,7 +294,7 @@ module OpenCL
274
294
  error = OpenCL.clGetKernelInfo( self, ATTRIBUTES, attributes_size.read_size_t, attr, nil)
275
295
  error_check(error)
276
296
  attr_string = attr.read_string
277
- return attr_string.split(" ")
297
+ @_attributes = attr_string.split(" ")
278
298
  end
279
299
 
280
300
  def global_work_size(device = program.devices.first)
@@ -13,8 +13,16 @@ module OpenCL
13
13
  #
14
14
  # * +:user_data+ - a Pointer (or convertible to Pointer using to_ptr) to the memory area to pass to the callback
15
15
  def self.set_mem_object_destructor_callback( memobj, options = {}, &block )
16
- @@callbacks.push( block ) if block
17
- error = clSetMemObjectDestructorCallback( memobj, block, options[:user_data] )
16
+ if block
17
+ wrapper_block = lambda { |p, u|
18
+ block.call(p, u)
19
+ @@callbacks.delete(wrapper_block)
20
+ }
21
+ @@callbacks[wrapper_block] = options[:user_data]
22
+ else
23
+ wrapper_block = nil
24
+ end
25
+ error = clSetMemObjectDestructorCallback( memobj, wrapper_block, options[:user_data] )
18
26
  error_check(error)
19
27
  return memobj
20
28
  end
@@ -29,24 +37,26 @@ module OpenCL
29
37
  return "#<#{self.class.name}: #{size}#{ 0 != f.to_i ? " (#{f})" : ""}>"
30
38
  end
31
39
 
32
- get_info("Mem", :cl_mem_object_type, "type")
33
- get_info("Mem", :cl_mem_flags, "flags")
34
- get_info("Mem", :size_t, "size")
40
+ get_info("Mem", :cl_mem_object_type, "type", true)
41
+ get_info("Mem", :cl_mem_flags, "flags", true)
42
+ get_info("Mem", :size_t, "size", true)
35
43
  get_info("Mem", :pointer, "host_ptr")
36
44
  get_info("Mem", :cl_uint, "map_count")
37
45
  get_info("Mem", :cl_uint, "reference_count")
38
46
 
39
47
  # Returns the Context associated to the Mem
40
48
  def context
49
+ return @_context if @_context
41
50
  ptr = MemoryPointer::new( Context )
42
51
  error = OpenCL.clGetMemObjectInfo(self, CONTEXT, Context.size, ptr, nil)
43
52
  error_check(error)
44
- return Context::new( ptr.read_pointer )
53
+ @_context = Context::new( ptr.read_pointer )
45
54
  end
46
55
 
47
56
  # Returns the Platform associated to the Mem
48
57
  def platform
49
- return self.context.platform
58
+ return @_platform if @_platform
59
+ @_platform = self.context.platform
50
60
  end
51
61
 
52
62
  # Returns the texture_target argument specified in create_from_GL_texture for Mem
@@ -88,7 +98,7 @@ module OpenCL
88
98
  module OpenCL11
89
99
  extend InnerGenerator
90
100
 
91
- get_info("Mem", :size_t, "offset")
101
+ get_info("Mem", :size_t, "offset", true)
92
102
 
93
103
  # Returns the Buffer this Buffer was created from using create_sub_buffer
94
104
  def associated_memobject
@@ -119,12 +129,18 @@ module OpenCL
119
129
  module OpenCL20
120
130
  extend InnerGenerator
121
131
 
122
- get_info("Mem", :cl_bool, "uses_svm_pointer")
132
+ get_info("Mem", :cl_bool, "uses_svm_pointer", true)
133
+ end
134
+
135
+ module OpenCL30
136
+ extend InnerGenerator
123
137
 
138
+ get_info_array("Mem", :cl_mem_properties, "properties")
124
139
  end
125
140
 
126
141
  register_extension( :v11, OpenCL11, "platform.version_number >= 1.1" )
127
142
  register_extension( :v20, OpenCL20, "platform.version_number >= 2.0" )
143
+ register_extension( :v30, OpenCL30, "platform.version_number >= 3.0" )
128
144
 
129
145
  end
130
146
 
@@ -34,6 +34,14 @@ module OpenCL
34
34
  get_info("Pipe", :cl_uint, "packet_size")
35
35
  get_info("Pipe", :cl_uint, "max_packets")
36
36
 
37
+ module OpenCL30
38
+ extend InnerGenerator
39
+
40
+ get_info_array("Pipe", :cl_pipe_properties, "properties")
41
+ end
42
+
43
+ register_extension( :v30, Pipe::OpenCL30, "platform.version_number >= 3.0" )
44
+
37
45
  end
38
46
 
39
47
  end
@@ -63,6 +63,7 @@ module OpenCL
63
63
 
64
64
  # Returns an Array of Platform containing the available OpenCL platforms
65
65
  def self.get_platforms
66
+ return @_platforms if @_platforms
66
67
  ptr1 = MemoryPointer::new(:cl_uint , 1)
67
68
 
68
69
  error = clGetPlatformIDs(0, nil, ptr1)
@@ -70,9 +71,10 @@ module OpenCL
70
71
  ptr2 = MemoryPointer::new(:pointer, ptr1.read_uint)
71
72
  error = clGetPlatformIDs(ptr1.read_uint(), ptr2, nil)
72
73
  error_check(error)
73
- return ptr2.get_array_of_pointer(0,ptr1.read_uint()).collect { |platform_ptr|
74
+ @_platforms = ptr2.get_array_of_pointer(0,ptr1.read_uint()).collect { |platform_ptr|
74
75
  Platform::new(platform_ptr, false)
75
76
  }
77
+ return @_platforms
76
78
  end
77
79
 
78
80
  class << self
@@ -88,11 +90,11 @@ module OpenCL
88
90
  return "#<#{self.class.name}: #{self.name}>"
89
91
  end
90
92
 
91
- get_info("Platform", :string, "profile")
92
- get_info("Platform", :string, "version")
93
- get_info("Platform", :string, "name")
93
+ get_info("Platform", :string, "profile", true)
94
+ get_info("Platform", :string, "version", true)
95
+ get_info("Platform", :string, "name", true)
94
96
  alias to_s name
95
- get_info("Platform", :string, "vendor")
97
+ get_info("Platform", :string, "vendor", true)
96
98
 
97
99
  # Returns an Array of string corresponding to the Platform extensions
98
100
  def extensions
@@ -175,12 +177,37 @@ module OpenCL
175
177
  module OpenCL21
176
178
  extend InnerGenerator
177
179
 
178
- get_info("Platform", :cl_ulong, "host_timer_resolution")
180
+ get_info("Platform", :cl_ulong, "host_timer_resolution", true)
181
+
182
+ end
183
+
184
+ module OpenCL30
185
+ extend InnerGenerator
186
+
187
+ def numeric_version
188
+ ptr = MemoryPointer::new( :cl_version )
189
+ error = OpenCL.clGetPlatformInfo( self, NUMERIC_VERSION, 4, ptr, nil)
190
+ error_check(error)
191
+ return Version::from_int(ptr.read_cl_version)
192
+ end
193
+
194
+ def extensions_with_version
195
+ sz = MemoryPointer::new( :size_t )
196
+ error = OpenCL.clGetPlatformInfo( self, EXTENSIONS_WITH_VERSION, 0, nil, sz)
197
+ error_check(error)
198
+ sz = sz.read_size_t
199
+ ptr = MemoryPointer::new( sz )
200
+ error = OpenCL.clGetPlatformInfo( self, EXTENSIONS_WITH_VERSION, sz, ptr, nil)
201
+ error_check(error)
202
+ nvsz = NameVersion.size
203
+ return (sz/nvsz).times.collect { |i| NameVersion::new(ptr + i*nvsz) }
204
+ end
179
205
 
180
206
  end
181
207
 
182
208
  register_extension( :v12, OpenCL12, "version_number >= 1.2" )
183
209
  register_extension( :v21, OpenCL21, "version_number >= 2.1" )
210
+ register_extension( :v30, OpenCL30, "version_number >= 3.0" )
184
211
 
185
212
  end
186
213
 
@@ -15,12 +15,20 @@ module OpenCL
15
15
  # * +:options+ - a String containing the options to use for the build
16
16
  # * +:user_data+ - a Pointer (or convertible to Pointer using to_ptr) to the memory area to pass to the callback
17
17
  def self.build_program(program, options = {}, &block)
18
- @@callbacks.push( block ) if block
18
+ if block
19
+ wrapper_block = lambda { |p, u|
20
+ block.call(p, u)
21
+ @@callbacks.delete(wrapper_block)
22
+ }
23
+ @@callbacks[wrapper_block] = options[:user_data]
24
+ else
25
+ wrapper_block = nil
26
+ end
19
27
  num_devices, devices_p = get_device_list( options )
20
28
  opt = ""
21
29
  opt = options[:options] if options[:options]
22
30
  options_p = MemoryPointer.from_string(opt)
23
- error = clBuildProgram(program, num_devices, devices_p, options_p, block, options[:user_data] )
31
+ error = clBuildProgram(program, num_devices, devices_p, options_p, wrapper_block, options[:user_data] )
24
32
  error_check(error)
25
33
  return program
26
34
  end
@@ -40,7 +48,15 @@ module OpenCL
40
48
  # * +:options+ - a String containing the options to use for the build
41
49
  # * +:user_data+ - a Pointer (or convertible to Pointer using to_ptr) to the memory area to pass to the callback
42
50
  def self.link_program(context, input_programs, options = {}, &block)
43
- @@callbacks.push( block ) if block
51
+ if block
52
+ wrapper_block = lambda { |p, u|
53
+ block.call(p, u)
54
+ @@callbacks.delete(wrapper_block)
55
+ }
56
+ @@callbacks[wrapper_block] = options[:user_data]
57
+ else
58
+ wrapper_block = nil
59
+ end
44
60
  num_devices, devices_p = get_device_list( options )
45
61
  opt = ""
46
62
  opt = options[:options] if options[:options]
@@ -50,7 +66,7 @@ module OpenCL
50
66
  programs_p = MemoryPointer::new( Program, num_programs )
51
67
  programs_p.write_array_of_pointer(programs)
52
68
  error = MemoryPointer::new( :cl_int )
53
- prog = clLinkProgram( context, num_devices, devices_p, options_p, num_programs, programs_p, block, options[:user_data], error)
69
+ prog = clLinkProgram( context, num_devices, devices_p, options_p, num_programs, programs_p, wrapper_block, options[:user_data], error)
54
70
  error_check(error.read_cl_int)
55
71
  return Program::new( prog, false )
56
72
  end
@@ -70,7 +86,15 @@ module OpenCL
70
86
  # * +:options+ - a String containing the options to use for the compilation
71
87
  # * +:input_headers+ - a Hash containing pairs of : String: header_include_name => Program: header
72
88
  def self.compile_program(program, options = {}, &block)
73
- @@callbacks.push( block ) if block
89
+ if block
90
+ wrapper_block = lambda { |p, u|
91
+ block.call(p, u)
92
+ @@callbacks.delete(wrapper_block)
93
+ }
94
+ @@callbacks[wrapper_block] = options[:user_data]
95
+ else
96
+ wrapper_block = nil
97
+ end
74
98
  num_devices, devices_p = get_device_list( options )
75
99
  opt = ""
76
100
  opt = options[:options] if options[:options]
@@ -80,7 +104,7 @@ module OpenCL
80
104
  header_include_names = nil
81
105
  num_headers = 0
82
106
  num_headers = headers.length if headers
83
- if num_headers then
107
+ if num_headers > 0 then
84
108
  headers_p = MemoryPointer::new( Program, num_headers )
85
109
  header_include_names = MemoryPointer::new( :pointer, num_headers )
86
110
  indx = 0
@@ -90,7 +114,7 @@ module OpenCL
90
114
  indx = indx + 1
91
115
  }
92
116
  end
93
- error = clCompileProgram(program, num_devices, devices_p, options_p, num_headers, headers_p, header_include_names, block, options[:user_data] )
117
+ error = clCompileProgram(program, num_devices, devices_p, options_p, num_headers, headers_p, header_include_names, wrapper_block, options[:user_data] )
94
118
  error_check(error)
95
119
  return program
96
120
  end
@@ -125,10 +149,10 @@ module OpenCL
125
149
  # * +device_list+ - an Array of Device to create the program for. Can throw an Error::INVALID_VALUE if the number of supplied devices is different from the number of supplied binaries.
126
150
  # * +binaries+ - Array of binaries
127
151
  def self.create_program_with_binary(context, device_list, binaries)
128
- bins = [binaries].flatten
129
- num_devices = bins.length
152
+ binaries = [binaries].flatten
153
+ num_devices = binaries.length
130
154
  devices = [device_list].flatten
131
- error_check(INVALID_VALUE) if devices.length != bins.length
155
+ error_check(INVALID_VALUE) if devices.length != binaries.length
132
156
  devices_p = MemoryPointer::new( Device, num_devices )
133
157
  lengths = MemoryPointer::new( :size_t, num_devices )
134
158
  binaries_p = MemoryPointer::new( :pointer, num_devices )
@@ -215,8 +239,16 @@ module OpenCL
215
239
  #
216
240
  # * +:user_data+ - a Pointer (or convertible to Pointer using to_ptr) to the memory area to pass to the callback
217
241
  def self.set_program_release_callback( program, options = {}, &block )
218
- @@callbacks.push( block ) if block
219
- error = clSetProgramReleaseCallback( program, block, options[:user_data] )
242
+ if block
243
+ wrapper_block = lambda { |p, u|
244
+ block.call(p, u)
245
+ @@callbacks.delete(wrapper_block)
246
+ }
247
+ @@callbacks[wrapper_block] = options[:user_data]
248
+ else
249
+ wrapper_block = nil
250
+ end
251
+ error = clSetProgramReleaseCallback( program, wrapper_block, options[:user_data] )
220
252
  error_check(error)
221
253
  return program
222
254
  end
@@ -270,26 +302,35 @@ module OpenCL
270
302
  end
271
303
  end
272
304
 
305
+ # Returns the Platform associated with the Program
306
+ def platform
307
+ return @_platform if @_platform
308
+ @_platform = self.context.platform
309
+ end
310
+
273
311
  # Returns the Context the Program is associated to
274
312
  def context
313
+ return @_context if @_context
275
314
  ptr = MemoryPointer::new( Context )
276
315
  error = OpenCL.clGetProgramInfo(self, CONTEXT, Context.size, ptr, nil)
277
316
  error_check(error)
278
- return Context::new( ptr.read_pointer )
317
+ @_context = Context::new( ptr.read_pointer )
279
318
  end
280
319
 
281
- get_info("Program", :cl_uint, "num_devices")
320
+ get_info("Program", :cl_uint, "num_devices", true)
282
321
  get_info("Program", :cl_uint, "reference_count")
283
322
 
284
323
  # Returns the Array of Device the Program is associated with
285
324
  def devices
325
+ return @_devices if @_devices
286
326
  n = self.num_devices
287
327
  ptr2 = MemoryPointer::new( Device, n )
288
328
  error = OpenCL.clGetProgramInfo(self, DEVICES, Device.size*n, ptr2, nil)
289
329
  error_check(error)
290
- return ptr2.get_array_of_pointer(0, n).collect { |device_ptr|
330
+ @_devices = ptr2.get_array_of_pointer(0, n).collect { |device_ptr|
291
331
  Device::new(device_ptr)
292
332
  }
333
+ return @_devices
293
334
  end
294
335
 
295
336
  get_info("Program", :string, "source")
@@ -462,7 +503,7 @@ module OpenCL
462
503
  il_size = MemoryPointer::new( :size_t )
463
504
  error = OpenCL.clGetProgramInfo(self, IL, 0, nil, il_size)
464
505
  error_check(error)
465
- return nil if il_size == 0
506
+ return nil if il_size.read_size_t == 0
466
507
  length = il_size.read_size_t
467
508
  il_p = MemoryPointer::new( length )
468
509
  error = OpenCL.clGetProgramInfo(self, IL, length, il_p, nil)