BOAST 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/BOAST.gemspec +4 -3
  3. data/lib/BOAST.rb +1 -0
  4. data/lib/BOAST/Language/Arithmetic.rb +5 -1
  5. data/lib/BOAST/Language/BOAST_OpenCL.rb +6 -6
  6. data/lib/BOAST/Language/Case.rb +11 -11
  7. data/lib/BOAST/Language/Comment.rb +2 -2
  8. data/lib/BOAST/Language/Config.rb +5 -5
  9. data/lib/BOAST/Language/DataTypes.rb +31 -29
  10. data/lib/BOAST/Language/Expression.rb +16 -16
  11. data/lib/BOAST/Language/For.rb +6 -6
  12. data/lib/BOAST/Language/FuncCall.rb +7 -7
  13. data/lib/BOAST/Language/HighLevelOperators.rb +6 -6
  14. data/lib/BOAST/Language/If.rb +7 -7
  15. data/lib/BOAST/Language/Index.rb +31 -31
  16. data/lib/BOAST/Language/Intrinsics.rb +27 -27
  17. data/lib/BOAST/Language/OpenMP.rb +19 -19
  18. data/lib/BOAST/Language/Operators.rb +62 -50
  19. data/lib/BOAST/Language/Pragma.rb +4 -4
  20. data/lib/BOAST/Language/Procedure.rb +47 -47
  21. data/lib/BOAST/Language/Slice.rb +14 -14
  22. data/lib/BOAST/Language/State.rb +1 -1
  23. data/lib/BOAST/Language/Transitions.rb +1 -1
  24. data/lib/BOAST/Language/Variable.rb +83 -90
  25. data/lib/BOAST/Language/While.rb +4 -4
  26. data/lib/BOAST/Optimization/Optimization.rb +61 -37
  27. data/lib/BOAST/Runtime/AffinityProbe.rb +99 -15
  28. data/lib/BOAST/Runtime/CRuntime.rb +18 -6
  29. data/lib/BOAST/Runtime/CUDARuntime.rb +11 -7
  30. data/lib/BOAST/Runtime/CoExecute.rb +77 -0
  31. data/lib/BOAST/Runtime/CompiledRuntime.rb +274 -110
  32. data/lib/BOAST/Runtime/Compilers.rb +15 -15
  33. data/lib/BOAST/Runtime/Config.rb +3 -0
  34. data/lib/BOAST/Runtime/EnergyProbe.rb +86 -71
  35. data/lib/BOAST/Runtime/FFIRuntime.rb +1 -1
  36. data/lib/BOAST/Runtime/FORTRANRuntime.rb +15 -5
  37. data/lib/BOAST/Runtime/MPPARuntime.rb +30 -19
  38. data/lib/BOAST/Runtime/OpenCLRuntime.rb +2 -2
  39. data/lib/BOAST/Runtime/Probe.rb +122 -41
  40. metadata +29 -8
@@ -38,7 +38,7 @@ module BOAST
38
38
  class BasicBinaryOperator < Operator
39
39
 
40
40
  def BasicBinaryOperator.string(arg1, arg2, return_type)
41
- if lang == C and (arg1.class == Variable and arg2.class == Variable) and (arg1.type.vector_length > 1 or arg2.type.vector_length > 1) then
41
+ if lang == C and (arg1.instance_of? Variable and arg2.instance_of? Variable) and (arg1.type.vector_length > 1 or arg2.type.vector_length > 1) then
42
42
  instruction = intrinsics(intr_symbol, return_type.type)
43
43
  a1 = convert(arg1, return_type.type)
44
44
  a2 = convert(arg2, return_type.type)
@@ -357,7 +357,7 @@ module BOAST
357
357
  elsif values.kind_of?(Array) then
358
358
  raise OperatorError, "Wrong number of mask values (#{values.length} for #{length})!" if length and values.length != length
359
359
  s = "0x"
360
- s += values.collect { |v| v != 0 ? 1 : 0 }.reverse.join
360
+ s << values.collect { |v| v != 0 ? 1 : 0 }.reverse.join
361
361
  @value = Int( s, :signed => false, :size => values.length / 8 + ( values.length % 8 > 0 ? 1 : 0 ), :constant => s )
362
362
  @length = values.length
363
363
  @pos_values = values.reject { |e| e == 0 }.length
@@ -434,7 +434,7 @@ module BOAST
434
434
  if lang == CL then
435
435
  return @return_type.copy("(#{@return_type.type.decl})( #{eff_src} )", DISCARD_OPTIONS) if lang == CL
436
436
  end
437
- if (@source.is_a?(Numeric) and @source == 0) or (@source.class == Variable and @source.constant == 0) then
437
+ if (@source.is_a?(Numeric) and @source == 0) or (@source.instance_of? Variable and @source.constant == 0) then
438
438
  begin
439
439
  instruction = intrinsics(:SETZERO, @return_type.type)
440
440
  return @return_type.copy("#{instruction}( )", DISCARD_OPTIONS) if instruction
@@ -464,9 +464,9 @@ module BOAST
464
464
 
465
465
  def pr
466
466
  s=""
467
- s += indent
468
- s += to_s
469
- s += ";" if [C, CL, CUDA].include?( lang )
467
+ s << indent
468
+ s << to_s
469
+ s << ";" if [C, CL, CUDA].include?( lang )
470
470
  output.puts s
471
471
  return self
472
472
  end
@@ -500,9 +500,9 @@ module BOAST
500
500
  tar = @target.to_var if @target.respond_to?(:to_var)
501
501
  src = @source
502
502
  src = @source.to_var if @source.respond_to?(:to_var)
503
- if tar.class == Variable and tar.type.vector_length > 1 then
503
+ if tar.instance_of? Variable and tar.type.vector_length > 1 then
504
504
  return @target.copy("#{@target} = #{Load(@source, @target, @options)}", DISCARD_OPTIONS)
505
- elsif src.class == Variable and src.type.vector_length > 1 then
505
+ elsif src.instance_of? Variable and src.type.vector_length > 1 then
506
506
  r_t, _ = transition(tar, src, Affectation)
507
507
  opts = @options.clone
508
508
  opts[:store_type] = r_t
@@ -517,9 +517,9 @@ module BOAST
517
517
 
518
518
  def pr
519
519
  s=""
520
- s += indent
521
- s += to_s
522
- s += ";" if [C, CL, CUDA].include?( lang )
520
+ s << indent
521
+ s << to_s
522
+ s << ";" if [C, CL, CUDA].include?( lang )
523
523
  output.puts s
524
524
  return self
525
525
  end
@@ -555,7 +555,7 @@ module BOAST
555
555
  if lang == C or lang == CL then
556
556
  if @source.kind_of?(Array) then
557
557
  return Set(@source, @return_type).to_var
558
- elsif @source.class == Variable or @source.respond_to?(:to_var) then
558
+ elsif @source.instance_of? Variable or @source.respond_to?(:to_var) then
559
559
  src_var = source.to_var
560
560
  if src_var.type == @return_type.type then
561
561
  return src_var
@@ -574,14 +574,14 @@ module BOAST
574
574
  if mask and not mask.full? then
575
575
  return Set(0, @return_type) if @zero and mask.empty?
576
576
  return @return_type if mask.empty?
577
- sym += "MASK"
578
- sym += "Z" if @zero
579
- sym += "_"
577
+ sym << "MASK"
578
+ sym << "Z" if @zero
579
+ sym << "_"
580
580
  end
581
581
  if src_var.alignment and @return_type.type.total_size and ( src_var.alignment % @return_type.type.total_size ) == 0 then
582
- sym += "LOADA"
582
+ sym << "LOADA"
583
583
  else
584
- sym += "LOAD"
584
+ sym << "LOAD"
585
585
  end
586
586
  instruction = intrinsics( sym.to_sym, @return_type.type)
587
587
  if mask and not mask.full? then
@@ -596,7 +596,7 @@ module BOAST
596
596
  elsif lang == FORTRAN then
597
597
  if @source.kind_of?(Array) then
598
598
  return Set(@source, @return_type).to_var
599
- elsif @source.class == Variable or @source.respond_to?(:to_var) then
599
+ elsif @source.instance_of? Variable or @source.respond_to?(:to_var) then
600
600
  if @source.to_var.type == @return_type.type then
601
601
  return @source.to_var
602
602
  elsif @source.kind_of?(Index) and @return_type.type.vector_length > 1 then
@@ -613,9 +613,9 @@ module BOAST
613
613
 
614
614
  def pr
615
615
  s=""
616
- s += indent
617
- s += to_s
618
- s += ";" if [C, CL, CUDA].include?( lang )
616
+ s << indent
617
+ s << to_s
618
+ s << ";" if [C, CL, CUDA].include?( lang )
619
619
  output.puts s
620
620
  return self
621
621
  end
@@ -667,7 +667,7 @@ module BOAST
667
667
  src = src[1..-1]
668
668
  end
669
669
  p_type = type.copy(:vector_length => 1)
670
- s += "#{instruction}( (#{p_type.decl} * ) #{src}, #{get_mask} )"
670
+ s << "#{instruction}( (#{p_type.decl} * ) #{src}, #{get_mask} )"
671
671
  return @return_type.copy( s, DISCARD_OPTIONS)
672
672
  end
673
673
 
@@ -677,9 +677,9 @@ module BOAST
677
677
 
678
678
  def pr
679
679
  s=""
680
- s += indent
681
- s += to_s
682
- s += ";" if [C, CL, CUDA].include?( lang )
680
+ s << indent
681
+ s << to_s
682
+ s << ";" if [C, CL, CUDA].include?( lang )
683
683
  output.puts s
684
684
  return self
685
685
  end
@@ -725,11 +725,11 @@ module BOAST
725
725
  mask = nil
726
726
  mask = Mask(@mask, :length => @store_type.type.vector_length) if @mask
727
727
  return "" if mask and mask.empty?
728
- sym += "MASK_" if mask and not mask.full?
728
+ sym << "MASK_" if mask and not mask.full?
729
729
  if @dest.alignment and type.total_size and ( @dest.alignment % type.total_size ) == 0 then
730
- sym += "STOREA"
730
+ sym << "STOREA"
731
731
  else
732
- sym += "STORE"
732
+ sym << "STORE"
733
733
  end
734
734
  instruction = intrinsics(sym.to_sym, type)
735
735
  p_type = type.copy(:vector_length => 1)
@@ -746,9 +746,9 @@ module BOAST
746
746
 
747
747
  def pr
748
748
  s=""
749
- s += indent
750
- s += to_s
751
- s += ";" if [C, CL, CUDA].include?( lang )
749
+ s << indent
750
+ s << to_s
751
+ s << ";" if [C, CL, CUDA].include?( lang )
752
752
  output.puts s
753
753
  return self
754
754
  end
@@ -799,16 +799,16 @@ module BOAST
799
799
  dst = dst[1..-1]
800
800
  end
801
801
  p_type = type.copy(:vector_length => 1)
802
- return s += "#{instruction}( (#{p_type.decl} * ) #{dst}, #{get_mask}, #{Operator.convert(@source, type)} )"
802
+ return s << "#{instruction}( (#{p_type.decl} * ) #{dst}, #{get_mask}, #{Operator.convert(@source, type)} )"
803
803
  end
804
804
 
805
805
  def pr
806
806
  ss = to_s
807
807
  if ss then
808
808
  s=""
809
- s += indent
810
- s += ss
811
- s += ";" if [C, CL, CUDA].include?( lang )
809
+ s << indent
810
+ s << ss
811
+ s << ";" if [C, CL, CUDA].include?( lang )
812
812
  output.puts s
813
813
  end
814
814
  return self
@@ -877,9 +877,9 @@ module BOAST
877
877
 
878
878
  def pr
879
879
  s=""
880
- s += indent
881
- s += to_s
882
- s += ";" if [C, CL, CUDA].include?( lang )
880
+ s << indent
881
+ s << to_s
882
+ s << ";" if [C, CL, CUDA].include?( lang )
883
883
  output.puts s
884
884
  return self
885
885
  end
@@ -948,9 +948,9 @@ module BOAST
948
948
 
949
949
  def pr
950
950
  s=""
951
- s += indent
952
- s += to_s
953
- s += ";" if [C, CL, CUDA].include?( lang )
951
+ s << indent
952
+ s << to_s
953
+ s << ";" if [C, CL, CUDA].include?( lang )
954
954
  output.puts s
955
955
  return self
956
956
  end
@@ -982,9 +982,9 @@ module BOAST
982
982
 
983
983
  def pr
984
984
  s=""
985
- s += indent
986
- s += to_s
987
- s += ";" if [C, CL, CUDA].include?( lang )
985
+ s << indent
986
+ s << to_s
987
+ s << ";" if [C, CL, CUDA].include?( lang )
988
988
  output.puts s
989
989
  return self
990
990
  end
@@ -1002,7 +1002,7 @@ module BOAST
1002
1002
  def to_s_fortran
1003
1003
  op1, op2 = op_to_var
1004
1004
  if @return_type and @return_type.type.kind_of?(Real) and ( not op1.type.kind_of?(Real) or not op2.type.kind_of?(Real) ) then
1005
- return "modulo(real(#{op1}, #{@return_type.type.size}), #{op2})" if not op1.type.kind_of?(Real)
1005
+ return "modulo(real(#{op1}, #{@return_type.type.size}), #{op2})" unless op1.type.kind_of?(Real)
1006
1006
  return "modulo(#{op1}, real(#{op2}, #{@return_type.type.size}))"
1007
1007
  else
1008
1008
  return "modulo(#{op1}, #{op2})"
@@ -1013,12 +1013,24 @@ module BOAST
1013
1013
  op1, op2 = op_to_var
1014
1014
  if @return_type and @return_type.type.kind_of?(Real) then
1015
1015
  if @return_type.type.size <= 4 then
1016
- return "((#{op1} < 0) ^ (#{op2} < 0) ? fmodf(#{op1}, #{op2}) + #{op2} : fmodf(#{op1}, #{op2}));"
1016
+ return "((#{op1} < 0) ^ (#{op2} < 0) ? fmodf(#{op1}, #{op2}) + #{op2} : fmodf(#{op1}, #{op2}))"
1017
1017
  else
1018
1018
  return "((#{op1} < 0) ^ (#{op2} < 0) ? fmod(#{op1}, #{op2}) + #{op2} : fmod(#{op1}, #{op2}))"
1019
1019
  end
1020
1020
  else
1021
- return "((#{op1} < 0) ^ (#{op2} < 0) ? (#{op1} % #{op2}) + #{op2} : #{op1} % #{op2})"
1021
+ test_op1 = true
1022
+ test_op1 = false if op1.respond_to?(:type) and op1.type.respond_to?(:signed?) and not op1.type.signed?
1023
+ test_op2 = true
1024
+ test_op2 = false if op2.respond_to?(:type) and op2.type.respond_to?(:signed?) and not op2.type.signed?
1025
+ if test_op1 and test_op2 then
1026
+ return "((#{op1} < 0) ^ (#{op2} < 0) ? (#{op1} % #{op2}) + #{op2} : #{op1} % #{op2})"
1027
+ elsif test_op1 then
1028
+ return "( (#{op1} < 0) ? (#{op1} % #{op2.cast(op1)}) + #{op2} : #{op1} % #{op2})"
1029
+ elsif test_op2 then
1030
+ return "( (#{op2} < 0) ? (#{op1.cast(op2)} % #{op2}) + #{op2} : #{op1} % #{op2})"
1031
+ else
1032
+ return "(#{op1} % #{op2})"
1033
+ end
1022
1034
  end
1023
1035
  end
1024
1036
 
@@ -1056,9 +1068,9 @@ module BOAST
1056
1068
 
1057
1069
  def pr
1058
1070
  s=""
1059
- s += indent
1060
- s += to_s
1061
- s += ";" if [C, CL, CUDA].include?( lang )
1071
+ s << indent
1072
+ s << to_s
1073
+ s << ";" if [C, CL, CUDA].include?( lang )
1062
1074
  output.puts s
1063
1075
  return self
1064
1076
  end
@@ -17,19 +17,19 @@ module BOAST
17
17
  def to_s
18
18
  s = ""
19
19
  if lang == FORTRAN then
20
- s += "!#{@name}$"
20
+ s << "!#{@name}$"
21
21
  else
22
- s += "#pragma #{name}"
22
+ s << "#pragma #{name}"
23
23
  end
24
24
  @options.each{ |opt|
25
- s += " #{opt}"
25
+ s << " #{opt}"
26
26
  }
27
27
  return s
28
28
  end
29
29
 
30
30
  def pr
31
31
  s=""
32
- s += to_s
32
+ s << to_s
33
33
  output.puts s
34
34
  return self
35
35
  end
@@ -39,14 +39,14 @@ module BOAST
39
39
  # @private
40
40
  def boast_header(lang=C)
41
41
  s = boast_header_s(lang)
42
- s += ";\n"
42
+ s << ";\n"
43
43
  output.print s
44
44
  return self
45
45
  end
46
46
 
47
47
  def call(*parameters)
48
48
  prefix = ""
49
- prefix += "call " if lang==FORTRAN and @properties[:return].nil?
49
+ prefix << "call " if lang==FORTRAN and @properties[:return].nil?
50
50
  f = FuncCall::new(@name, *parameters, :return => @properties[:return] )
51
51
  f.prefix = prefix
52
52
  return f
@@ -114,50 +114,50 @@ module BOAST
114
114
  s = ""
115
115
  if lang == CL then
116
116
  if @properties[:local] then
117
- s += "#if __OPENCL_C_VERSION__ && __OPENCL_C_VERSION__ >= 120\n"
118
- s += "static\n"
119
- s += "#endif\n"
117
+ s << "#if __OPENCL_C_VERSION__ && __OPENCL_C_VERSION__ >= 120\n"
118
+ s << "static\n"
119
+ s << "#endif\n"
120
120
  else
121
- s += "__kernel "
121
+ s << "__kernel "
122
122
  wgs = @properties[:reqd_work_group_size]
123
123
  if wgs then
124
- s += "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
124
+ s << "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
125
125
  end
126
126
  end
127
127
  elsif lang == CUDA then
128
128
  if @properties[:local] then
129
- s += "static __device__ "
129
+ s << "static __device__ "
130
130
  else
131
- s += "__global__ "
131
+ s << "__global__ "
132
132
  wgs = @properties[:reqd_work_group_size]
133
133
  if wgs then
134
- s += "__launch_bounds__(#{wgs[0]}*#{wgs[1]}*#{wgs[2]}) "
134
+ s << "__launch_bounds__(#{wgs[0]}*#{wgs[1]}*#{wgs[2]}) "
135
135
  end
136
136
  end
137
137
  elsif lang == C then
138
138
  if @properties[:local] then
139
- s += "static "
139
+ s << "static "
140
140
  end
141
141
  if @properties[:inline] then
142
- s+= "inline "
142
+ s << "inline "
143
143
  end
144
144
  end
145
145
  if @properties[:qualifiers] then
146
- s += "#{@properties[:qualifiers]} "
146
+ s << "#{@properties[:qualifiers]} "
147
147
  end
148
148
  if @properties[:return] then
149
- s += "#{@properties[:return].type.decl} "
149
+ s << "#{@properties[:return].type.decl} "
150
150
  else
151
- s += "void "
151
+ s << "void "
152
152
  end
153
- s += "#{@name}("
153
+ s << "#{@name}("
154
154
  if @parameters.first then
155
- s += @parameters.first.send(:decl_c_s, @properties[:local])
155
+ s << @parameters.first.send(:decl_c_s, @properties[:local])
156
156
  @parameters[1..-1].each { |p|
157
- s += ", "+p.send(:decl_c_s, @properties[:local])
157
+ s << ", "+p.send(:decl_c_s, @properties[:local])
158
158
  }
159
159
  end
160
- s += ")"
160
+ s << ")"
161
161
  return s
162
162
  end
163
163
 
@@ -170,13 +170,13 @@ module BOAST
170
170
  def to_s_fortran
171
171
  s = ""
172
172
  if @properties[:return] then
173
- s += "#{@properties[:return].type.decl} FUNCTION "
173
+ s << "#{@properties[:return].type.decl} FUNCTION "
174
174
  else
175
- s += "SUBROUTINE "
175
+ s << "SUBROUTINE "
176
176
  end
177
- s += "#{@name}("
178
- s += @parameters.collect(&:name).join(", ")
179
- s += ")"
177
+ s << "#{@name}("
178
+ s << @parameters.collect(&:name).join(", ")
179
+ s << ")"
180
180
  end
181
181
 
182
182
  def open_c
@@ -205,7 +205,7 @@ module BOAST
205
205
 
206
206
  def open_fortran
207
207
  s = indent + to_s_fortran
208
- s += "\n"
208
+ s << "\n"
209
209
  increment_indent_level
210
210
  tmp_buff = StringIO::new
211
211
  push_env( :output => tmp_buff ) {
@@ -214,8 +214,8 @@ module BOAST
214
214
  }
215
215
  }
216
216
  tmp_buff.rewind
217
- s += tmp_buff.read
218
- s += indent + "integer, parameter :: wp=kind(1.0d0)"
217
+ s << tmp_buff.read
218
+ s << indent + "integer, parameter :: wp=kind(1.0d0)"
219
219
  output.puts s
220
220
  @constants.each { |c|
221
221
  BOAST::decl c
@@ -247,9 +247,9 @@ module BOAST
247
247
 
248
248
  def close_c
249
249
  s = ""
250
- s += indent + "return #{@properties[:return]};\n" if @properties[:return]
250
+ s << indent + "return #{@properties[:return]};\n" if @properties[:return]
251
251
  decrement_indent_level
252
- s += indent + "}"
252
+ s << indent + "}"
253
253
  output.puts s
254
254
  return self
255
255
  end
@@ -257,12 +257,12 @@ module BOAST
257
257
  def close_fortran
258
258
  s = ""
259
259
  if @properties[:return] then
260
- s += indent + "#{@name} = #{@properties[:return]}\n"
260
+ s << indent + "#{@name} = #{@properties[:return]}\n"
261
261
  decrement_indent_level
262
- s += indent + "END FUNCTION #{@name}"
262
+ s << indent + "END FUNCTION #{@name}"
263
263
  else
264
264
  decrement_indent_level
265
- s += indent + "END SUBROUTINE #{@name}"
265
+ s << indent + "END SUBROUTINE #{@name}"
266
266
  end
267
267
  output.puts s
268
268
  return self
@@ -271,38 +271,38 @@ module BOAST
271
271
  def boast_header_s( lang=C )
272
272
  s = ""
273
273
  headers.each { |h|
274
- s += "#include <#{h}>\n"
274
+ s << "#include <#{h}>\n"
275
275
  }
276
276
  if lang == CL then
277
- s += "__kernel "
277
+ s << "__kernel "
278
278
  wgs = @properties[:reqd_work_group_size]
279
279
  if wgs then
280
- s += "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
280
+ s << "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
281
281
  end
282
282
  end
283
283
  trailer = ""
284
- trailer += "_" if lang == FORTRAN
285
- trailer += "_wrapper" if lang == CUDA
284
+ trailer << "_" if lang == FORTRAN
285
+ trailer << "_wrapper" if lang == CUDA
286
286
  if @properties[:return] then
287
- s += "#{@properties[:return].type.decl} "
287
+ s << "#{@properties[:return].type.decl} "
288
288
  elsif lang == CUDA
289
- s += "unsigned long long int "
289
+ s << "unsigned long long int "
290
290
  else
291
- s += "void "
291
+ s << "void "
292
292
  end
293
- s += "#{@name}#{trailer}("
293
+ s << "#{@name}#{trailer}("
294
294
  if @parameters.first then
295
- s += @parameters.first.boast_header(lang)
295
+ s << @parameters.first.boast_header(lang)
296
296
  @parameters[1..-1].each { |p|
297
- s += ", "
298
- s += p.boast_header(lang)
297
+ s << ", "
298
+ s << p.boast_header(lang)
299
299
  }
300
300
  end
301
301
  if lang == CUDA then
302
- s += ", " if parameters.first
303
- s += "size_t *_boast_block_number, size_t *_boast_block_size, int _boast_repeat"
302
+ s << ", " if parameters.first
303
+ s << "size_t *_boast_block_number, size_t *_boast_block_size, int _boast_repeat"
304
304
  end
305
- s += ")"
305
+ s << ")"
306
306
  return s
307
307
  end
308
308