opencl_ruby_ffi 1.3.5 → 1.3.10

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
@@ -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,53 +113,63 @@ module OpenCL
107
113
 
108
114
  # Returns an AddressQualifier corresponding to the Arg
109
115
  def address_qualifier
110
- error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
111
- ptr = MemoryPointer::new( :cl_kernel_arg_address_qualifier )
112
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, ADDRESS_QUALIFIER, ptr.size, ptr, nil)
113
- error_check(error)
114
- return AddressQualifier::new( ptr.read_cl_kernel_arg_address_qualifier )
116
+ @_address_qualifier ||= begin
117
+ error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
118
+ ptr = MemoryPointer::new( :cl_kernel_arg_address_qualifier )
119
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, ADDRESS_QUALIFIER, ptr.size, ptr, nil)
120
+ error_check(error)
121
+ AddressQualifier::new( ptr.read_cl_kernel_arg_address_qualifier )
122
+ end
115
123
  end
116
124
 
117
125
  # Returns an AccessQualifier corresponding to the Arg
118
126
  def access_qualifier
119
- error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
120
- ptr = MemoryPointer::new( :cl_kernel_arg_access_qualifier )
121
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, ACCESS_QUALIFIER, ptr.size, ptr, nil)
122
- error_check(error)
123
- return AccessQualifier::new( ptr.read_cl_kernel_arg_access_qualifier )
127
+ @_access_qualifier ||= begin
128
+ error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
129
+ ptr = MemoryPointer::new( :cl_kernel_arg_access_qualifier )
130
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, ACCESS_QUALIFIER, ptr.size, ptr, nil)
131
+ error_check(error)
132
+ AccessQualifier::new( ptr.read_cl_kernel_arg_access_qualifier )
133
+ end
124
134
  end
125
135
 
126
136
  # Returns a String corresponding to the Arg type name
127
137
  def type_name
128
- error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
129
- ptr1 = MemoryPointer::new( :size_t, 1)
130
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_NAME, 0, nil, ptr1)
131
- error_check(error)
132
- ptr2 = MemoryPointer::new( ptr1.read_size_t )
133
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_NAME, ptr1.read_size_t, ptr2, nil)
134
- error_check(error)
135
- return ptr2.read_string
138
+ @_type_name ||= begin
139
+ error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
140
+ ptr1 = MemoryPointer::new( :size_t, 1)
141
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_NAME, 0, nil, ptr1)
142
+ error_check(error)
143
+ ptr2 = MemoryPointer::new( ptr1.read_size_t )
144
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_NAME, ptr1.read_size_t, ptr2, nil)
145
+ error_check(error)
146
+ ptr2.read_string
147
+ end
136
148
  end
137
149
 
138
150
  # Returns a TypeQualifier corresponding to the Arg
139
151
  def type_qualifier
140
- error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
141
- ptr = MemoryPointer::new( :cl_kernel_arg_type_qualifier )
142
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_QUALIFIER, ptr.size, ptr, nil)
143
- error_check(error)
144
- return TypeQualifier::new( ptr.read_cl_kernel_arg_type_qualifier )
152
+ @_type_qualifier ||= begin
153
+ error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
154
+ ptr = MemoryPointer::new( :cl_kernel_arg_type_qualifier )
155
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, TYPE_QUALIFIER, ptr.size, ptr, nil)
156
+ error_check(error)
157
+ TypeQualifier::new( ptr.read_cl_kernel_arg_type_qualifier )
158
+ end
145
159
  end
146
160
 
147
161
  # Returns a String corresponding to the Arg name
148
162
  def name
149
- error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
150
- ptr1 = MemoryPointer::new( :size_t, 1)
151
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, NAME, 0, nil, ptr1)
152
- error_check(error)
153
- ptr2 = MemoryPointer::new( ptr1.read_size_t )
154
- error = OpenCL.clGetKernelArgInfo(@kernel, @index, NAME, ptr1.read_size_t, ptr2, nil)
155
- error_check(error)
156
- return ptr2.read_string
163
+ @_name ||= begin
164
+ error_check(INVALID_OPERATION) if @kernel.context.platform.version_number < 1.2
165
+ ptr1 = MemoryPointer::new( :size_t, 1)
166
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, NAME, 0, nil, ptr1)
167
+ error_check(error)
168
+ ptr2 = MemoryPointer::new( ptr1.read_size_t )
169
+ error = OpenCL.clGetKernelArgInfo(@kernel, @index, NAME, ptr1.read_size_t, ptr2, nil)
170
+ error_check(error)
171
+ ptr2.read_string
172
+ end
157
173
  end
158
174
 
159
175
  alias to_s name
@@ -174,27 +190,36 @@ module OpenCL
174
190
  return a
175
191
  end
176
192
 
177
- get_info("Kernel", :string, "function_name")
193
+ get_info("Kernel", :string, "function_name", true)
178
194
  alias name function_name
179
195
  alias to_s name
180
196
 
181
- get_info("Kernel", :cl_uint, "num_args")
197
+ get_info("Kernel", :cl_uint, "num_args", true)
182
198
  get_info("Kernel", :cl_uint, "reference_count")
183
199
 
200
+ # Returns the Platform associated with the Kernel
201
+ def platform
202
+ @_platform ||= self.context.platform
203
+ end
204
+
184
205
  # Returns the Context the Kernel is associated with
185
206
  def context
186
- ptr = MemoryPointer::new( Context )
187
- error = OpenCL.clGetKernelInfo(self, CONTEXT, Context.size, ptr, nil)
188
- error_check(error)
189
- return Context::new( ptr.read_pointer )
207
+ @_context ||= begin
208
+ ptr = MemoryPointer::new( Context )
209
+ error = OpenCL.clGetKernelInfo(self, CONTEXT, Context.size, ptr, nil)
210
+ error_check(error)
211
+ Context::new( ptr.read_pointer )
212
+ end
190
213
  end
191
214
 
192
215
  # Returns the Program the Kernel was created from
193
216
  def program
194
- ptr = MemoryPointer::new( Program )
195
- error = OpenCL.clGetKernelInfo(self, PROGRAM, Program.size, ptr, nil)
196
- error_check(error)
197
- return Program::new(ptr.read_pointer)
217
+ @_program ||= begin
218
+ ptr = MemoryPointer::new( Program )
219
+ error = OpenCL.clGetKernelInfo(self, PROGRAM, Program.size, ptr, nil)
220
+ error_check(error)
221
+ Program::new(ptr.read_pointer)
222
+ end
198
223
  end
199
224
 
200
225
  def work_group_size(device = program.devices.first)
@@ -267,14 +292,16 @@ module OpenCL
267
292
  ##
268
293
  # returns a String containing the attributes qualifier used at kernel definition
269
294
  def attributes
270
- attributes_size = MemoryPointer::new( :size_t )
271
- error = OpenCL.clGetKernelInfo( self, ATTRIBUTES, 0, nil, attributes_size)
272
- error_check(error)
273
- attr = MemoryPointer::new( attributes_size.read_size_t )
274
- error = OpenCL.clGetKernelInfo( self, ATTRIBUTES, attributes_size.read_size_t, attr, nil)
275
- error_check(error)
276
- attr_string = attr.read_string
277
- return attr_string.split(" ")
295
+ @_attributes ||= begin
296
+ attributes_size = MemoryPointer::new( :size_t )
297
+ error = OpenCL.clGetKernelInfo( self, ATTRIBUTES, 0, nil, attributes_size)
298
+ error_check(error)
299
+ attr = MemoryPointer::new( attributes_size.read_size_t )
300
+ error = OpenCL.clGetKernelInfo( self, ATTRIBUTES, attributes_size.read_size_t, attr, nil)
301
+ error_check(error)
302
+ attr_string = attr.read_string
303
+ attr_string.split(" ")
304
+ end
278
305
  end
279
306
 
280
307
  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)