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.
@@ -77,23 +77,30 @@ module OpenCL
77
77
 
78
78
  # Returns the CommandQueue associated with the Event, if it exists
79
79
  def command_queue
80
- ptr = MemoryPointer::new( CommandQueue )
81
- error = OpenCL.clGetEventInfo(self, COMMAND_QUEUE, CommandQueue.size, ptr, nil)
82
- error_check(error)
83
- pt = ptr.read_pointer
84
- if pt.null? then
85
- return nil
86
- else
87
- return CommandQueue::new( pt )
80
+ @_command_queue ||= begin
81
+ ptr = MemoryPointer::new( CommandQueue )
82
+ error = OpenCL.clGetEventInfo(self, COMMAND_QUEUE, CommandQueue.size, ptr, nil)
83
+ error_check(error)
84
+ pt = ptr.read_pointer
85
+ if pt.null? then
86
+ nil
87
+ else
88
+ CommandQueue::new( pt )
89
+ end
88
90
  end
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
+ @_platform ||= self.context.platform
102
+ end
103
+
97
104
  # Returns a CommandExecutionStatus corresponding to the status of the command associtated with the Event
98
105
  def command_execution_status
99
106
  ptr = MemoryPointer::new( :cl_int )
@@ -140,10 +147,12 @@ module OpenCL
140
147
 
141
148
  # Returns the Context associated with the Event
142
149
  def context
143
- ptr = MemoryPointer::new( Context )
144
- error = OpenCL.clGetEventInfo(self, CONTEXT, Context.size, ptr, nil)
145
- error_check(error)
146
- return Context::new( ptr.read_pointer )
150
+ @_context ||= begin
151
+ ptr = MemoryPointer::new( Context )
152
+ error = OpenCL.clGetEventInfo(self, CONTEXT, Context.size, ptr, nil)
153
+ error_check(error)
154
+ Context::new( ptr.read_pointer )
155
+ end
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
@@ -29,9 +29,12 @@ module OpenCL
29
29
  sz = size
30
30
  sz = value.class.size if sz == nil
31
31
  val = value
32
- if value.kind_of?(Mem) then
32
+ if value.kind_of?(Mem)
33
33
  val = MemoryPointer::new( Mem )
34
34
  val.write_pointer(value.to_ptr)
35
+ elsif value.kind_of?(Sampler)
36
+ val = MemoryPointer::new( Sampler )
37
+ val.write_pointer(value.to_ptr)
35
38
  end
36
39
  error = clSetKernelArg( kernel, index, sz, val )
37
40
  error_check(error)
@@ -64,6 +67,11 @@ module OpenCL
64
67
  # Returns the Kernel this Arg belongs to
65
68
  attr_reader :kernel
66
69
 
70
+ # Returns the Platform associated with this Arg
71
+ def platform
72
+ kernel.platform
73
+ end
74
+
67
75
  if ExtendedStruct::const_get(:FORCE_EXTENSIONS_LOADING) then
68
76
 
69
77
  def self.register_extension(name, mod, cond)
@@ -108,53 +116,63 @@ module OpenCL
108
116
 
109
117
  # Returns an AddressQualifier corresponding to the Arg
110
118
  def address_qualifier
111
- error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
112
- ptr = MemoryPointer::new( :cl_kernel_arg_address_qualifier )
113
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, ADDRESS_QUALIFIER, ptr.size, ptr, nil)
114
- error_check(error)
115
- return AddressQualifier::new( ptr.read_cl_kernel_arg_address_qualifier )
119
+ @_address_qualifier ||= begin
120
+ error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
121
+ ptr = MemoryPointer::new( :cl_kernel_arg_address_qualifier )
122
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, ADDRESS_QUALIFIER, ptr.size, ptr, nil)
123
+ error_check(error)
124
+ AddressQualifier::new( ptr.read_cl_kernel_arg_address_qualifier )
125
+ end
116
126
  end
117
127
 
118
128
  # Returns an AccessQualifier corresponding to the Arg
119
129
  def access_qualifier
120
- error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
121
- ptr = MemoryPointer::new( :cl_kernel_arg_access_qualifier )
122
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, ACCESS_QUALIFIER, ptr.size, ptr, nil)
123
- error_check(error)
124
- return AccessQualifier::new( ptr.read_cl_kernel_arg_access_qualifier )
130
+ @_access_qualifier ||= begin
131
+ error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
132
+ ptr = MemoryPointer::new( :cl_kernel_arg_access_qualifier )
133
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, ACCESS_QUALIFIER, ptr.size, ptr, nil)
134
+ error_check(error)
135
+ AccessQualifier::new( ptr.read_cl_kernel_arg_access_qualifier )
136
+ end
125
137
  end
126
138
 
127
139
  # Returns a String corresponding to the Arg type name
128
140
  def type_name
129
- error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
130
- ptr1 = MemoryPointer::new( :size_t, 1)
131
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_NAME, 0, nil, ptr1)
132
- error_check(error)
133
- ptr2 = MemoryPointer::new( ptr1.read_size_t )
134
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_NAME, ptr1.read_size_t, ptr2, nil)
135
- error_check(error)
136
- return ptr2.read_string
141
+ @_type_name ||= begin
142
+ error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
143
+ ptr1 = MemoryPointer::new( :size_t, 1)
144
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_NAME, 0, nil, ptr1)
145
+ error_check(error)
146
+ ptr2 = MemoryPointer::new( ptr1.read_size_t )
147
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_NAME, ptr1.read_size_t, ptr2, nil)
148
+ error_check(error)
149
+ ptr2.read_string
150
+ end
137
151
  end
138
152
 
139
153
  # Returns a TypeQualifier corresponding to the Arg
140
154
  def type_qualifier
141
- error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
142
- ptr = MemoryPointer::new( :cl_kernel_arg_type_qualifier )
143
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_QUALIFIER, ptr.size, ptr, nil)
144
- error_check(error)
145
- return TypeQualifier::new( ptr.read_cl_kernel_arg_type_qualifier )
155
+ @_type_qualifier ||= begin
156
+ error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
157
+ ptr = MemoryPointer::new( :cl_kernel_arg_type_qualifier )
158
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_QUALIFIER, ptr.size, ptr, nil)
159
+ error_check(error)
160
+ TypeQualifier::new( ptr.read_cl_kernel_arg_type_qualifier )
161
+ end
146
162
  end
147
163
 
148
164
  # Returns a String corresponding to the Arg name
149
165
  def name
150
- error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
151
- ptr1 = MemoryPointer::new( :size_t, 1)
152
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, NAME, 0, nil, ptr1)
153
- error_check(error)
154
- ptr2 = MemoryPointer::new( ptr1.read_size_t )
155
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, NAME, ptr1.read_size_t, ptr2, nil)
156
- error_check(error)
157
- return ptr2.read_string
166
+ @_name ||= begin
167
+ error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
168
+ ptr1 = MemoryPointer::new( :size_t, 1)
169
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, NAME, 0, nil, ptr1)
170
+ error_check(error)
171
+ ptr2 = MemoryPointer::new( ptr1.read_size_t )
172
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, NAME, ptr1.read_size_t, ptr2, nil)
173
+ error_check(error)
174
+ ptr2.read_string
175
+ end
158
176
  end
159
177
 
160
178
  alias to_s name
@@ -175,27 +193,36 @@ module OpenCL
175
193
  return a
176
194
  end
177
195
 
178
- get_info("Kernel", :string, "function_name")
196
+ get_info("Kernel", :string, "function_name", true)
179
197
  alias name function_name
180
198
  alias to_s name
181
199
 
182
- get_info("Kernel", :cl_uint, "num_args")
200
+ get_info("Kernel", :cl_uint, "num_args", true)
183
201
  get_info("Kernel", :cl_uint, "reference_count")
184
202
 
203
+ # Returns the Platform associated with the Kernel
204
+ def platform
205
+ @_platform ||= self.context.platform
206
+ end
207
+
185
208
  # Returns the Context the Kernel is associated with
186
209
  def context
187
- ptr = MemoryPointer::new( Context )
188
- error = OpenCL.clGetKernelInfo(self, CONTEXT, Context.size, ptr, nil)
189
- error_check(error)
190
- return Context::new( ptr.read_pointer )
210
+ @_context ||= begin
211
+ ptr = MemoryPointer::new( Context )
212
+ error = OpenCL.clGetKernelInfo(self, CONTEXT, Context.size, ptr, nil)
213
+ error_check(error)
214
+ Context::new( ptr.read_pointer )
215
+ end
191
216
  end
192
217
 
193
218
  # Returns the Program the Kernel was created from
194
219
  def program
195
- ptr = MemoryPointer::new( Program )
196
- error = OpenCL.clGetKernelInfo(self, PROGRAM, Program.size, ptr, nil)
197
- error_check(error)
198
- return Program::new(ptr.read_pointer)
220
+ @_program ||= begin
221
+ ptr = MemoryPointer::new( Program )
222
+ error = OpenCL.clGetKernelInfo(self, PROGRAM, Program.size, ptr, nil)
223
+ error_check(error)
224
+ Program::new(ptr.read_pointer)
225
+ end
199
226
  end
200
227
 
201
228
  def work_group_size(device = program.devices.first)
@@ -268,14 +295,16 @@ module OpenCL
268
295
  ##
269
296
  # returns a String containing the attributes qualifier used at kernel definition
270
297
  def attributes
271
- attributes_size = MemoryPointer::new( :size_t )
272
- error = OpenCL.clGetKernelInfo( self, ATTRIBUTES, 0, nil, attributes_size)
273
- error_check(error)
274
- attr = MemoryPointer::new( attributes_size.read_size_t )
275
- error = OpenCL.clGetKernelInfo( self, ATTRIBUTES, attributes_size.read_size_t, attr, nil)
276
- error_check(error)
277
- attr_string = attr.read_string
278
- return attr_string.split(" ")
298
+ @_attributes ||= begin
299
+ attributes_size = MemoryPointer::new( :size_t )
300
+ error = OpenCL.clGetKernelInfo( self, ATTRIBUTES, 0, nil, attributes_size)
301
+ error_check(error)
302
+ attr = MemoryPointer::new( attributes_size.read_size_t )
303
+ error = OpenCL.clGetKernelInfo( self, ATTRIBUTES, attributes_size.read_size_t, attr, nil)
304
+ error_check(error)
305
+ attr_string = attr.read_string
306
+ attr_string.split(" ")
307
+ end
279
308
  end
280
309
 
281
310
  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
41
- ptr = MemoryPointer::new( Context )
42
- error = OpenCL.clGetMemObjectInfo(self, CONTEXT, Context.size, ptr, nil)
43
- error_check(error)
44
- return Context::new( ptr.read_pointer )
49
+ @_context ||= begin
50
+ ptr = MemoryPointer::new( Context )
51
+ error = OpenCL.clGetMemObjectInfo(self, CONTEXT, Context.size, ptr, nil)
52
+ error_check(error)
53
+ Context::new( ptr.read_pointer )
54
+ end
45
55
  end
46
56
 
47
57
  # Returns the Platform associated to the Mem
48
58
  def platform
49
- return self.context.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,16 +63,18 @@ module OpenCL
63
63
 
64
64
  # Returns an Array of Platform containing the available OpenCL platforms
65
65
  def self.get_platforms
66
- ptr1 = MemoryPointer::new(:cl_uint , 1)
66
+ @_platforms ||= begin
67
+ ptr1 = MemoryPointer::new(:cl_uint , 1)
67
68
 
68
- error = clGetPlatformIDs(0, nil, ptr1)
69
- error_check(error)
70
- ptr2 = MemoryPointer::new(:pointer, ptr1.read_uint)
71
- error = clGetPlatformIDs(ptr1.read_uint(), ptr2, nil)
72
- error_check(error)
73
- return ptr2.get_array_of_pointer(0,ptr1.read_uint()).collect { |platform_ptr|
74
- Platform::new(platform_ptr, false)
75
- }
69
+ error = clGetPlatformIDs(0, nil, ptr1)
70
+ error_check(error)
71
+ ptr2 = MemoryPointer::new(:pointer, ptr1.read_uint)
72
+ error = clGetPlatformIDs(ptr1.read_uint(), ptr2, nil)
73
+ error_check(error)
74
+ ptr2.get_array_of_pointer(0,ptr1.read_uint()).collect { |platform_ptr|
75
+ Platform::new(platform_ptr, false)
76
+ }
77
+ end
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
@@ -248,7 +280,11 @@ module OpenCL
248
280
  build_status.each { |d,s|
249
281
  success |= true if s.to_i == BuildStatus::SUCCESS
250
282
  }
251
- return "#<#{self.class.name}: #{success ? kernel_names : ""}>"
283
+ begin
284
+ return "#<#{self.class.name}: #{success ? kernel_names : ""}>"
285
+ rescue
286
+ return "#<#{self.class.name}: >"
287
+ end
252
288
  end
253
289
 
254
290
  alias_method :orig_method_missing, :method_missing
@@ -270,26 +306,35 @@ module OpenCL
270
306
  end
271
307
  end
272
308
 
309
+ # Returns the Platform associated with the Program
310
+ def platform
311
+ @_platform ||= self.context.platform
312
+ end
313
+
273
314
  # Returns the Context the Program is associated to
274
315
  def context
275
- ptr = MemoryPointer::new( Context )
276
- error = OpenCL.clGetProgramInfo(self, CONTEXT, Context.size, ptr, nil)
277
- error_check(error)
278
- return Context::new( ptr.read_pointer )
316
+ @_context ||= begin
317
+ ptr = MemoryPointer::new( Context )
318
+ error = OpenCL.clGetProgramInfo(self, CONTEXT, Context.size, ptr, nil)
319
+ error_check(error)
320
+ Context::new( ptr.read_pointer )
321
+ end
279
322
  end
280
323
 
281
- get_info("Program", :cl_uint, "num_devices")
324
+ get_info("Program", :cl_uint, "num_devices", true)
282
325
  get_info("Program", :cl_uint, "reference_count")
283
326
 
284
327
  # Returns the Array of Device the Program is associated with
285
328
  def devices
286
- n = self.num_devices
287
- ptr2 = MemoryPointer::new( Device, n )
288
- error = OpenCL.clGetProgramInfo(self, DEVICES, Device.size*n, ptr2, nil)
289
- error_check(error)
290
- return ptr2.get_array_of_pointer(0, n).collect { |device_ptr|
291
- Device::new(device_ptr)
292
- }
329
+ @_devices ||= begin
330
+ n = self.num_devices
331
+ ptr2 = MemoryPointer::new( Device, n )
332
+ error = OpenCL.clGetProgramInfo(self, DEVICES, Device.size*n, ptr2, nil)
333
+ error_check(error)
334
+ ptr2.get_array_of_pointer(0, n).collect { |device_ptr|
335
+ Device::new(device_ptr)
336
+ }
337
+ end
293
338
  end
294
339
 
295
340
  get_info("Program", :string, "source")
@@ -462,7 +507,7 @@ module OpenCL
462
507
  il_size = MemoryPointer::new( :size_t )
463
508
  error = OpenCL.clGetProgramInfo(self, IL, 0, nil, il_size)
464
509
  error_check(error)
465
- return nil if il_size == 0
510
+ return nil if il_size.read_size_t == 0
466
511
  length = il_size.read_size_t
467
512
  il_p = MemoryPointer::new( length )
468
513
  error = OpenCL.clGetProgramInfo(self, IL, length, il_p, nil)