opencl_ruby_ffi 0.994 → 0.995

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,5 @@
1
1
  module FFI
2
+
2
3
  class Pointer
3
4
  alias_method :orig_method_missing, :method_missing
4
5
  # if a missing write_type, read_type, get_array_of_type can transitively get a replacement, an alias is created and the method is called
@@ -42,36 +43,8 @@ module FFI
42
43
  end
43
44
 
44
45
  module OpenCL
45
- @@type_converter = {
46
- :cl_device_type => Device::Type,
47
- :cl_device_fp_config => Device::FPConfig,
48
- :cl_device_mem_cache_type => Device::MemCacheType,
49
- :cl_device_local_mem_type => Device::LocalMemType,
50
- :cl_device_exec_capabilities => Device::ExecCapabilities,
51
- :cl_command_queue_properties => CommandQueue::Properties,
52
- :cl_device_affinity_domain => Device::AffinityDomain,
53
- :cl_device_svm_capabilities => Device::SVMCapabilities,
54
- :cl_channel_order => ChannelOrder,
55
- :cl_channel_type => ChannelType,
56
- :cl_mem_flags => Mem::Flags,
57
- :cl_mem_object_type => Mem::Type,
58
- :cl_mem_migration_flags => Mem::MigrationFlags,
59
- :cl_addressing_mode => AddressingMode,
60
- :cl_filter_mode => FilterMode,
61
- :cl_map_flags => MapFlags,
62
- :cl_program_binary_type => Program::BinaryType,
63
- :cl_kernel_arg_address_qualifier => Kernel::Arg::AddressQualifier,
64
- :cl_kernel_arg_access_qualifier => Kernel::Arg::AccessQualifier,
65
- :cl_kernel_arg_type_qualifier => Kernel::Arg::TypeQualifier,
66
- :cl_command_type => CommandType,
67
- :cl_build_status => BuildStatus
68
- }
69
- @@callbacks = []
70
46
 
71
- # Converts a type from a symbol to an OpenCL class if a convertion is found
72
- def self.convert_type(type)
73
- return @@type_converter[type]
74
- end
47
+ @@callbacks = []
75
48
 
76
49
  # Maps the :cl_image_fomat type of OpenCL
77
50
  class ImageFormat < FFI::Struct
@@ -87,7 +60,7 @@ module OpenCL
87
60
 
88
61
  # Returns a new ChannelOrder corresponding to the ImageFormat internal value
89
62
  def channel_order
90
- return OpenCL::ChannelOrder::new(self[:image_channel_order])
63
+ return ChannelOrder::new(self[:image_channel_order])
91
64
  end
92
65
 
93
66
  # Sets the ImageFormat internal value for the image channel order
@@ -97,7 +70,7 @@ module OpenCL
97
70
 
98
71
  # Returns a new ChannelType corresponding to the ImageFormat internal value
99
72
  def channel_data_type
100
- return OpenCL::ChannelType::new(self[:image_channel_data_type])
73
+ return ChannelType::new(self[:image_channel_data_type])
101
74
  end
102
75
 
103
76
  # Sets the ImageFormat internal value for the image channel data type
@@ -134,7 +107,7 @@ module OpenCL
134
107
  :image_slice_pitch, :size_t,
135
108
  :num_mip_levels, :cl_uint,
136
109
  :num_samples, :cl_uint,
137
- :buffer, OpenCL::Mem.ptr
110
+ :buffer, Mem.ptr
138
111
 
139
112
  # Creates anew ImageDesc using the values provided by the user
140
113
  def initialize( image_type, image_width, image_height, image_depth, image_array_size, image_row_pitch, image_slice_pitch, num_mip_levels, num_samples, buffer )
@@ -165,163 +138,222 @@ module OpenCL
165
138
  end
166
139
  end
167
140
 
168
- # Extracts the :flags named option from the hash given and returns the flags value
169
- def self.get_flags( options )
170
- flags = 0
171
- if options[:flags] then
172
- if options[:flags].respond_to?(:each) then
173
- options[:flags].each { |f| flags = flags | f }
141
+ #:stopdoc:
142
+ module InnerInterface
143
+
144
+ private
145
+
146
+ # Extracts the :flags named option from the hash given and returns the flags value
147
+ def get_flags( options )
148
+ flags = 0
149
+ if options[:flags] then
150
+ if options[:flags].respond_to?(:each) then
151
+ options[:flags].each { |f| flags = flags | f }
152
+ else
153
+ flags = options[:flags]
154
+ end
155
+ end
156
+ return flags
157
+ end
158
+
159
+ # Extracts the :event_wait_list named option from the hash given and returns a tuple containing the number of events and a pointer to those events
160
+ def get_event_wait_list( options )
161
+ num_events = 0
162
+ events = nil
163
+ if options[:event_wait_list] then
164
+ num_events = options[:event_wait_list].length
165
+ if num_events > 0 then
166
+ events = FFI::MemoryPointer::new( Event, num_events )
167
+ options[:event_wait_list].each_with_index { |e, i|
168
+ events[i].write_pointer(e)
169
+ }
170
+ end
171
+ end
172
+ return [num_events, events]
173
+ end
174
+
175
+ # Extracts the :properties named option (for a CommandQueue) from the hash given and returns the properties values
176
+ def get_command_queue_properties( options )
177
+ properties = CommandQueue::Properties::new(0)
178
+ if options[:properties] then
179
+ if options[:properties].respond_to?(:each) then
180
+ options[:properties].each { |f| properties = properties | f }
181
+ else
182
+ properties = properties | options[:properties]
183
+ end
184
+ end
185
+ return properties
186
+ end
187
+
188
+ # Extracts the origin_symbol and region_symbol named options for image from the given hash. Returns the read (or detemined suitable) origin and region in a tuple
189
+ def get_origin_region( image, options, origin_symbol, region_symbol )
190
+ origin = FFI::MemoryPointer::new( :size_t, 3 )
191
+ (0..2).each { |i| origin[i].write_size_t(0) }
192
+ if options[origin_symbol] then
193
+ options[origin_symbol].each_with_index { |e, i|
194
+ origin[i].write_size_t(e)
195
+ }
196
+ end
197
+ region = FFI::MemoryPointer::new( :size_t, 3 )
198
+ (0..2).each { |i| region[i].write_size_t(1) }
199
+ if options[region_symbol] then
200
+ options[region_symbol].each_with_index { |e, i|
201
+ region[i].write_size_t(e)
202
+ }
174
203
  else
175
- flags = options[:flags]
204
+ region[0].write_size_t( image.width - origin[0].read_size_t )
205
+ if image.type == Mem::IMAGE1D_ARRAY then
206
+ region[1].write_size_t( image.array_size - origin[1].read_size_t )
207
+ else
208
+ region[1].write_size_t( image.height != 0 ? image.height - origin[1].read_size_t : 1 )
209
+ end
210
+ if image.type == Mem::IMAGE2D_ARRAY then
211
+ region[2].write_size_t( image.array_size - origin[2].read_size_t )
212
+ else
213
+ region[2].write_size_t( image.depth != 0 ? image.depth - origin[2].read_size_t : 1 )
214
+ end
176
215
  end
216
+ return [origin, region]
177
217
  end
178
- return flags
179
- end
180
-
181
- # Extracts the :event_wait_list named option from the hash given and returns a tuple containing the number of events and a pointer to those events
182
- def self.get_event_wait_list( options )
183
- num_events = 0
184
- events = nil
185
- if options[:event_wait_list] then
186
- num_events = options[:event_wait_list].length
187
- if num_events > 0 then
188
- events = FFI::MemoryPointer::new( Event, num_events )
189
- options[:event_wait_list].each_with_index { |e, i|
190
- events[i].write_pointer(e)
218
+
219
+ # Extracts the :properties named option (for a Context) from the hash given and returns an FFI:Pointer to a 0 terminated list of properties
220
+ def get_context_properties( options )
221
+ properties = nil
222
+ if options[:properties] then
223
+ properties = FFI::MemoryPointer::new( :cl_context_properties, options[:properties].length + 1 )
224
+ options[:properties].each_with_index { |e,i|
225
+ properties[i].write_cl_context_properties(e)
191
226
  }
227
+ properties[options[:properties].length].write_cl_context_properties(0)
192
228
  end
229
+ return properties
193
230
  end
194
- return [ num_events, events ]
195
- end
196
-
197
- # Extracts the :properties named option (for a CommandQueue) from the hash given and returns the properties values
198
- def self.get_command_queue_properties( options )
199
- properties = CommandQueue::Properties::new(0)
200
- if options[:properties] then
201
- if options[:properties].respond_to?(:each) then
202
- options[:properties].each { |f| properties = properties | f }
231
+
232
+ # Extracts the :device_list named option from the hash given and returns [ number of devices, an FFI:Pointer to the list of Device or nil ]
233
+ def get_device_list( options )
234
+ devices = options[:device_list]
235
+ devices = [devices].flatten if devices
236
+ devices_p = nil
237
+ num_devices = 0
238
+ if devices and devices.size > 0 then
239
+ num_devices = devices.size
240
+ devices_p = FFI::MemoryPointer::new( Device, num_devices)
241
+ devices_p.write_array_of_pointer(devices)
242
+ end
243
+ return [num_devices, devices_p]
244
+ end
245
+
246
+ # checks if a :cl_int corresponds to an error code and raises the apropriate Error
247
+ def error_check(errcode)
248
+ return nil if errcode == SUCCESS
249
+ klass = Error::CLASSES[errcode]
250
+ if klass then
251
+ raise klass::new
203
252
  else
204
- properties = properties | options[:properties]
253
+ raise Error::new("#{errcode}")
205
254
  end
206
255
  end
207
- return properties
208
- end
209
256
 
210
- # Extracts the origin_symbol and region_symbol named options for image from the given hash. Returns the read (or detemined suitable) origin and region in a tuple
211
- def self.get_origin_region( image, options, origin_symbol, region_symbol )
212
- origin = FFI::MemoryPointer::new( :size_t, 3 )
213
- (0..2).each { |i| origin[i].write_size_t(0) }
214
- if options[origin_symbol] then
215
- options[origin_symbol].each_with_index { |e, i|
216
- origin[i].write_size_t(e)
217
- }
218
- end
219
- region = FFI::MemoryPointer::new( :size_t, 3 )
220
- (0..2).each { |i| region[i].write_size_t(1) }
221
- if options[region_symbol] then
222
- options[region_symbol].each_with_index { |e, i|
223
- region[i].write_size_t(e)
224
- }
225
- else
226
- region[0].write_size_t( image.width - origin[0].read_size_t )
227
- if image.type == Mem::IMAGE1D_ARRAY then
228
- region[1].write_size_t( image.array_size - origin[1].read_size_t )
229
- else
230
- region[1].write_size_t( image.height != 0 ? image.height - origin[1].read_size_t : 1 )
231
- end
232
- if image.type == Mem::IMAGE2D_ARRAY then
233
- region[2].write_size_t( image.array_size - origin[2].read_size_t )
234
- else
235
- region[2].write_size_t( image.depth != 0 ? image.depth - origin[2].read_size_t : 1 )
236
- end
257
+ TYPE_CONVERTER = {
258
+ :cl_device_type => Device::Type,
259
+ :cl_device_fp_config => Device::FPConfig,
260
+ :cl_device_mem_cache_type => Device::MemCacheType,
261
+ :cl_device_local_mem_type => Device::LocalMemType,
262
+ :cl_device_exec_capabilities => Device::ExecCapabilities,
263
+ :cl_command_queue_properties => CommandQueue::Properties,
264
+ :cl_device_affinity_domain => Device::AffinityDomain,
265
+ :cl_device_svm_capabilities => Device::SVMCapabilities,
266
+ :cl_channel_order => ChannelOrder,
267
+ :cl_channel_type => ChannelType,
268
+ :cl_mem_flags => Mem::Flags,
269
+ :cl_mem_object_type => Mem::Type,
270
+ :cl_mem_migration_flags => Mem::MigrationFlags,
271
+ :cl_addressing_mode => AddressingMode,
272
+ :cl_filter_mode => FilterMode,
273
+ :cl_map_flags => MapFlags,
274
+ :cl_program_binary_type => Program::BinaryType,
275
+ :cl_kernel_arg_address_qualifier => Kernel::Arg::AddressQualifier,
276
+ :cl_kernel_arg_access_qualifier => Kernel::Arg::AccessQualifier,
277
+ :cl_kernel_arg_type_qualifier => Kernel::Arg::TypeQualifier,
278
+ :cl_command_type => CommandType,
279
+ :cl_build_status => BuildStatus
280
+ }
281
+
282
+ private_constant :TYPE_CONVERTER
283
+
284
+ # Converts a type from a symbol to an OpenCL class if a convertion is found
285
+ def convert_type(type)
286
+ return TYPE_CONVERTER[type]
237
287
  end
238
- return [origin, region]
239
- end
240
288
 
241
- # Extracts the :properties named option (for a Context) from the hash given and returns an FFI:Pointer to a 0 terminated list of properties
242
- def self.get_context_properties( options )
243
- properties = nil
244
- if options[:properties] then
245
- properties = FFI::MemoryPointer::new( :cl_context_properties, options[:properties].length + 1 )
246
- options[:properties].each_with_index { |e,i|
247
- properties[i].write_cl_context_properties(e)
248
- }
249
- properties[options[:properties].length].write_cl_context_properties(0)
250
- end
251
- return properties
252
289
  end
253
290
 
254
- # checks if a :cl_int corresponds to an error code and raises the apropriate Error
255
- def self.error_check(errcode)
256
- return nil if errcode == SUCCESS
257
- klass = Error::CLASSES[errcode]
258
- if klass then
259
- raise klass::new
260
- else
261
- raise Error::new("#{errcode}")
262
- end
263
- end
291
+ private_constant :InnerInterface
292
+ extend InnerInterface
293
+
294
+ module InnerGenerator
264
295
 
265
- # Generates a new method for klass that use the apropriate clGetKlassInfo, to read an Array of element of the given type. The info queried is specified by name.
266
- def self.get_info_array(klass, type, name)
267
- klass_name = klass
268
- klass_name = "MemObject" if klass == "Mem"
269
- s = <<EOF
296
+ private
297
+
298
+ # Generates a new method for klass that use the apropriate clGetKlassInfo, to read an element of the given type. The info queried is specified by name.
299
+ def get_info(klass, type, name)
300
+ klass_name = klass
301
+ klass_name = "MemObject" if klass == "Mem"
302
+ s = <<EOF
270
303
  def #{name.downcase}
271
304
  ptr1 = FFI::MemoryPointer::new( :size_t, 1)
272
305
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name}, 0, nil, ptr1)
273
- OpenCL.error_check(error)
274
- EOF
275
- if ( klass == "Device" and name == "PARTITION_TYPE" ) or ( klass == "Context" and name == "PROPERTIES" ) then
276
- s+= <<EOF
277
- return [] if ptr1.read_size_t == 0
278
- EOF
279
- end
280
- s += <<EOF
306
+ error_check(error)
281
307
  ptr2 = FFI::MemoryPointer::new( ptr1.read_size_t )
282
308
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name}, ptr1.read_size_t, ptr2, nil)
283
- OpenCL.error_check(error)
284
- arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t/ FFI.find_type(:#{type}).size)
285
- EOF
286
- if ( klass == "Device" and ( name == "PARTITION_TYPE" or name == "PARTITION_PROPERTIES" ) ) or ( klass == "Context" and name == "PROPERTIES" ) then
287
- s+= <<EOF
288
- return arr.reject! { |e| e == 0 }
289
- end
290
- EOF
291
- else
292
- s+= <<EOF
293
- return arr
309
+ error_check(error)
310
+ if(convert_type(:#{type})) then
311
+ return convert_type(:#{type})::new(ptr2.read_#{type})
312
+ else
313
+ return ptr2.read_#{type}
314
+ end
294
315
  end
295
316
  EOF
317
+ return s
296
318
  end
297
- return s
298
- end
299
319
 
300
- # Generates a new method for klass that use the apropriate clGetKlassInfo, to read an element of the given type. The info queried is specified by name.
301
- def self.get_info(klass, type, name)
302
- klass_name = klass
303
- klass_name = "MemObject" if klass == "Mem"
304
- s = <<EOF
320
+ # Generates a new method for klass that use the apropriate clGetKlassInfo, to read an Array of element of the given type. The info queried is specified by name.
321
+ def get_info_array(klass, type, name)
322
+ klass_name = klass
323
+ klass_name = "MemObject" if klass == "Mem"
324
+ s = <<EOF
305
325
  def #{name.downcase}
306
326
  ptr1 = FFI::MemoryPointer::new( :size_t, 1)
307
327
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name}, 0, nil, ptr1)
308
- OpenCL.error_check(error)
328
+ error_check(error)
329
+ EOF
330
+ if ( klass == "Device" and name == "PARTITION_TYPE" ) or ( klass == "Context" and name == "PROPERTIES" ) then
331
+ s+= <<EOF
332
+ return [] if ptr1.read_size_t == 0
333
+ EOF
334
+ end
335
+ s += <<EOF
309
336
  ptr2 = FFI::MemoryPointer::new( ptr1.read_size_t )
310
337
  error = OpenCL.clGet#{klass_name}Info(self, #{klass}::#{name}, ptr1.read_size_t, ptr2, nil)
311
- OpenCL.error_check(error)
338
+ error_check(error)
339
+ arr = ptr2.get_array_of_#{type}(0, ptr1.read_size_t/ FFI.find_type(:#{type}).size)
312
340
  EOF
313
- if(convert_type(type)) then
314
- s += <<EOF
315
- return OpenCL::convert_type(:#{type})::new(ptr2.read_#{type})
341
+ if ( klass == "Device" and ( name == "PARTITION_TYPE" or name == "PARTITION_PROPERTIES" ) ) or ( klass == "Context" and name == "PROPERTIES" ) then
342
+ s+= <<EOF
343
+ return arr.reject! { |e| e == 0 }
316
344
  end
317
345
  EOF
318
- else
319
- s += <<EOF
320
- return ptr2.read_#{type}
346
+ else
347
+ s+= <<EOF
348
+ return arr
321
349
  end
322
350
  EOF
351
+ end
352
+ return s
323
353
  end
324
- return s
354
+
325
355
  end
356
+ private_constant :InnerGenerator
357
+ #:startdoc:
326
358
 
327
359
  end