BOAST 1.0.9 → 1.1.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.
@@ -11,7 +11,7 @@ module BOAST
11
11
  elsif lang == C then
12
12
  s += "#pragma omp"
13
13
  else
14
- raise "Language does not support OpenMP!"
14
+ raise LanguageError, "Language does not support OpenMP!"
15
15
  end
16
16
  return s
17
17
  end
@@ -1,5 +1,8 @@
1
1
  module BOAST
2
2
 
3
+ class OperatorError < Error
4
+ end
5
+
3
6
  class Operator
4
7
  extend PrivateStateAccessor
5
8
  extend Intrinsics
@@ -11,10 +14,10 @@ module BOAST
11
14
  end
12
15
 
13
16
  def Operator.convert(arg, type)
17
+ return "#{arg}" if get_vector_name(arg.type) == get_vector_name(type) or lang == CUDA
14
18
  return "convert_#{type.decl}( #{arg} )" if lang == CL
15
19
 
16
20
  path = get_conversion_path(type, arg.type)
17
- raise "Unavailable conversion from #{get_vector_name(arg.type)} to #{get_vector_name(type)}!" if not path
18
21
  s = "#{arg}"
19
22
  if path.length > 1 then
20
23
  path.each_cons(2) { |slice|
@@ -29,10 +32,9 @@ module BOAST
29
32
 
30
33
  class BasicBinaryOperator < Operator
31
34
 
32
- def BasicBinaryOperator.to_s(arg1, arg2, return_type)
35
+ def BasicBinaryOperator.string(arg1, arg2, return_type)
33
36
  if lang == C and (arg1.class == Variable and arg2.class == Variable) and (arg1.type.vector_length > 1 or arg2.type.vector_length > 1) then
34
37
  instruction = intrinsics(intr_symbol, return_type.type)
35
- raise "Unavailable operator #{symbol} for #{get_vector_name(return_type.type)}!" unless instruction
36
38
  a1 = convert(arg1, return_type.type)
37
39
  a2 = convert(arg2, return_type.type)
38
40
  return "#{instruction}( #{a1}, #{a2} )"
@@ -43,9 +45,63 @@ module BOAST
43
45
 
44
46
  end
45
47
 
48
+ class Minus < Operator
49
+
50
+ def Minus.string(arg1, arg2, return_type)
51
+ return " -(#{arg2})"
52
+ end
53
+
54
+ end
55
+
56
+ class Plus < Operator
57
+
58
+ def Plus.string(arg1, arg2, return_type)
59
+ return " +#{arg2}"
60
+ end
61
+
62
+ end
63
+
64
+ class Not < Operator
65
+
66
+ def Not.string(arg1, arg2, return_type)
67
+ return " (.not. (#{arg2}))" if lang == FORTRAN
68
+ return " !(#{arg2})"
69
+ end
70
+
71
+ end
72
+
73
+ class Reference < Operator
74
+
75
+ def Reference.string(arg1, arg2, return_type)
76
+ return " #{arg2}" if lang == FORTRAN
77
+ return " &#{arg2}"
78
+ end
79
+
80
+ end
81
+
82
+ class Dereference < Operator
83
+
84
+ def Dereference.string(arg1, arg2, return_type)
85
+ return " *(#{arg2})"
86
+ end
87
+
88
+ end
89
+
90
+ class Equal < Operator
91
+
92
+ def Equal.string(arg1, arg2, return_type)
93
+ return basic_usage(arg1, arg2)
94
+ end
95
+
96
+ def Equal.basic_usage(arg1, arg2)
97
+ return "#{arg1} == #{arg2}"
98
+ end
99
+
100
+ end
101
+
46
102
  class Different < Operator
47
103
 
48
- def Different.to_s(arg1, arg2, return_type)
104
+ def Different.string(arg1, arg2, return_type)
49
105
  return basic_usage(arg1, arg2)
50
106
  end
51
107
 
@@ -56,9 +112,83 @@ module BOAST
56
112
 
57
113
  end
58
114
 
115
+ class Greater < Operator
116
+
117
+ def Greater.string(arg1, arg2, return_type)
118
+ return basic_usage(arg1, arg2)
119
+ end
120
+
121
+ def Greater.basic_usage(arg1, arg2)
122
+ return "#{arg1} > #{arg2}"
123
+ end
124
+
125
+ end
126
+
127
+ class Less < Operator
128
+
129
+ def Less.string(arg1, arg2, return_type)
130
+ return basic_usage(arg1, arg2)
131
+ end
132
+
133
+ def Less.basic_usage(arg1, arg2)
134
+ return "#{arg1} < #{arg2}"
135
+ end
136
+
137
+ end
138
+
139
+ class GreaterOrEqual < Operator
140
+
141
+ def GreaterOrEqual.string(arg1, arg2, return_type)
142
+ return basic_usage(arg1, arg2)
143
+ end
144
+
145
+ def GreaterOrEqual.basic_usage(arg1, arg2)
146
+ return "#{arg1} >= #{arg2}"
147
+ end
148
+
149
+ end
150
+
151
+ class LessOrEqual < Operator
152
+
153
+ def LessOrEqual.string(arg1, arg2, return_type)
154
+ return basic_usage(arg1, arg2)
155
+ end
156
+
157
+ def LessOrEqual.basic_usage(arg1, arg2)
158
+ return "#{arg1} <= #{arg2}"
159
+ end
160
+
161
+ end
162
+
163
+ class And < Operator
164
+
165
+ def And.string(arg1, arg2, return_type)
166
+ return basic_usage(arg1, arg2)
167
+ end
168
+
169
+ def And.basic_usage(arg1, arg2)
170
+ return "#{arg1} .and. #{arg2}" if lang == FORTRAN
171
+ return "#{arg1} && #{arg2}"
172
+ end
173
+
174
+ end
175
+
176
+ class Or < Operator
177
+
178
+ def Or.string(arg1, arg2, return_type)
179
+ return basic_usage(arg1, arg2)
180
+ end
181
+
182
+ def Or.basic_usage(arg1, arg2)
183
+ return "#{arg1} .or. #{arg2}" if lang == FORTRAN
184
+ return "#{arg1} || #{arg2}"
185
+ end
186
+
187
+ end
188
+
59
189
  class Affectation < Operator
60
190
 
61
- def Affectation.to_s(arg1, arg2, return_type)
191
+ def Affectation.string(arg1, arg2, return_type)
62
192
  if arg1.class == Variable and arg1.type.vector_length > 1 then
63
193
  return "#{arg1} = #{Load(arg2, arg1)}"
64
194
  elsif arg2.class == Variable and arg2.type.vector_length > 1 then
@@ -73,6 +203,27 @@ module BOAST
73
203
 
74
204
  end
75
205
 
206
+ class Exponentiation < BasicBinaryOperator
207
+
208
+ class << self
209
+
210
+ def symbol
211
+ return "**"
212
+ end
213
+
214
+ def intr_symbol
215
+ return :POW
216
+ end
217
+
218
+ def basic_usage(arg1, arg2)
219
+ return "(#{arg1})**(#{arg2})" if lang == FORTRAN
220
+ return "pow(#{arg1}, #{arg2})"
221
+ end
222
+
223
+ end
224
+
225
+ end
226
+
76
227
  class Multiplication < BasicBinaryOperator
77
228
 
78
229
  class << self
@@ -153,22 +304,6 @@ module BOAST
153
304
 
154
305
  end
155
306
 
156
- class Minus < Operator
157
-
158
- def Minus.to_s(arg1, arg2, return_type)
159
- return " -(#{arg2})"
160
- end
161
-
162
- end
163
-
164
- class Not < Operator
165
-
166
- def Not.to_s(arg1, arg2, return_type)
167
- return " ! #{arg2}"
168
- end
169
-
170
- end
171
-
172
307
  class Set < Operator
173
308
  extend Functor
174
309
  include Intrinsics
@@ -191,24 +326,24 @@ module BOAST
191
326
  def to_var
192
327
  if lang == C or lang == CL and @return_type.type.vector_length > 1 then
193
328
  if @source.kind_of?( Array ) then
194
- raise "Invalid array length!" unless @source.length == @return_type.type.vector_length
329
+ raise OperatorError, "Invalid array length!" unless @source.length == @return_type.type.vector_length
195
330
  return @return_type.copy("(#{@return_type.type.decl})( #{@source.join(", ")} )", DISCARD_OPTIONS) if lang == CL
196
331
 
197
- instruction = intrinsics(:SET, @return_type.type)
198
- return @return_type.copy("#{instruction}( #{@source.join(", ")} )", DISCARD_OPTIONS) if instruction
199
-
200
- instruction = intrinsics(:SET_LANE, @return_type.type)
201
- raise "Unavailable operator set for #{get_vector_name(@return_type.type)}!" unless instruction
202
- s = Set(0, @return_type).to_s
203
- @source.each_with_index { |v,i|
204
- s = "#{instruction}(#{v}, #{s}, #{i})"
205
- }
206
- return @return_type.copy(s, DISCARD_OPTIONS)
332
+ begin
333
+ instruction = intrinsics(:SET, @return_type.type)
334
+ return @return_type.copy("#{instruction}( #{@source.join(", ")} )", DISCARD_OPTIONS)
335
+ rescue IntrinsicsError
336
+ instruction = intrinsics(:SET_LANE, @return_type.type)
337
+ s = Set(0, @return_type).to_s
338
+ @source.each_with_index { |v,i|
339
+ s = "#{instruction}(#{v}, #{s}, #{i})"
340
+ }
341
+ return @return_type.copy(s, DISCARD_OPTIONS)
342
+ end
207
343
  elsif @source.class != Variable or @source.type.vector_length == 1 then
208
344
  return @return_type.copy("(#{@return_type.type.decl})( #{@source} )", DISCARD_OPTIONS) if lang == CL
209
345
 
210
346
  instruction = intrinsics(:SET1, @return_type.type)
211
- raise "Unavailable operator set1 for #{get_vector_name(@return_type.type)}!" unless instruction
212
347
  return @return_type.copy("#{instruction}( #{@source} )", DISCARD_OPTIONS)
213
348
  elsif @return_type.type != @source.type
214
349
  return @return_type.copy("#{Operator.convert(@source, @return_type.type)}", DISCARD_OPTIONS)
@@ -267,12 +402,11 @@ module BOAST
267
402
  end
268
403
  return @return_type.copy("vload#{@return_type.type.vector_length}(0, #{a2})", DISCARD_OPTIONS) if lang == CL
269
404
  return @return_type.copy("_m_from_int64( *((int64_t * ) #{a2} ) )", DISCARD_OPTIONS) if get_architecture == X86 and @return_type.type.total_size*8 == 64
270
- if @source.align == @return_type.type.total_size then
405
+ if @source.alignment == @return_type.type.total_size then
271
406
  instruction = intrinsics(:LOADA, @return_type.type)
272
407
  else
273
408
  instruction = intrinsics(:LOAD, @return_type.type)
274
409
  end
275
- raise "Unavailable operator load for #{get_vector_name(@return_type.type)}!" unless instruction
276
410
  return @return_type.copy("#{instruction}( #{a2} )", DISCARD_OPTIONS)
277
411
  else
278
412
  return @return_type.copy("#{Operator.convert(@source, @return_type.type)}", DISCARD_OPTIONS)
@@ -315,7 +449,7 @@ module BOAST
315
449
  end
316
450
 
317
451
  def get_mask
318
- raise "Mask size is wrong: #{@mask.length} for #{@return_type.type.vector_length}!" if @mask.length != @return_type.type.vector_length
452
+ raise OperatorError, "Mask size is wrong: #{@mask.length} for #{@return_type.type.vector_length}!" if @mask.length != @return_type.type.vector_length
319
453
  return Load(@mask.collect { |m| ( m and m != 0 ) ? -1 : 0 }, Int("mask", :size => @return_type.type.size, :vector_length => @return_type.type.vector_length ) )
320
454
  end
321
455
 
@@ -326,9 +460,9 @@ module BOAST
326
460
  end
327
461
 
328
462
  def to_var
329
- raise "Cannot load unknown type!" unless @return_type
330
- raise "Unsupported language!" unless lang == C
331
- raise "MaskLoad not supported!"unless supported(:MASKLOAD, @return_type.type)
463
+ raise OperatorError, "Cannot load unknown type!" unless @return_type
464
+ raise LanguageError, "Unsupported language!" unless lang == C
465
+ instruction = intrinsics(:MASKLOAD, @return_type.type)
332
466
  s = ""
333
467
  src = "#{@source}"
334
468
  if src[0] != "*" then
@@ -337,7 +471,7 @@ module BOAST
337
471
  src = src[1..-1]
338
472
  end
339
473
  p_type = @return_type.type.copy(:vector_length => 1)
340
- s += "#{intrinsics(:MASKLOAD, @return_type.type)}((#{p_type.decl} * )#{src}, #{get_mask})"
474
+ s += "#{instruction}((#{p_type.decl} * )#{src}, #{get_mask})"
341
475
  return @return_type.copy( s, DISCARD_OPTIONS)
342
476
  end
343
477
 
@@ -386,12 +520,11 @@ module BOAST
386
520
  return "vstore#{@source.type.vector_length}(#{@source}, 0, #{dst})" if lang == CL
387
521
  return "*((int64_t * ) #{dst}) = _m_to_int64( #{@source} )" if get_architecture == X86 and @source.type.total_size*8 == 64
388
522
 
389
- if @dest.align == @source.type.total_size then
523
+ if @dest.alignment == @source.type.total_size then
390
524
  instruction = intrinsics(:STOREA, @source.type)
391
525
  else
392
526
  instruction = intrinsics(:STORE, @source.type)
393
527
  end
394
- raise "Unavailable operator store for #{get_vector_name(@source.type)}!" unless instruction
395
528
  p_type = @source.type.copy(:vector_length => 1)
396
529
  p_type = @source.type if get_architecture == X86 and @source.type.kind_of?(Int)
397
530
  return "#{instruction}( (#{p_type.decl} * ) #{dst}, #{@source} )"
@@ -431,16 +564,16 @@ module BOAST
431
564
  end
432
565
 
433
566
  def get_mask
434
- raise "Mask size is wrong: #{@mask.length} for #{@store_type.type.vector_length}!" if @mask.length != @store_type.type.vector_length
567
+ raise OperatorError, "Mask size is wrong: #{@mask.length} for #{@store_type.type.vector_length}!" if @mask.length != @store_type.type.vector_length
435
568
  return Load.to_s(@mask.collect { |m| ( m and m != 0 ) ? -1 : 0 }, Int("mask", :size => @store_type.type.size, :vector_length => @store_type.type.vector_length ) )
436
569
  end
437
570
 
438
571
  private :get_mask
439
572
 
440
573
  def to_s
441
- raise "Cannot store unknown type!" unless @store_type
442
- raise "Unsupported language!" unless lang == C
443
- raise "MaskStore not supported!"unless supported(:MASKSTORE, @store_type.type)
574
+ raise OperatorError, "Cannot store unknown type!" unless @store_type
575
+ raise LanguageError, "Unsupported language!" unless lang == C
576
+ instruction = intrinsics(:MASKSTORE, @store_type.type)
444
577
  s = ""
445
578
  dst = "#{@dest}"
446
579
  if dst[0] != "*" then
@@ -449,7 +582,7 @@ module BOAST
449
582
  dst = dst[1..-1]
450
583
  end
451
584
  p_type = @store_type.type.copy(:vector_length => 1)
452
- return s += "#{intrinsics(:MASKSTORE, @store_type.type)}((#{p_type.decl} * )#{dst}, #{get_mask}, #{Operator.convert(@source, @store_type.type)})"
585
+ return s += "#{instruction}((#{p_type.decl} * )#{dst}, #{get_mask}, #{Operator.convert(@source, @store_type.type)})"
453
586
  end
454
587
 
455
588
  def pr
@@ -494,7 +627,12 @@ module BOAST
494
627
  end
495
628
 
496
629
  def to_var
497
- return (@operand3 + @operand1 * @operand2).to_var unless lang != FORTRAN and @return_type and ( supported(:FMADD, @return_type.type) or ( [CL, CUDA].include?(lang) ) )
630
+ instruction = nil
631
+ begin
632
+ instruction = intrinsics(:FMADD,@return_type.type)
633
+ rescue
634
+ end
635
+ return (@operand3 + @operand1 * @operand2).to_var unless lang != FORTRAN and @return_type and ( instruction or ( [CL, CUDA].include?(lang) ) )
498
636
  op1 = convert_operand(@operand1)
499
637
  op2 = convert_operand(@operand2)
500
638
  op3 = convert_operand(@operand3)
@@ -503,9 +641,9 @@ module BOAST
503
641
  else
504
642
  case architecture
505
643
  when X86
506
- ret_name = "#{intrinsics(:FMADD,@return_type.type)}(#{op1},#{op2},#{op3})"
644
+ ret_name = "#{instruction}(#{op1},#{op2},#{op3})"
507
645
  when ARM
508
- ret_name = "#{intrinsics(:FMADD,@return_type.type)}(#{op2},#{op3},#{op1})"
646
+ ret_name = "#{instruction}(#{op2},#{op3},#{op1})"
509
647
  else
510
648
  return (@operand1 * @operand2 + @operand3).to_var
511
649
  end
@@ -544,14 +682,31 @@ module BOAST
544
682
  @operand3 = z
545
683
  end
546
684
 
685
+ def op_to_var
686
+ op1 = @operand1.respond_to?(:to_var) ? @operand1.to_var : @operand1
687
+ op1 = @operand1 unless op1
688
+ op2 = @operand2.respond_to?(:to_var) ? @operand2.to_var : @operand2
689
+ op2 = @operand2 unless op2
690
+ op3 = @operand3.respond_to?(:to_var) ? @operand3.to_var : @operand3
691
+ op3 = @operand3 unless op3
692
+ return [op1, op2, op3]
693
+ end
694
+
695
+ private :op_to_var
696
+
547
697
  def to_s
548
- raise "Ternary operator unsupported in FORTRAN!" if lang == FORTRAN
698
+ return to_s_fortran if lang == FORTRAN
549
699
  return to_s_c if [C, CL, CUDA].include?( lang )
550
700
  end
551
701
 
702
+ def to_s_fortran
703
+ op1, op2, op3 = op_to_var
704
+ "merge(#{op2}, #{op3}, #{op1})"
705
+ end
706
+
552
707
  def to_s_c
553
- s = ""
554
- s += "(#{@operand1} ? #{@operand2} : #{@operand3})"
708
+ op1, op2, op3 = op_to_var
709
+ "(#{op1} ? #{op2} : #{op3})"
555
710
  end
556
711
 
557
712
  def pr
@@ -8,7 +8,7 @@ module BOAST
8
8
  attr_reader :name
9
9
  attr_reader :options
10
10
 
11
- def initialize(name, options)
11
+ def initialize(name, *options)
12
12
  @name = name
13
13
  @options = options
14
14
  end
@@ -16,9 +16,9 @@ module BOAST
16
16
  def to_s
17
17
  s = ""
18
18
  if lang == FORTRAN then
19
- s += "$!"
19
+ s += "!#{@name}$"
20
20
  else
21
- s += "#pragma"
21
+ s += "#pragma #{name}"
22
22
  end
23
23
  @options.each{ |opt|
24
24
  s += " #{opt}"
@@ -1,11 +1,11 @@
1
1
  module BOAST
2
2
 
3
- def self.print(a)
4
- a.pr
3
+ def self.print(a, *args)
4
+ pr(a, *args)
5
5
  end
6
6
 
7
7
  def self.open(a)
8
- a.open
8
+ opn(a)
9
9
  end
10
10
 
11
11
  end