BOAST 1.3.5 → 2.0.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/BOAST.gemspec +1 -1
  3. data/LICENSE +13 -1
  4. data/README.md +62 -13
  5. data/lib/BOAST.rb +3 -1
  6. data/lib/BOAST/Language/ARMCPUID_by_name.rb +3752 -0
  7. data/lib/BOAST/Language/Algorithm.rb +4 -24
  8. data/lib/BOAST/Language/Architectures.rb +5 -0
  9. data/lib/BOAST/Language/Arithmetic.rb +38 -5
  10. data/lib/BOAST/Language/BOAST_OpenCL.rb +7 -8
  11. data/lib/BOAST/Language/Case.rb +10 -3
  12. data/lib/BOAST/Language/Config.rb +36 -12
  13. data/lib/BOAST/Language/ControlStructure.rb +7 -3
  14. data/lib/BOAST/Language/DataTypes.rb +6 -0
  15. data/lib/BOAST/Language/Expression.rb +26 -2
  16. data/lib/BOAST/Language/For.rb +59 -30
  17. data/lib/BOAST/Language/FuncCall.rb +9 -5
  18. data/lib/BOAST/Language/Functors.rb +1 -1
  19. data/lib/BOAST/Language/HighLevelOperators.rb +172 -0
  20. data/lib/BOAST/Language/If.rb +25 -9
  21. data/lib/BOAST/Language/Index.rb +5 -5
  22. data/lib/BOAST/Language/Intrinsics.rb +40 -27
  23. data/lib/BOAST/Language/OpenMP.rb +1 -0
  24. data/lib/BOAST/Language/Operators.rb +221 -34
  25. data/lib/BOAST/Language/Parens.rb +3 -2
  26. data/lib/BOAST/Language/Procedure.rb +18 -5
  27. data/lib/BOAST/Language/Slice.rb +176 -44
  28. data/lib/BOAST/Language/Variable.rb +99 -56
  29. data/lib/BOAST/Language/While.rb +18 -3
  30. data/lib/BOAST/Language/{CPUID_by_name.rb → X86CPUID_by_name.rb} +0 -0
  31. data/lib/BOAST/Optimization/Optimization.rb +2 -0
  32. data/lib/BOAST/Runtime/AffinityProbe.rb +7 -3
  33. data/lib/BOAST/Runtime/CKernel.rb +3 -0
  34. data/lib/BOAST/Runtime/CRuntime.rb +4 -0
  35. data/lib/BOAST/Runtime/CompiledRuntime.rb +404 -77
  36. data/lib/BOAST/Runtime/Compilers.rb +44 -18
  37. data/lib/BOAST/Runtime/Config.rb +9 -0
  38. data/lib/BOAST/Runtime/EnergyProbe.rb +19 -3
  39. data/lib/BOAST/Runtime/FFIRuntime.rb +23 -0
  40. data/lib/BOAST/Runtime/FORTRANRuntime.rb +1 -1
  41. data/lib/BOAST/Runtime/MAQAO.rb +29 -0
  42. data/lib/BOAST/Runtime/NonRegression.rb +64 -3
  43. data/lib/BOAST/Runtime/OpenCLRuntime.rb +16 -6
  44. data/lib/BOAST/Runtime/Probe.rb +21 -1
  45. metadata +5 -3
@@ -53,32 +53,12 @@ module BOAST
53
53
 
54
54
  # Returns the symbol corresponding to the active architecture
55
55
  def get_architecture_name
56
- case architecture
57
- when X86
58
- return :X86
59
- when ARM
60
- return :ARM
61
- when MPPA
62
- return :MPPA
63
- else
64
- return nil
65
- end
56
+ return ARCHITECTURES[architecture]
66
57
  end
67
58
 
68
59
  # Returns the symbol corresponding to the active language
69
60
  def get_lang_name
70
- case lang
71
- when C
72
- return :C
73
- when FORTRAN
74
- return :FORTRAN
75
- when CL
76
- return :CL
77
- when CUDA
78
- return :CUDA
79
- else
80
- nil
81
- end
61
+ return LANGUAGES[lang]
82
62
  end
83
63
 
84
64
  @@output = STDOUT
@@ -174,9 +154,9 @@ module BOAST
174
154
  # Calls the given object pr method with the optional arguments.
175
155
  # @param a a BOAST Expression, ControlStructure or Procedure
176
156
  # @param args an optional list of parameters
177
- def pr(a, *args)
157
+ def pr(a, *args, &block)
178
158
  pr_annotate(a) if annotate?
179
- a.pr(*args)
159
+ a.pr(*args, &block)
180
160
  end
181
161
 
182
162
  # One of BOAST keywords: declares BOAST Variables and Procedures.
@@ -293,4 +293,9 @@ X86architectures ={"pentium2"=>["MMX"],
293
293
  "SSE",
294
294
  "MMX"]}
295
295
  private_constant :X86architectures
296
+ ARMarchitectures = {
297
+ "armv7-a" => ["NEON"],
298
+ "armv8-a" => ["ASIMD"]
299
+ }
300
+ private_constant :ARMarchitectures
296
301
  end
@@ -2,32 +2,58 @@ module BOAST
2
2
 
3
3
  module TopLevelExpressions
4
4
 
5
+ # Creates a return Expression
6
+ # @param [#to_var] value to return
7
+ # @return [Expression]
5
8
  def Return(value)
6
9
  return Expression::new("return",nil, value)
7
10
  end
8
11
 
12
+ # Creates an Expression using the boolean And Operator
13
+ # @param [#to_var] a
14
+ # @param [#to_var] b
15
+ # @return [Expression]
9
16
  def And(a, b)
10
17
  return Expression::new(And, a, b)
11
18
  end
12
19
 
20
+ # Creates an Expression using the boolean Or Operator
21
+ # @param [#to_var] a
22
+ # @param [#to_var] b
23
+ # @return [Expression]
13
24
  def Or(a, b)
14
25
  return Expression::new(Or, a, b)
15
26
  end
16
27
 
28
+ def Max(a, b)
29
+ return Expression::new(Max, a, b)
30
+ end
31
+
32
+ def Min(a, b)
33
+ return Expression::new(Min, a, b)
34
+ end
35
+
17
36
  end
18
37
 
19
38
  extend TopLevelExpressions
20
39
 
21
40
  EXTENDED.push TopLevelExpressions
22
41
 
42
+ # Defines arithmetic operation, mostly using operator overloading.
23
43
  module Arithmetic
24
44
 
45
+ # Returns an Exponentiation Expression bewtween self and x
46
+ # @param [#to_var] x
47
+ # @return [Expression]
25
48
  def **(x)
26
49
  return Expression::new(Exponentiation,self,x)
27
50
  end
28
51
 
52
+ # Returns an Affectation Expression x into self
53
+ # @param [#to_var] x
54
+ # @return [Expression]
29
55
  def ===(x)
30
- return Expression::new(Affectation,self,x)
56
+ return Affectation::new(self,x)
31
57
  end
32
58
 
33
59
  def !
@@ -63,7 +89,7 @@ module BOAST
63
89
  end
64
90
 
65
91
  def -(x)
66
- return Expression::new(Substraction,self,x)
92
+ return Expression::new(Subtraction,self,x)
67
93
  end
68
94
 
69
95
  def *(x)
@@ -110,11 +136,18 @@ module BOAST
110
136
  end
111
137
 
112
138
  def components( range )
113
- if self.type.vector_length == 1
139
+ var = self.to_var
140
+ if var.type.vector_length == 1
114
141
  return self
115
142
  else
116
- existing_set = [*('0'..'9'),*('a'..'z')].first(self.type.vector_length)
117
- eval "self.s#{existing_set[range].join("")}"
143
+ existing_set = [*('0'..'9'),*('a'..'z')].first(var.type.vector_length)
144
+ if range.kind_of?(Range) then
145
+ eval "self.s#{existing_set[range].join("")}"
146
+ elsif range.kind_of?(Array) then
147
+ eval "self.s#{existing_set.values_at(*range).join("")}"
148
+ else
149
+ eval "self.s#{existing_set[range]}"
150
+ end
118
151
  end
119
152
  end
120
153
 
@@ -13,7 +13,6 @@ module BOAST
13
13
 
14
14
  def barrier(*locality)
15
15
  if lang == CL then
16
- loc=""
17
16
  if locality.include?(:local) and locality.include?(:global) then
18
17
  return FuncCall::new("barrier","CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE")
19
18
  elsif locality.include?(:local) then
@@ -32,7 +31,7 @@ module BOAST
32
31
 
33
32
  def get_work_dim
34
33
  if lang == CL then
35
- return FuncCall::new("get_work_dim", :returns => Int("wd", :signed => false))
34
+ return FuncCall::new("get_work_dim", :return => Int("wd", :signed => false))
36
35
  else
37
36
  raise "Unsupported language!"
38
37
  end
@@ -40,7 +39,7 @@ module BOAST
40
39
 
41
40
  def get_global_size(dim)
42
41
  if lang == CL then
43
- return FuncCall::new("get_global_size", dim, :returns => Sizet)
42
+ return FuncCall::new("get_global_size", dim, :return => Sizet)
44
43
  elsif lang == CUDA then
45
44
  d = OCL_CUDA_DIM_ASSOC[dim]
46
45
  raise "Unsupported dimension!" if not d
@@ -52,7 +51,7 @@ module BOAST
52
51
 
53
52
  def get_global_id(dim)
54
53
  if lang == CL then
55
- return FuncCall::new("get_global_id",dim, :returns => Sizet)
54
+ return FuncCall::new("get_global_id",dim, :return => Sizet)
56
55
  elsif lang == CUDA then
57
56
  d = OCL_CUDA_DIM_ASSOC[dim]
58
57
  raise "Unsupported dimension!" if not d
@@ -64,7 +63,7 @@ module BOAST
64
63
 
65
64
  def get_local_size(dim)
66
65
  if lang == CL then
67
- return FuncCall::new("get_local_size",dim, :returns => Sizet)
66
+ return FuncCall::new("get_local_size",dim, :return => Sizet)
68
67
  elsif lang == CUDA then
69
68
  d = OCL_CUDA_DIM_ASSOC[dim]
70
69
  raise "Unsupported dimension!" if not d
@@ -76,7 +75,7 @@ module BOAST
76
75
 
77
76
  def get_local_id(dim)
78
77
  if lang == CL then
79
- return FuncCall::new("get_local_id",dim, :returns => Sizet)
78
+ return FuncCall::new("get_local_id",dim, :return => Sizet)
80
79
  elsif lang == CUDA then
81
80
  d = OCL_CUDA_DIM_ASSOC[dim]
82
81
  raise "Unsupported dimension!" if not d
@@ -88,7 +87,7 @@ module BOAST
88
87
 
89
88
  def get_num_groups(dim)
90
89
  if lang == CL then
91
- return FuncCall::new("get_num_groups",dim, :returns => Sizet)
90
+ return FuncCall::new("get_num_groups",dim, :return => Sizet)
92
91
  elsif lang == CUDA then
93
92
  d = OCL_CUDA_DIM_ASSOC[dim]
94
93
  raise "Unsupported dimension!" if not d
@@ -100,7 +99,7 @@ module BOAST
100
99
 
101
100
  def get_group_id(dim)
102
101
  if lang == CL then
103
- return FuncCall::new("get_group_id",dim, :returns => Sizet)
102
+ return FuncCall::new("get_group_id",dim, :return => Sizet)
104
103
  elsif lang == CUDA then
105
104
  d = OCL_CUDA_DIM_ASSOC[dim]
106
105
  raise "Unsupported dimension!" if not d
@@ -6,6 +6,7 @@ module BOAST
6
6
  attr_reader :constants
7
7
 
8
8
  def initialize(constants = nil, &block)
9
+ super()
9
10
  @constants = constants
10
11
  @block = block
11
12
  end
@@ -61,11 +62,12 @@ module BOAST
61
62
  return self
62
63
  end
63
64
 
64
- def pr(*args)
65
+ def pr(*args, &block)
65
66
  args = @args if args.length == 0 and @args
67
+ block = @block unless block
66
68
  open
67
- if @block then
68
- @block.call(*args)
69
+ if block then
70
+ block.call(*args)
69
71
  close
70
72
  end
71
73
  return self
@@ -79,7 +81,12 @@ module BOAST
79
81
  attr_reader :expression
80
82
  attr_reader :case_conditions
81
83
 
84
+ # Creates a new instance of the Caonstruct
85
+ # @param [#to_s] expression tested Expression/Variable
86
+ # @param [Hash{#to_s, :default => Proc}] control conditions and associated blocks.
87
+ # @param [Proc,nil] block if provided, and :default is not defined in control (or nil), will be used as the default block.
82
88
  def initialize(expression, control = {}, &block)
89
+ super()
83
90
  @expression = expression
84
91
  @case_conditions = []
85
92
  default = control.delete(:default)
@@ -2,13 +2,17 @@ require 'os'
2
2
  require 'yaml'
3
3
 
4
4
  module BOAST
5
- FORTRAN = 1
6
- C = 2
7
- CL = 3
8
- CUDA = 4
9
- X86 = 1
10
- ARM = 2
11
- MPPA = 3
5
+
6
+ LANGUAGES = ['FORTRAN', 'C', 'CL', 'CUDA']
7
+ ARCHITECTURES = ['X86', 'ARM', 'MPPA']
8
+
9
+ LANGUAGES.each_with_index { |l, i|
10
+ const_set(l, i)
11
+ }
12
+
13
+ ARCHITECTURES.each_with_index { |a, i|
14
+ const_set(a, i)
15
+ }
12
16
 
13
17
  @@boast_config = {
14
18
  :fortran_line_length => 72
@@ -51,6 +55,7 @@ module BOAST
51
55
  private_state_accessor :architecture
52
56
  private_state_accessor :model
53
57
  private_state_accessor :address_size
58
+ private_state_accessor :default_type
54
59
  private_state_accessor :default_int_size
55
60
  private_state_accessor :default_real_size
56
61
  private_state_accessor :default_align
@@ -79,6 +84,7 @@ module BOAST
79
84
  state_accessor :architecture
80
85
  state_accessor :model
81
86
  state_accessor :address_size
87
+ state_accessor :default_type
82
88
  state_accessor :default_int_size
83
89
  state_accessor :default_real_size
84
90
  state_accessor :default_align
@@ -127,30 +133,48 @@ module BOAST
127
133
  class << self
128
134
  alias use_vla_old? use_vla?
129
135
  private :use_vla_old?
136
+ alias set_model_old set_model
137
+ private :set_model_old
138
+ alias model_old= model=
139
+ private :model_old=
130
140
  end
131
141
 
142
+ undef_method :use_vla?
132
143
  # @return the boolean evaluation of the *use_vla* state. false if lang is CL or CUDA.
133
144
  def use_vla?
134
145
  return false if [CL,CUDA].include?(lang)
135
146
  return use_vla_old?
136
147
  end
137
148
 
149
+ undef_method :set_model
138
150
  def set_model(val)
139
- @@model=val
151
+ set_model_old(val)
140
152
  Intrinsics::generate_conversions
141
153
  end
142
154
 
155
+ undef_method :model=
143
156
  def model=(val)
144
- @@model=val
157
+ set_model_old(val)
145
158
  Intrinsics::generate_conversions
146
159
  end
147
160
 
148
161
  # @private
149
162
  def get_default_architecture
150
- architecture = const_get(ENV["ARCHITECTURE"]) if ENV["ARCHITECTURE"]
151
- architecture = const_get(ENV["ARCH"]) if not architecture and ENV["ARCH"]
163
+ architecture = nil
164
+ begin
165
+ env = nil
166
+ if ENV["ARCHITECTURE"] then
167
+ env = ENV["ARCHITECTURE"]
168
+ elsif ENV["ARCH"] then
169
+ env = ENV["ARCH"]
170
+ end
171
+ raise "Error" if env and not ARCHITECTURES.include?(env)
172
+ architecture = const_get(env) if env
173
+ rescue
174
+ raise "'#{env}' is not a valid value for ARCH or ARCHITECTURE!"
175
+ end
152
176
  return architecture if architecture
153
- return ARM if YAML::load( OS.report )["host_cpu"].match("arm")
177
+ return ARM if YAML::load( OS.report )["host_cpu"].match(/arm|aarch64/)
154
178
  return X86
155
179
  end
156
180
 
@@ -21,16 +21,16 @@ module BOAST
21
21
 
22
22
  class << self
23
23
 
24
+ private
25
+
24
26
  def token_string_generator(name, *args)
25
- s = <<EOF
27
+ return <<EOF
26
28
  def #{name}_string(#{args.join(",")})
27
29
  return eval get_strings[get_lang][:#{name}]
28
30
  end
29
31
  EOF
30
32
  end
31
33
 
32
- private :token_string_generator
33
-
34
34
  end
35
35
 
36
36
  def [](*args)
@@ -38,6 +38,10 @@ EOF
38
38
  return self
39
39
  end
40
40
 
41
+ def initialize
42
+ @args = nil
43
+ end
44
+
41
45
  end
42
46
 
43
47
  end
@@ -9,6 +9,10 @@ module BOAST
9
9
  child.extend( VarFunctor)
10
10
  end
11
11
 
12
+ def vector?
13
+ return @vector_length
14
+ end
15
+
12
16
  end
13
17
 
14
18
  # @!parse module VarFunctors; var_functorize Sizet; end
@@ -259,6 +263,8 @@ module BOAST
259
263
 
260
264
  end
261
265
 
266
+ default_state_getter :default_type, Int, '"const_get(#{envs})"'
267
+
262
268
  # @!parse module VarFunctors; var_functorize CStruct; end
263
269
  class CStruct < DataType
264
270
 
@@ -13,6 +13,26 @@ module BOAST
13
13
 
14
14
  ANNOTATIONS = [:operator, :operand1, :operand2]
15
15
 
16
+ def method_missing(m, *a, &b)
17
+ var = to_var
18
+ if var.type.methods.include?(:members) and var.type.members[m.to_s] then
19
+ return struct_reference(type.members[m.to_s])
20
+ elsif var.vector? and m.to_s[0] == 's' and lang != CUDA then
21
+ required_set = m.to_s[1..-1].chars.to_a
22
+ existing_set = [*('0'..'9'),*('a'..'z')].first(var.type.vector_length)
23
+ if required_set.length == required_set.uniq.length and (required_set - existing_set).empty? then
24
+ return var.copy(var.name+"."+m.to_s, :vector_length => m.to_s[1..-1].length) if lang == CL
25
+ return var.copy("(#{var.name})(#{existing_set.index(required_set[0])+1})", :vector_length => 1) if lang == FORTRAN
26
+ return var.copy("(#{var.name})[#{existing_set.index(required_set[0])}]", :vector_length => 1) if lang == C
27
+ return super
28
+ else
29
+ return super
30
+ end
31
+ else
32
+ return super
33
+ end
34
+ end
35
+
16
36
  attr_reader :operator
17
37
  attr_reader :operand1
18
38
  attr_reader :operand2
@@ -20,6 +40,10 @@ module BOAST
20
40
  @operator = operator
21
41
  @operand1 = operand1
22
42
  @operand2 = operand2
43
+ if @operand1.nil? and @operand2.nil?
44
+ STDERR.puts "#{@operand1} #{@operand2}"
45
+ raise "Expression on no operand!"
46
+ end
23
47
  end
24
48
 
25
49
  def to_s_base(op1, op2, oper, return_type = nil)
@@ -59,8 +83,8 @@ module BOAST
59
83
  res_exp = to_s_base(op1, @operand2, @operator)
60
84
  return op1.copy(res_exp, :const => nil, :constant => nil, :direction => nil, :dir => nil, :align => nil)
61
85
  else
62
- STDERR.puts "#{@operand1} #{@operand2}"
63
- raise "Expression on no operand!"
86
+ res_exp = to_s_base(@operand1, @operand2, @operator)
87
+ return Variable::new(res_exp, get_default_type)
64
88
  end
65
89
  end
66
90