BOAST 1.2.2 → 1.3.0

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/BOAST.gemspec +2 -2
  3. data/lib/BOAST.rb +1 -0
  4. data/lib/BOAST/Language/Algorithm.rb +68 -30
  5. data/lib/BOAST/Language/Annotation.rb +1 -0
  6. data/lib/BOAST/Language/Architectures.rb +1 -0
  7. data/lib/BOAST/Language/Arithmetic.rb +15 -9
  8. data/lib/BOAST/Language/BOAST_OpenCL.rb +94 -87
  9. data/lib/BOAST/Language/CPUID_by_name.rb +1 -0
  10. data/lib/BOAST/Language/Case.rb +6 -0
  11. data/lib/BOAST/Language/CodeBlock.rb +1 -0
  12. data/lib/BOAST/Language/Comment.rb +14 -11
  13. data/lib/BOAST/Language/Config.rb +23 -15
  14. data/lib/BOAST/Language/ControlStructure.rb +10 -2
  15. data/lib/BOAST/Language/DataTypes.rb +23 -15
  16. data/lib/BOAST/Language/Expression.rb +3 -0
  17. data/lib/BOAST/Language/For.rb +31 -26
  18. data/lib/BOAST/Language/FuncCall.rb +7 -0
  19. data/lib/BOAST/Language/Functors.rb +56 -19
  20. data/lib/BOAST/Language/If.rb +3 -0
  21. data/lib/BOAST/Language/Index.rb +11 -9
  22. data/lib/BOAST/Language/Intrinsics.rb +2 -0
  23. data/lib/BOAST/Language/OpenMP.rb +57 -40
  24. data/lib/BOAST/Language/Operators.rb +27 -19
  25. data/lib/BOAST/Language/Pragma.rb +1 -0
  26. data/lib/BOAST/Language/Print.rb +3 -0
  27. data/lib/BOAST/Language/Procedure.rb +81 -76
  28. data/lib/BOAST/Language/Slice.rb +16 -14
  29. data/lib/BOAST/Language/State.rb +126 -55
  30. data/lib/BOAST/Language/Transitions.rb +26 -26
  31. data/lib/BOAST/Language/Variable.rb +89 -58
  32. data/lib/BOAST/Language/While.rb +3 -0
  33. data/lib/BOAST/Runtime/AffinityProbe.rb +65 -0
  34. data/lib/BOAST/Runtime/CKernel.rb +44 -1
  35. data/lib/BOAST/Runtime/CRuntime.rb +3 -0
  36. data/lib/BOAST/Runtime/CUDARuntime.rb +3 -0
  37. data/lib/BOAST/Runtime/CompiledRuntime.rb +4 -0
  38. data/lib/BOAST/Runtime/Compilers.rb +6 -5
  39. data/lib/BOAST/Runtime/Config.rb +1 -1
  40. data/lib/BOAST/Runtime/FFIRuntime.rb +3 -0
  41. data/lib/BOAST/Runtime/FORTRANRuntime.rb +3 -0
  42. data/lib/BOAST/Runtime/MPPARuntime.rb +2 -0
  43. data/lib/BOAST/Runtime/NonRegression.rb +5 -3
  44. data/lib/BOAST/Runtime/OpenCLRuntime.rb +7 -10
  45. data/lib/BOAST/Runtime/Probe.rb +2 -0
  46. metadata +7 -6
@@ -13,34 +13,34 @@ module BOAST
13
13
  t = ops[:default]
14
14
  return [t,operator] if t
15
15
  raise "Unresolvable transition!"
16
- end
16
+ end
17
17
 
18
- def set_transition(type1, type2, operator, return_type)
19
- @@transitions[[type1,type2]][operator] = return_type
20
- end
18
+ def set_transition(type1, type2, operator, return_type)
19
+ @@transitions[[type1,type2]][operator] = return_type
20
+ end
21
21
 
22
- def transition(var1, var2, operator)
23
- signed = false
24
- size = nil
25
- vector_length = 1
26
- t1 = var1.type.class
27
- t2 = var2.type.class
28
- t1 = var1.type.name if t1 == CustomType
29
- t2 = var2.type.name if t2 == CustomType
30
- return_type, operator = get_transition(t1, t2, operator)
31
- #STDERR.puts "#{return_type} : #{var1.type.class} #{operator} #{var2.type.class}"
32
- if t1 == return_type and t2 == return_type then
33
- signed = (signed or var1.type.signed)
34
- signed = (signed or var2.type.signed)
35
- size = [var1.type.size, var2.type.size].max
36
- vector_length = [var1.type.vector_length, var2.type.vector_length].max
37
- return [Variable::new("dummy", return_type, :size => size, :signed => signed, :vector_length => vector_length), operator]
38
- elsif var1.type.class == return_type then
39
- return [var1, operator]
40
- else # var2.type.class == return_type then
41
- return [var2, operator]
42
- end
43
- end
22
+ def transition(var1, var2, operator)
23
+ signed = false
24
+ size = nil
25
+ vector_length = 1
26
+ t1 = var1.type.class
27
+ t2 = var2.type.class
28
+ t1 = var1.type.name if t1 == CustomType
29
+ t2 = var2.type.name if t2 == CustomType
30
+ return_type, operator = get_transition(t1, t2, operator)
31
+ #STDERR.puts "#{return_type} : #{var1.type.class} #{operator} #{var2.type.class}"
32
+ if t1 == return_type and t2 == return_type then
33
+ signed = (signed or var1.type.signed)
34
+ signed = (signed or var2.type.signed)
35
+ size = [var1.type.size, var2.type.size].max
36
+ vector_length = [var1.type.vector_length, var2.type.vector_length].max
37
+ return [Variable::new("dummy", return_type, :size => size, :signed => signed, :vector_length => vector_length), operator]
38
+ elsif var1.type.class == return_type then
39
+ return [var1, operator]
40
+ else # var2.type.class == return_type then
41
+ return [var2, operator]
42
+ end
43
+ end
44
44
 
45
45
  end
46
46
 
@@ -1,5 +1,6 @@
1
1
  module BOAST
2
2
 
3
+ # @!parse module Functors; functorize Dimension; end
3
4
  class Dimension
4
5
  include PrivateStateAccessor
5
6
  include Inspectable
@@ -9,10 +10,19 @@ module BOAST
9
10
  attr_reader :val2
10
11
  attr_reader :size
11
12
 
13
+ # Creates a new {Dimension}.
14
+ # @overload initialize()
15
+ # Creates a {Dimension} of unknown {#size}, used to declare an array of unknown size.
16
+ # @overload initialize( size )
17
+ # Creates a {Dimension} of size *size*, {#start} is computed at evaluation as {BOAST.get_array_start}.
18
+ # @param [Object] size can be an integer or a {Variable} or {Expression}
19
+ # @overload initialize( lower, upper )
20
+ # Creates a {Dimension} with a lower and upper bound. {#size} is computed as 'upper - lower + 1' and can be an {Expression}
21
+ # @param [Object] lower bound of the {Dimension}
22
+ # @param [Object] upper bound of the {Dimension}
12
23
  def initialize(v1=nil,v2=nil)
13
24
  if v1 then
14
25
  if v2 then
15
- #@size = Expression::new(Substraction, v2, v1) + 1
16
26
  begin
17
27
  @size = v2-v1+1
18
28
  rescue
@@ -28,6 +38,7 @@ module BOAST
28
38
  @val2 = v2
29
39
  end
30
40
 
41
+ # Returns a {String} representation of the {Dimension}
31
42
  def to_s
32
43
  if lang == FORTRAN and @val2 then
33
44
  return "#{@val1}:#{@val2}"
@@ -40,6 +51,7 @@ module BOAST
40
51
  end
41
52
  end
42
53
 
54
+ # Returns the start of the {Dimension} as given at initialization or as computed {BOAST.get_array_start}.
43
55
  def start
44
56
  if @val2 then
45
57
  return @val1
@@ -48,6 +60,7 @@ module BOAST
48
60
  end
49
61
  end
50
62
 
63
+ # Returns the end of the {Dimension} if the size is known.
51
64
  def finish
52
65
  if @val2 then
53
66
  return @val2
@@ -72,6 +85,10 @@ module BOAST
72
85
 
73
86
  end
74
87
 
88
+ module Functors
89
+ alias Dim Dimension
90
+ end
91
+
75
92
  class ConstArray < Array
76
93
  include PrivateStateAccessor
77
94
  include Inspectable
@@ -88,8 +105,10 @@ module BOAST
88
105
  return to_s_c if [C, CL, CUDA].include?( lang )
89
106
  end
90
107
 
108
+ private
109
+
91
110
  def to_s_fortran
92
- arr = self.flatten
111
+ arr = flatten
93
112
  s = ""
94
113
  return s if arr.first.nil?
95
114
  s += "reshape(" if @shape
@@ -106,7 +125,7 @@ module BOAST
106
125
  end
107
126
 
108
127
  def to_s_c
109
- arr = self.flatten
128
+ arr = flatten
110
129
  s = ""
111
130
  return s if arr.first.nil?
112
131
  s += "{\n"
@@ -118,8 +137,10 @@ module BOAST
118
137
  }
119
138
  s += "}"
120
139
  end
140
+
121
141
  end
122
142
 
143
+ # @!parse module Functors; functorize Variable; end
123
144
  class Variable
124
145
  include PrivateStateAccessor
125
146
  include Arithmetic
@@ -137,7 +158,7 @@ module BOAST
137
158
  required_set = m.to_s[1..-1].chars.to_a
138
159
  existing_set = [*('0'..'9'),*('a'..'z')].first(@type.vector_length)
139
160
  if required_set.length == required_set.uniq.length and (required_set - existing_set).empty? then
140
- return self.copy(name+"."+m.to_s, :vector_length => m.to_s[1..-1].length)
161
+ return copy(name+"."+m.to_s, :vector_length => m.to_s[1..-1].length)
141
162
  else
142
163
  return orig_method_missing(m, *a, &b)
143
164
  end
@@ -210,21 +231,25 @@ module BOAST
210
231
  !!@deferred_shape
211
232
  end
212
233
 
213
- def initialize(name,type,hash={})
234
+ # Creates a new {Variable}
235
+ # @param [#to_s] name
236
+ # @param [DataType] type
237
+ # @param [Hash] properties a set of named properties.
238
+ def initialize(name, type, properties={})
214
239
  @name = name.to_s
215
- @direction = hash[:direction] ? hash[:direction] : hash[:dir]
216
- @constant = hash[:constant] ? hash[:constant] : hash[:const]
217
- @dimension = hash[:dimension] ? hash[:dimension] : hash[:dim]
218
- @local = hash[:local] ? hash[:local] : hash[:shared]
219
- @texture = hash[:texture]
220
- @allocate = hash[:allocate]
221
- @restrict = hash[:restrict]
222
- @alignment = hash[:align]
223
- @deferred_shape = hash[:deferred_shape]
224
- @optional = hash[:optional]
240
+ @direction = properties[:direction] ? properties[:direction] : properties[:dir]
241
+ @constant = properties[:constant] ? properties[:constant] : properties[:const]
242
+ @dimension = properties[:dimension] ? properties[:dimension] : properties[:dim]
243
+ @local = properties[:local] ? properties[:local] : properties[:shared]
244
+ @texture = properties[:texture]
245
+ @allocate = properties[:allocate]
246
+ @restrict = properties[:restrict]
247
+ @alignment = properties[:align]
248
+ @deferred_shape = properties[:deferred_shape]
249
+ @optional = properties[:optional]
225
250
  @force_replace_constant = false
226
- if not hash[:replace_constant].nil? then
227
- @replace_constant = hash[:replace_constant]
251
+ if not properties[:replace_constant].nil? then
252
+ @replace_constant = properties[:replace_constant]
228
253
  else
229
254
  @replace_constant = true
230
255
  end
@@ -233,8 +258,8 @@ module BOAST
233
258
  else
234
259
  @sampler = nil
235
260
  end
236
- @type = type::new(hash)
237
- @options = hash
261
+ @type = type::new(properties)
262
+ @properties = properties
238
263
  if (@direction == :out or @direction == :inout) and not dimension? then
239
264
  @scalar_output = true
240
265
  else
@@ -243,10 +268,10 @@ module BOAST
243
268
  @dimension = [@dimension].flatten if dimension?
244
269
  end
245
270
 
246
- def copy(name=nil,options={})
271
+ def copy(name=nil,properties={})
247
272
  name = @name if not name
248
- h = @options.clone
249
- options.each { |k,v|
273
+ h = @properties.clone
274
+ properties.each { |k,v|
250
275
  h[k] = v
251
276
  }
252
277
  return Variable::new(name, @type.class, h)
@@ -257,9 +282,9 @@ module BOAST
257
282
  return self
258
283
  end
259
284
 
260
- def self.from_type(name, type, options={})
285
+ def self.from_type(name, type, properties={})
261
286
  hash = type.to_hash
262
- options.each { |k,v|
287
+ properties.each { |k,v|
263
288
  hash[k] = v
264
289
  }
265
290
  hash[:direction] = nil
@@ -304,13 +329,6 @@ module BOAST
304
329
  return Index::new(self,*args)
305
330
  end
306
331
 
307
- def finalize
308
- s = ""
309
- s += ";" if [C, CL, CUDA].include?( lang )
310
- s+="\n"
311
- return s
312
- end
313
-
314
332
  def boast_header(lang=C)
315
333
  return decl_texture_s if texture?
316
334
  s = ""
@@ -345,12 +363,39 @@ module BOAST
345
363
  return decl_c if [C, CL, CUDA].include?( lang )
346
364
  end
347
365
 
366
+ def align
367
+ if dimension? then
368
+ if align? or default_align > 1 then
369
+ a = ( align? ? alignment : 1 )
370
+ a = ( a >= default_align ? a : default_align )
371
+ return align_c(a) if lang == C
372
+ return align_fortran(a) if lang == FORTRAN
373
+ end
374
+ end
375
+ return nil
376
+ end
377
+
378
+ def alloc( dims = nil, align = get_address_size )
379
+ @dimension = [dims].flatten if dims
380
+ dims = @dimension
381
+ raise "Cannot allocate array with unknown dimension!" unless dims
382
+ return alloc_fortran(dims) if lang == FORTRAN
383
+ return alloc_c(dims, align) if lang == C
384
+ end
385
+
386
+ def dealloc
387
+ return dealloc_fortran if lang == FORTRAN
388
+ return dealloc_c if lang == C
389
+ end
390
+
391
+ private
392
+
348
393
  def __const?
349
394
  return !!( constant? or @direction == :in )
350
395
  end
351
396
 
352
397
  def __global?
353
- return !!( lang == CL and @direction and dimension? and not (@options[:register] or @options[:private] or local?) )
398
+ return !!( lang == CL and @direction and dimension? and not (@properties[:register] or @properties[:private] or local?) )
354
399
  end
355
400
 
356
401
  def __local?
@@ -468,18 +513,6 @@ module BOAST
468
513
  return Pragma::new("DIR", "ASSUME_ALIGNED", "#{@name}: #{a}")
469
514
  end
470
515
 
471
- def align
472
- if dimension? then
473
- if align? or default_align > 1 then
474
- a = ( align? ? alignment : 1 )
475
- a = ( a >= default_align ? a : default_align )
476
- return align_c(a) if lang == C
477
- return align_fortran(a) if lang == FORTRAN
478
- end
479
- end
480
- return nil
481
- end
482
-
483
516
  def alloc_fortran( dims = nil )
484
517
  return FuncCall::new(:allocate, FuncCall(name, * dims ) )
485
518
  end
@@ -489,20 +522,12 @@ module BOAST
489
522
  if align > (OS.bits/8) then
490
523
  # check alignment is a power of 2
491
524
  raise "Invalid alignment #{align}!" if align & (align - 1) != 0
492
- return FuncCall::new(:posix_memalign, self.address, align, FuncCall::new(:sizeof, @type.decl) * d)
525
+ return FuncCall::new(:posix_memalign, address, align, FuncCall::new(:sizeof, @type.decl) * d)
493
526
  else
494
527
  return self === FuncCall::new(:malloc, FuncCall::new(:sizeof, @type.decl) * d).cast(self)
495
528
  end
496
529
  end
497
530
 
498
- def alloc( dims = nil, align = get_address_size )
499
- @dimension = [dims].flatten if dims
500
- dims = @dimension
501
- raise "Cannot allocate array with unknown dimension!" unless dims
502
- return alloc_fortran(dims) if lang == FORTRAN
503
- return alloc_c(dims, align) if lang == C
504
- end
505
-
506
531
  def dealloc_fortran
507
532
  return FuncCall::new(:deallocate, self)
508
533
  end
@@ -511,11 +536,6 @@ module BOAST
511
536
  return FuncCall::new(:free, self)
512
537
  end
513
538
 
514
- def dealloc
515
- return dealloc_fortran if lang == FORTRAN
516
- return dealloc_c if lang == C
517
- end
518
-
519
539
  def decl_fortran
520
540
  s = ""
521
541
  s += indent
@@ -555,6 +575,17 @@ module BOAST
555
575
  return self
556
576
  end
557
577
 
578
+ def finalize
579
+ s = ""
580
+ s += ";" if [C, CL, CUDA].include?( lang )
581
+ s+="\n"
582
+ return s
583
+ end
584
+
585
+ end
586
+
587
+ module Functors
588
+ alias Var Variable
558
589
  end
559
590
 
560
591
  end
@@ -1,5 +1,6 @@
1
1
  module BOAST
2
2
 
3
+ # @!parse module Functors; functorize While; end
3
4
  class While < ControlStructure
4
5
  include Annotation
5
6
  ANNOTATIONS = [ :condition ]
@@ -21,6 +22,8 @@ module BOAST
21
22
  :end => '"end do"' }
22
23
  end
23
24
 
25
+ private :get_c_strings, :get_fortran_strings
26
+
24
27
  alias get_cl_strings get_c_strings
25
28
  alias get_cuda_strings get_c_strings
26
29
 
@@ -0,0 +1,65 @@
1
+ module BOAST
2
+
3
+ # @private
4
+ module AffinityProbe
5
+ extend PrivateStateAccessor
6
+
7
+ module_function
8
+
9
+ def header
10
+ get_output.puts "#ifndef _GNU_SOURCE"
11
+ get_output.puts "#define _GNU_SOURCE"
12
+ get_output.puts "#endif"
13
+ get_output.puts "#include <sched.h>"
14
+ end
15
+
16
+ def decl
17
+ get_output.puts " cpu_set_t _boast_affinity_mask_old;"
18
+ get_output.puts " int _boast_affinity_set = 0;"
19
+ end
20
+
21
+ def configure
22
+ get_output.print <<EOF
23
+ if( _boast_rb_opts != Qnil ) {
24
+ VALUE _boast_affinity_rb_ptr = Qnil;
25
+
26
+ _boast_affinity_rb_ptr = rb_hash_aref(_boast_rb_opts, ID2SYM(rb_intern("cpu_affinity")));
27
+
28
+ if( _boast_affinity_rb_ptr != Qnil ) {
29
+ cpu_set_t _boast_affinity_mask;
30
+ int _boast_affinity_counter;
31
+ int _boast_affinity_cpu_number;
32
+
33
+ if( TYPE(_boast_affinity_rb_ptr) != T_ARRAY )
34
+ rb_raise(rb_eArgError, "Option :cpu_affinity should be an array!");
35
+ CPU_ZERO(&_boast_affinity_mask);
36
+ _boast_affinity_cpu_number = RARRAY_LEN(_boast_affinity_rb_ptr);
37
+ for( _boast_affinity_counter = 0; _boast_affinity_counter < _boast_affinity_cpu_number; _boast_affinity_counter++ )
38
+ CPU_SET(FIX2INT(rb_ary_entry(_boast_affinity_rb_ptr,_boast_affinity_counter)), &_boast_affinity_mask);
39
+ sched_getaffinity(getpid(), sizeof(_boast_affinity_mask_old), &_boast_affinity_mask_old);
40
+ if( sched_setaffinity(getpid(), sizeof(_boast_affinity_mask), &_boast_affinity_mask) != 0)
41
+ rb_raise(rb_eArgError, "Invalid affinity list provided!");
42
+ _boast_affinity_set = 1;
43
+ }
44
+ }
45
+ EOF
46
+ end
47
+
48
+ def start
49
+ end
50
+
51
+ def stop
52
+ end
53
+
54
+ def compute
55
+ get_output.print <<EOF
56
+ if ( _boast_affinity_set == 1 ) {
57
+ sched_setaffinity(getpid(), sizeof(_boast_affinity_mask_old), &_boast_affinity_mask_old);
58
+ _boast_affinity_set = 0;
59
+ }
60
+ EOF
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -23,7 +23,13 @@ module BOAST
23
23
  attr_accessor :architecture
24
24
  attr_accessor :kernels
25
25
  attr_accessor :cost_function
26
-
26
+
27
+ # Creates a new CKernel object. BOAST output is redirected to the CKernel. If the chain_code state is set the current BOAST output, as returned by {BOAST.get_output}, is used.
28
+ # @param [Hash] options contains named options
29
+ # @option options [StringIO] :code specify a StringIO to use rather than create a new one.
30
+ # @option options [Array] :kernels list of kernels this kernel depends on. The kernels will be linked at build time.
31
+ # @option options [Integer] :lang specify the language to use. Default is current language state as returned by {BOAST.get_lang}.
32
+ # @option options [Integer] :architecture specify the architecture to use. Default is the current BOAST architecture as returned by {BOAST.get_architecture}.
27
33
  def initialize(options={})
28
34
  if options[:code] then
29
35
  @code = options[:code]
@@ -50,6 +56,7 @@ module BOAST
50
56
  @architecture = get_architecture
51
57
  end
52
58
  @probes = [TimerProbe, PAPIProbe]
59
+ @probes.push AffinityProbe unless OS.mac?
53
60
 
54
61
  case @lang
55
62
  when CL
@@ -71,11 +78,13 @@ module BOAST
71
78
  end
72
79
  end
73
80
 
81
+ # @deprecated
74
82
  def print
75
83
  @code.rewind
76
84
  puts @code.read
77
85
  end
78
86
 
87
+ # @return [String] source code of the kernel
79
88
  def to_s
80
89
  if @lang == FORTRAN then
81
90
  return line_limited_source
@@ -85,6 +94,7 @@ module BOAST
85
94
  end
86
95
  end
87
96
 
97
+ # @private
88
98
  def method_missing(meth, *args, &block)
89
99
  if meth.to_s == "run" then
90
100
  build
@@ -94,8 +104,41 @@ module BOAST
94
104
  end
95
105
  end
96
106
 
107
+ # If a cost function is provided returns the cost of running the function on the provided arguments.
97
108
  def cost(*args)
98
109
  @cost_function.call(*args)
99
110
  end
111
+
112
+ # @!method build( options = {} )
113
+ # Builds the computing kernel.
114
+ # @param [Hash] options contains build time options. Usual compiling flags are supported. Default values can be overriden in $XDG_CONFIG_HOME/.config/BOAST/compiler_options or $HOME/.config/BOAST/compiler_options. The same flags can be set as environment variables. Flags given here override environment variable ones.
115
+ # @option options [String] :CC C compiler
116
+ # @option options [String] :CFLAGS C compiler flags
117
+ # @option options [String] :FC Fortran compiler
118
+ # @option options [String] :FCFLAGS Fortran compiler flags
119
+ # @option options [String] :CXX C++ compiler
120
+ # @option options [String] :CXXFLAGS C++ compiler flags
121
+ # @option options [String] :LD linker
122
+ # @option options [String] :LDFLAGS linker flags
123
+ # @option options [Boolean] :OPENMP activate OpenMP support. Correct flag should be set for your compiler in $XDG_CONFIG_HOME/.config/BOAST/openmp_flags or $HOME/.config/BOAST/openmp_flags.
124
+ # @option options [String] :NVCC cuda compiler
125
+ # @option options [String] :NVCCFLAGS cuda compiler flags
126
+ # @option options [String] :CLFLAGS opencl compiation flags
127
+ # @option options [String] :CLVENDOR restrict selected OpenCL platforms to the ones which vendor match the option
128
+ # @option options [String] :CLPLATFORM restrict selected OpenCL platforms to the ones which name match the option
129
+ # @option options [String] :CLDEVICE restrict selected OpenCL devices to the ones which mame match the option or use the provided OpenCL::Device
130
+ # @option options [String] :CLCONTEXT use the devices in the given OpenCL::Context
131
+ # @option options [String] :CLDEVICETYPE restrict selected OpenCL devices to the corresponding types
132
+
133
+ # @!method run( *args, options = {} )
134
+ # Runs the computing kernel using the given arguments.
135
+ # @param args the arguments corresponding to the list of parameters of the #procedure attribute
136
+ # @param [Hash] options contains runtime options.
137
+ # @option options [Array] :global_work_size only considered for CUDA and OpenCL kernels. See corresponding OpenCL documentation
138
+ # @option options [Array] :local_work_size only considered for CUDA and OpenCL kernels. See corresponding OpenCL documentation
139
+ # @option options [Array] :block_number only considered for CUDA and OpenCL kernels. See corresponding CUDA documentation
140
+ # @option options [Array] :block_size only considered for CUDA and OpenCL kernels. See corresponding CUDA documentation
141
+ # @option options [Array] :PAPI list of PAPI counters to monitor. ( ex: ['PAPI_L1_DCM', 'PAPI_L2_DCM'], see PAPI documentation.
142
+ # @return [Hash] contains at least the *:duration* entry which is the runtime of the kernel in seconds. If the kernel is a function then the *:return* field will contain the returned value. For :inout or :out scalars the *:reference_return* field will be a Hash with each parameter name associated to the corresponding value. If *:PAPI* options was given will contain a *:PAPI* entry with the corresponding counters value.
100
143
  end
101
144
  end