BOAST 1.3.5 → 2.0.0

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