BOAST 1.0.7 → 1.0.8
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.
- checksums.yaml +4 -4
- data/BOAST.gemspec +2 -1
- data/lib/BOAST/Language/Algorithm.rb +33 -28
- data/lib/BOAST/Language/Architectures.rb +210 -0
- data/lib/BOAST/Language/CPUID_by_name.rb +5675 -0
- data/lib/BOAST/Language/DataTypes.rb +24 -85
- data/lib/BOAST/Language/Index.rb +12 -0
- data/lib/BOAST/Language/Inspectable.rb +1 -1
- data/lib/BOAST/Language/Intrinsics.rb +148 -10
- data/lib/BOAST/Language/Operators.rb +376 -136
- data/lib/BOAST/Language/Procedure.rb +1 -1
- data/lib/BOAST/Language/State.rb +14 -0
- data/lib/BOAST/Language/Transitions.rb +1 -1
- data/lib/BOAST/Language/Variable.rb +81 -31
- data/lib/BOAST/Runtime/CKernel.rb +6 -2
- data/lib/BOAST/Runtime/CRuntime.rb +1 -0
- data/lib/BOAST/Runtime/CompiledRuntime.rb +9 -12
- data/lib/BOAST/Runtime/Compilers.rb +3 -0
- data/lib/BOAST/Runtime/Config.rb +5 -7
- data/lib/BOAST/Runtime/FORTRANRuntime.rb +19 -11
- data/lib/BOAST/Runtime/MAQAO.rb +10 -3
- data/lib/BOAST.rb +2 -0
- metadata +24 -2
@@ -4,6 +4,8 @@ module BOAST
|
|
4
4
|
extend PrivateStateAccessor
|
5
5
|
extend Intrinsics
|
6
6
|
|
7
|
+
DISCARD_OPTIONS = { :const => nil, :constant => nil, :direction => nil, :dir => nil, :align => nil }
|
8
|
+
|
7
9
|
def Operator.inspect
|
8
10
|
return "#{name}"
|
9
11
|
end
|
@@ -11,9 +13,16 @@ module BOAST
|
|
11
13
|
def Operator.convert(arg, type)
|
12
14
|
return "convert_#{type.decl}( #{arg} )" if lang == CL
|
13
15
|
|
14
|
-
|
15
|
-
raise "Unavailable conversion from #{get_vector_name(arg.type)} to #{get_vector_name(type)}!" if not
|
16
|
-
|
16
|
+
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
|
+
s = "#{arg}"
|
19
|
+
if path.length > 1 then
|
20
|
+
path.each_cons(2) { |slice|
|
21
|
+
instruction = intrinsics_by_vector_name(:CVT, slice[1], slice[0])
|
22
|
+
s = "#{instruction}( #{s} )"
|
23
|
+
}
|
24
|
+
end
|
25
|
+
return s
|
17
26
|
end
|
18
27
|
|
19
28
|
end
|
@@ -21,14 +30,11 @@ module BOAST
|
|
21
30
|
class BasicBinaryOperator < Operator
|
22
31
|
|
23
32
|
def BasicBinaryOperator.to_s(arg1, arg2, return_type)
|
24
|
-
#puts "#{arg1.class} * #{arg2.class} : #{arg1} * #{arg2}"
|
25
33
|
if lang == C and (arg1.class == Variable and arg2.class == Variable) and (arg1.type.vector_length > 1 or arg2.type.vector_length > 1) then
|
26
|
-
|
27
|
-
#puts "#{arg1.type.signed} #{arg2.type.signed} #{return_type.type.signed}"
|
28
|
-
instruction = intrinsics[get_architecture][intr_symbol][get_vector_name(return_type.type)]
|
34
|
+
instruction = intrinsics(intr_symbol, return_type.type)
|
29
35
|
raise "Unavailable operator #{symbol} for #{get_vector_name(return_type.type)}!" unless instruction
|
30
|
-
a1 =
|
31
|
-
a2 =
|
36
|
+
a1 = convert(arg1, return_type.type)
|
37
|
+
a2 = convert(arg2, return_type.type)
|
32
38
|
return "#{instruction}( #{a1}, #{a2} )"
|
33
39
|
else
|
34
40
|
return basic_usage( arg1, arg2 )
|
@@ -37,54 +43,6 @@ module BOAST
|
|
37
43
|
|
38
44
|
end
|
39
45
|
|
40
|
-
class Set < Operator
|
41
|
-
|
42
|
-
def Set.to_s(arg1, arg2, return_type)
|
43
|
-
if lang == C or lang == CL then
|
44
|
-
if arg1.class == Variable and arg1.type.vector_length > 1 then
|
45
|
-
if arg2.kind_of?( Array ) then
|
46
|
-
raise "Invalid array length!" unless arg2.length == arg1.type.vector_length
|
47
|
-
return "#{arg1} = (#{arg1.type.decl})( #{arg2.join(", ")} )" if lang == CL
|
48
|
-
|
49
|
-
instruction = intrinsics[get_architecture][:SET][get_vector_name(arg1.type)]
|
50
|
-
if not instruction then
|
51
|
-
instruction = intrinsics[get_architecture][:SET_LANE][get_vector_name(arg1.type)]
|
52
|
-
raise "Unavailable operator set for #{get_vector_name(arg1.type)}!" unless instruction
|
53
|
-
s = "#{arg1}"
|
54
|
-
arg2.each_with_index { |v,i|
|
55
|
-
s = "#{instruction}(#{v}, #{s}, #{i})"
|
56
|
-
}
|
57
|
-
return "#{arg1} = #{s}"
|
58
|
-
else
|
59
|
-
return "#{arg1} = #{instruction}( #{arg2.join(", ")} )"
|
60
|
-
end
|
61
|
-
elsif arg2.class != Variable or arg2.type.vector_length == 1 then
|
62
|
-
return "#{arg1} = (#{arg1.type.decl})( #{arg2} )" if lang == CL
|
63
|
-
|
64
|
-
instruction = intrinsics[get_architecture][:SET1][get_vector_name(arg1.type)]
|
65
|
-
raise "Unavailable operator set1 for #{get_vector_name(arg1.type)}!" unless instruction
|
66
|
-
return "#{arg1} = #{instruction}( #{arg2} )"
|
67
|
-
elsif arg1.type == arg2.type then
|
68
|
-
return basic_usage(arg1, arg2)
|
69
|
-
elsif arg1.type.vector_length == arg2.type.vector_length then
|
70
|
-
return "#{arg1} = #{convert(arg2, arg1.type)}"
|
71
|
-
else
|
72
|
-
raise "Unknown convertion between vector of different length!"
|
73
|
-
end
|
74
|
-
else
|
75
|
-
return basic_usage(arg1, arg2)
|
76
|
-
end
|
77
|
-
else
|
78
|
-
return basic_usage(arg1, arg2)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def Set.basic_usage(arg1, arg2)
|
83
|
-
return "(#{arg1} = #{arg2})"
|
84
|
-
end
|
85
|
-
|
86
|
-
end
|
87
|
-
|
88
46
|
class Different < Operator
|
89
47
|
|
90
48
|
def Different.to_s(arg1, arg2, return_type)
|
@@ -98,90 +56,13 @@ module BOAST
|
|
98
56
|
|
99
57
|
end
|
100
58
|
|
101
|
-
class Load < Operator
|
102
|
-
|
103
|
-
def Load.to_s(arg1, arg2, return_type)
|
104
|
-
if lang == C or lang == CL then
|
105
|
-
if arg1 then
|
106
|
-
if arg1.class == Variable and arg1.type.vector_length > 1 then
|
107
|
-
if arg2.kind_of?( Array ) then
|
108
|
-
return Set.to_s(arg1, arg2, return_type)
|
109
|
-
elsif arg1.type == arg2.type then
|
110
|
-
return Affectation.basic_usage(arg1, arg2)
|
111
|
-
elsif arg1.type.vector_length == arg2.type.vector_length then
|
112
|
-
return "#{arg1} = #{convert(arg2, arg1.type)}"
|
113
|
-
elsif arg2.type.vector_length == 1 then
|
114
|
-
return "#{arg1} = #{Load.to_s(nil, arg2, arg1)}"
|
115
|
-
else
|
116
|
-
raise "Unknown convertion between vectors of different length!"
|
117
|
-
end
|
118
|
-
else
|
119
|
-
Affectation.basic_usage(arg1, arg2)
|
120
|
-
end
|
121
|
-
elsif arg2.class == Variable and arg2.type.vector_length == 1 then
|
122
|
-
a2 = "#{arg2}"
|
123
|
-
if a2[0] != "*" then
|
124
|
-
a2 = "&" + a2
|
125
|
-
else
|
126
|
-
a2 = a2[1..-1]
|
127
|
-
end
|
128
|
-
|
129
|
-
return "vload#{return_type.type.vector_length}(0, #{a2})" if lang == CL
|
130
|
-
return "#{arg1} = _m_from_int64( *((int64_t * ) #{a2} ) )" if get_architecture == X86 and arg2.type.total_size*8 == 64
|
131
|
-
|
132
|
-
if arg2.align == return_type.type.total_size then
|
133
|
-
instruction = intrinsics[get_architecture][:LOADA][get_vector_name(return_type.type)]
|
134
|
-
else
|
135
|
-
instruction = intrinsics[get_architecture][:LOAD][get_vector_name(return_type.type)]
|
136
|
-
end
|
137
|
-
raise "Unavailable operator load for #{get_vector_name(return_type.type)}!" unless instruction
|
138
|
-
return "#{instruction}( #{a2} )"
|
139
|
-
else
|
140
|
-
return "#{arg2}"
|
141
|
-
end
|
142
|
-
end
|
143
|
-
return Affectation.basic_usage(arg1, arg2) if arg1
|
144
|
-
return "#{arg2}"
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
148
|
-
|
149
|
-
class Store < Operator
|
150
|
-
|
151
|
-
def Store.to_s(arg1, arg2, return_type)
|
152
|
-
if lang == C or lang == CL then
|
153
|
-
a1 = "#{arg1}"
|
154
|
-
if a1[0] != "*" then
|
155
|
-
a1 = "&" + a1
|
156
|
-
else
|
157
|
-
a1 = a1[1..-1]
|
158
|
-
end
|
159
|
-
|
160
|
-
return "vstore#{arg2.type.vector_length}(#{arg2}, 0, #{a1})" if lang == CL
|
161
|
-
return "*((int64_t * ) #{a1}) = _m_to_int64( #{arg2} )" if get_architecture == X86 and arg2.type.total_size*8 == 64
|
162
|
-
|
163
|
-
if arg1.align == arg2.type.total_size then
|
164
|
-
instruction = intrinsics[get_architecture][:STOREA][get_vector_name(arg2.type)]
|
165
|
-
else
|
166
|
-
instruction = intrinsics[get_architecture][:STORE][get_vector_name(arg2.type)]
|
167
|
-
end
|
168
|
-
raise "Unavailable operator store for #{get_vector_name(arg2.type)}!" unless instruction
|
169
|
-
p_type = arg2.type.copy(:vector_length => 1)
|
170
|
-
p_type = arg2.type if get_architecture == X86 and arg2.type.kind_of?(Int)
|
171
|
-
return "#{instruction}( (#{p_type.decl} * ) #{a1}, #{arg2} )"
|
172
|
-
end
|
173
|
-
return Affectation.basic_usage(arg1, arg2)
|
174
|
-
end
|
175
|
-
|
176
|
-
end
|
177
|
-
|
178
59
|
class Affectation < Operator
|
179
60
|
|
180
61
|
def Affectation.to_s(arg1, arg2, return_type)
|
181
62
|
if arg1.class == Variable and arg1.type.vector_length > 1 then
|
182
|
-
return Load
|
63
|
+
return "#{arg1} = #{Load(arg2, arg1)}"
|
183
64
|
elsif arg2.class == Variable and arg2.type.vector_length > 1 then
|
184
|
-
return Store
|
65
|
+
return "#{Store(arg1, arg2, return_type)}"
|
185
66
|
end
|
186
67
|
return basic_usage(arg1, arg2)
|
187
68
|
end
|
@@ -288,6 +169,365 @@ module BOAST
|
|
288
169
|
|
289
170
|
end
|
290
171
|
|
172
|
+
class Set < Operator
|
173
|
+
extend Functor
|
174
|
+
include Intrinsics
|
175
|
+
include Arithmetic
|
176
|
+
include Inspectable
|
177
|
+
include PrivateStateAccessor
|
178
|
+
|
179
|
+
attr_reader :source
|
180
|
+
attr_reader :return_type
|
181
|
+
|
182
|
+
def initialize(source, return_type)
|
183
|
+
@source = source
|
184
|
+
@return_type = return_type
|
185
|
+
end
|
186
|
+
|
187
|
+
def type
|
188
|
+
return @return_type.type
|
189
|
+
end
|
190
|
+
|
191
|
+
def to_var
|
192
|
+
if lang == C or lang == CL and @return_type.type.vector_length > 1 then
|
193
|
+
if @source.kind_of?( Array ) then
|
194
|
+
raise "Invalid array length!" unless @source.length == @return_type.type.vector_length
|
195
|
+
return @return_type.copy("(#{@return_type.type.decl})( #{@source.join(", ")} )", DISCARD_OPTIONS) if lang == CL
|
196
|
+
|
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)
|
207
|
+
elsif @source.class != Variable or @source.type.vector_length == 1 then
|
208
|
+
return @return_type.copy("(#{@return_type.type.decl})( #{@source} )", DISCARD_OPTIONS) if lang == CL
|
209
|
+
|
210
|
+
instruction = intrinsics(:SET1, @return_type.type)
|
211
|
+
raise "Unavailable operator set1 for #{get_vector_name(@return_type.type)}!" unless instruction
|
212
|
+
return @return_type.copy("#{instruction}( #{@source} )", DISCARD_OPTIONS)
|
213
|
+
elsif @return_type.type != @source.type
|
214
|
+
return @return_type.copy("#{Operator.convert(@source, @return_type.type)}", DISCARD_OPTIONS)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
return @return_type.copy("#{@source}", DISCARD_OPTIONS)
|
218
|
+
end
|
219
|
+
|
220
|
+
def to_s
|
221
|
+
return to_var.to_s
|
222
|
+
end
|
223
|
+
|
224
|
+
def pr
|
225
|
+
s=""
|
226
|
+
s += indent
|
227
|
+
s += to_s
|
228
|
+
s += ";" if [C, CL, CUDA].include?( lang )
|
229
|
+
output.puts s
|
230
|
+
return self
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
class Load < Operator
|
236
|
+
extend Functor
|
237
|
+
include Intrinsics
|
238
|
+
include Arithmetic
|
239
|
+
include Inspectable
|
240
|
+
include PrivateStateAccessor
|
241
|
+
|
242
|
+
attr_reader :source
|
243
|
+
attr_reader :return_type
|
244
|
+
|
245
|
+
def initialize(source, return_type)
|
246
|
+
@source = source
|
247
|
+
@return_type = return_type
|
248
|
+
end
|
249
|
+
|
250
|
+
def type
|
251
|
+
return @return_type.type
|
252
|
+
end
|
253
|
+
|
254
|
+
def to_var
|
255
|
+
if lang == C or lang == CL then
|
256
|
+
if @source.kind_of?(Array) then
|
257
|
+
return Set(@source, @return_type).to_var
|
258
|
+
elsif @source.class == Variable or @source.respond_to?(:to_var) then
|
259
|
+
if @source.to_var.type == @return_type.type
|
260
|
+
return @source.to_var
|
261
|
+
elsif @source.to_var.type.vector_length == 1 then
|
262
|
+
a2 = "#{@source}"
|
263
|
+
if a2[0] != "*" then
|
264
|
+
a2 = "&" + a2
|
265
|
+
else
|
266
|
+
a2 = a2[1..-1]
|
267
|
+
end
|
268
|
+
return @return_type.copy("vload#{@return_type.type.vector_length}(0, #{a2})", DISCARD_OPTIONS) if lang == CL
|
269
|
+
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
|
271
|
+
instruction = intrinsics(:LOADA, @return_type.type)
|
272
|
+
else
|
273
|
+
instruction = intrinsics(:LOAD, @return_type.type)
|
274
|
+
end
|
275
|
+
raise "Unavailable operator load for #{get_vector_name(@return_type.type)}!" unless instruction
|
276
|
+
return @return_type.copy("#{instruction}( #{a2} )", DISCARD_OPTIONS)
|
277
|
+
else
|
278
|
+
return @return_type.copy("#{Operator.convert(@source, @return_type.type)}", DISCARD_OPTIONS)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
return @return_type.copy("#{@source}", DISCARD_OPTIONS)
|
283
|
+
end
|
284
|
+
|
285
|
+
def to_s
|
286
|
+
return to_var.to_s
|
287
|
+
end
|
288
|
+
|
289
|
+
def pr
|
290
|
+
s=""
|
291
|
+
s += indent
|
292
|
+
s += to_s
|
293
|
+
s += ";" if [C, CL, CUDA].include?( lang )
|
294
|
+
output.puts s
|
295
|
+
return self
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
class MaskLoad < Operator
|
301
|
+
extend Functor
|
302
|
+
include Intrinsics
|
303
|
+
include Arithmetic
|
304
|
+
include Inspectable
|
305
|
+
include PrivateStateAccessor
|
306
|
+
|
307
|
+
attr_reader :source
|
308
|
+
attr_reader :mask
|
309
|
+
attr_reader :return_type
|
310
|
+
|
311
|
+
def initialize(source, mask, return_type)
|
312
|
+
@source = source
|
313
|
+
@mask = mask
|
314
|
+
@return_type = return_type
|
315
|
+
end
|
316
|
+
|
317
|
+
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
|
319
|
+
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
|
+
end
|
321
|
+
|
322
|
+
private :get_mask
|
323
|
+
|
324
|
+
def type
|
325
|
+
return @return_type.type
|
326
|
+
end
|
327
|
+
|
328
|
+
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)
|
332
|
+
s = ""
|
333
|
+
src = "#{@source}"
|
334
|
+
if src[0] != "*" then
|
335
|
+
src = "&" + src
|
336
|
+
else
|
337
|
+
src = src[1..-1]
|
338
|
+
end
|
339
|
+
p_type = @return_type.type.copy(:vector_length => 1)
|
340
|
+
s += "#{intrinsics(:MASKLOAD, @return_type.type)}((#{p_type.decl} * )#{src}, #{get_mask})"
|
341
|
+
return @return_type.copy( s, DISCARD_OPTIONS)
|
342
|
+
end
|
343
|
+
|
344
|
+
def to_s
|
345
|
+
return to_var.to_s
|
346
|
+
end
|
347
|
+
|
348
|
+
def pr
|
349
|
+
s=""
|
350
|
+
s += indent
|
351
|
+
s += to_s
|
352
|
+
s += ";" if [C, CL, CUDA].include?( lang )
|
353
|
+
output.puts s
|
354
|
+
return self
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|
358
|
+
|
359
|
+
class Store < Operator
|
360
|
+
extend Functor
|
361
|
+
include Intrinsics
|
362
|
+
include Arithmetic
|
363
|
+
include Inspectable
|
364
|
+
include PrivateStateAccessor
|
365
|
+
|
366
|
+
attr_reader :dest
|
367
|
+
attr_reader :source
|
368
|
+
attr_reader :store_type
|
369
|
+
|
370
|
+
def initialize(dest, source, mask, store_type = nil)
|
371
|
+
@dest = dest
|
372
|
+
@source = source
|
373
|
+
@store_type = store_type
|
374
|
+
@store_type = source unless @store_type
|
375
|
+
end
|
376
|
+
|
377
|
+
def to_s
|
378
|
+
if lang == C or lang == CL then
|
379
|
+
dst = "#{@dest}"
|
380
|
+
if dst[0] != "*" then
|
381
|
+
dst = "&" + dst
|
382
|
+
else
|
383
|
+
dst = dst[1..-1]
|
384
|
+
end
|
385
|
+
|
386
|
+
return "vstore#{@source.type.vector_length}(#{@source}, 0, #{dst})" if lang == CL
|
387
|
+
return "*((int64_t * ) #{dst}) = _m_to_int64( #{@source} )" if get_architecture == X86 and @source.type.total_size*8 == 64
|
388
|
+
|
389
|
+
if @dest.align == @source.type.total_size then
|
390
|
+
instruction = intrinsics(:STOREA, @source.type)
|
391
|
+
else
|
392
|
+
instruction = intrinsics(:STORE, @source.type)
|
393
|
+
end
|
394
|
+
raise "Unavailable operator store for #{get_vector_name(@source.type)}!" unless instruction
|
395
|
+
p_type = @source.type.copy(:vector_length => 1)
|
396
|
+
p_type = @source.type if get_architecture == X86 and @source.type.kind_of?(Int)
|
397
|
+
return "#{instruction}( (#{p_type.decl} * ) #{dst}, #{@source} )"
|
398
|
+
end
|
399
|
+
return Affectation.basic_usage(@dest, @source)
|
400
|
+
end
|
401
|
+
|
402
|
+
def pr
|
403
|
+
s=""
|
404
|
+
s += indent
|
405
|
+
s += to_s
|
406
|
+
s += ";" if [C, CL, CUDA].include?( lang )
|
407
|
+
output.puts s
|
408
|
+
return self
|
409
|
+
end
|
410
|
+
|
411
|
+
end
|
412
|
+
|
413
|
+
class MaskStore < Operator
|
414
|
+
extend Functor
|
415
|
+
include Intrinsics
|
416
|
+
include Arithmetic
|
417
|
+
include Inspectable
|
418
|
+
include PrivateStateAccessor
|
419
|
+
|
420
|
+
attr_reader :dest
|
421
|
+
attr_reader :source
|
422
|
+
attr_reader :mask
|
423
|
+
attr_reader :store_type
|
424
|
+
|
425
|
+
def initialize(dest, source, mask, store_type = nil)
|
426
|
+
@dest = dest
|
427
|
+
@source = source
|
428
|
+
@mask = mask
|
429
|
+
@store_type = store_type
|
430
|
+
@store_type = source unless @store_type
|
431
|
+
end
|
432
|
+
|
433
|
+
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
|
435
|
+
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
|
+
end
|
437
|
+
|
438
|
+
private :get_mask
|
439
|
+
|
440
|
+
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)
|
444
|
+
s = ""
|
445
|
+
dst = "#{@dest}"
|
446
|
+
if dst[0] != "*" then
|
447
|
+
dst = "&" + dst
|
448
|
+
else
|
449
|
+
dst = dst[1..-1]
|
450
|
+
end
|
451
|
+
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)})"
|
453
|
+
end
|
454
|
+
|
455
|
+
def pr
|
456
|
+
s=""
|
457
|
+
s += indent
|
458
|
+
s += to_s
|
459
|
+
s += ";" if [C, CL, CUDA].include?( lang )
|
460
|
+
output.puts s
|
461
|
+
return self
|
462
|
+
end
|
463
|
+
|
464
|
+
end
|
465
|
+
|
466
|
+
class FMA < Operator
|
467
|
+
extend Functor
|
468
|
+
include Intrinsics
|
469
|
+
include Arithmetic
|
470
|
+
include Inspectable
|
471
|
+
include PrivateStateAccessor
|
472
|
+
|
473
|
+
attr_reader :operand1
|
474
|
+
attr_reader :operand2
|
475
|
+
attr_reader :operand3
|
476
|
+
attr_reader :return_type
|
477
|
+
|
478
|
+
def initialize(a,b,c)
|
479
|
+
@operand1 = a
|
480
|
+
@operand2 = b
|
481
|
+
@operand3 = c
|
482
|
+
@return_type = nil
|
483
|
+
@return_type = @operand3.to_var unless @return_type
|
484
|
+
end
|
485
|
+
|
486
|
+
def convert_operand(op)
|
487
|
+
return "#{Operator.convert(op, @return_type.type)}"
|
488
|
+
end
|
489
|
+
|
490
|
+
private :convert_operand
|
491
|
+
|
492
|
+
def type
|
493
|
+
return @return_type.type
|
494
|
+
end
|
495
|
+
|
496
|
+
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) ) )
|
498
|
+
op1 = convert_operand(@operand1)
|
499
|
+
op2 = convert_operand(@operand2)
|
500
|
+
op3 = convert_operand(@operand3)
|
501
|
+
if [CL, CUDA].include?(lang)
|
502
|
+
ret_name = "fma(#{op1},#{op2},#{op3})"
|
503
|
+
else
|
504
|
+
case architecture
|
505
|
+
when X86
|
506
|
+
ret_name = "#{intrinsics(:FMADD,@return_type.type)}(#{op1},#{op2},#{op3})"
|
507
|
+
when ARM
|
508
|
+
ret_name = "#{intrinsics(:FMADD,@return_type.type)}(#{op2},#{op3},#{op1})"
|
509
|
+
else
|
510
|
+
return (@operand1 * @operand2 + @operand3).to_var
|
511
|
+
end
|
512
|
+
end
|
513
|
+
return @return_type.copy( ret_name, DISCARD_OPTIONS)
|
514
|
+
end
|
515
|
+
|
516
|
+
def to_s
|
517
|
+
return to_var.to_s
|
518
|
+
end
|
519
|
+
|
520
|
+
def pr
|
521
|
+
s=""
|
522
|
+
s += indent
|
523
|
+
s += to_s
|
524
|
+
s += ";" if [C, CL, CUDA].include?( lang )
|
525
|
+
output.puts s
|
526
|
+
return self
|
527
|
+
end
|
528
|
+
|
529
|
+
end
|
530
|
+
|
291
531
|
class Ternary
|
292
532
|
extend Functor
|
293
533
|
include Arithmetic
|
data/lib/BOAST/Language/State.rb
CHANGED
@@ -37,6 +37,20 @@ EOF
|
|
37
37
|
}
|
38
38
|
end
|
39
39
|
|
40
|
+
def self.default_state_getter(arg, default, get_env_string=nil, env = arg.upcase)
|
41
|
+
envs = "ENV['#{env}']"
|
42
|
+
s = <<EOF
|
43
|
+
def get_default_#{arg}
|
44
|
+
#{arg} = #{default.inspect}
|
45
|
+
#{arg} = #{get_env_string ? eval( "#{get_env_string}" ) : "YAML::load(#{envs})" } if #{envs}
|
46
|
+
return #{arg}
|
47
|
+
end
|
48
|
+
module_function :get_default_#{arg}
|
49
|
+
@@#{arg} = get_default_#{arg}
|
50
|
+
EOF
|
51
|
+
eval s
|
52
|
+
end
|
53
|
+
|
40
54
|
module PrivateStateAccessor
|
41
55
|
|
42
56
|
def self.private_state_accessor(*args)
|
@@ -34,7 +34,7 @@ module BOAST
|
|
34
34
|
signed = (signed or var2.type.signed)
|
35
35
|
size = [var1.type.size, var2.type.size].max
|
36
36
|
vector_length = [var1.type.vector_length, var2.type.vector_length].max
|
37
|
-
[Variable::new("dummy", return_type, :size => size, :signed => signed, :vector_length => vector_length), operator]
|
37
|
+
return [Variable::new("dummy", return_type, :size => size, :signed => signed, :vector_length => vector_length), operator]
|
38
38
|
elsif var1.type.class == return_type then
|
39
39
|
return [var1, operator]
|
40
40
|
else # var2.type.class == return_type then
|