opencl_ruby_ffi 1.3.6 → 1.3.11

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