BOAST 1.0.7 → 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,7 +1,7 @@
|
|
1
1
|
module BOAST
|
2
2
|
|
3
3
|
class DataType
|
4
|
-
|
4
|
+
include Intrinsics
|
5
5
|
include PrivateStateAccessor
|
6
6
|
|
7
7
|
def self.inherited(child)
|
@@ -55,10 +55,6 @@ module BOAST
|
|
55
55
|
|
56
56
|
def suffix
|
57
57
|
s = ""
|
58
|
-
# if [C, CL, CUDA].include?( lang ) then
|
59
|
-
# s += "U" if not @signed
|
60
|
-
# s += "LL" if @size == 8
|
61
|
-
# end
|
62
58
|
return s
|
63
59
|
end
|
64
60
|
|
@@ -84,14 +80,8 @@ module BOAST
|
|
84
80
|
else
|
85
81
|
@size = get_default_real_size
|
86
82
|
end
|
87
|
-
# @getters = {}
|
88
|
-
# @setters = {}
|
89
83
|
if hash[:vector_length] and hash[:vector_length] > 1 then
|
90
84
|
@vector_length = hash[:vector_length]
|
91
|
-
# @vector_length.times{ |indx|
|
92
|
-
# @getters["s#{indx}"] = indx
|
93
|
-
# @setters["s#{indx}="] = indx
|
94
|
-
# }
|
95
85
|
else
|
96
86
|
@vector_length = 1
|
97
87
|
end
|
@@ -121,16 +111,7 @@ module BOAST
|
|
121
111
|
return "float" if @size == 4
|
122
112
|
return "double" if @size == 8
|
123
113
|
elsif lang == C and @vector_length > 1 then
|
124
|
-
|
125
|
-
return "__m#{@total_size*8}" if @size == 4
|
126
|
-
return "__m#{@total_size*8}d" if @size == 8
|
127
|
-
elsif get_architecture == ARM then
|
128
|
-
raise "Unsupported data type in NEON: double!" if @size == 8
|
129
|
-
raise "Unsupported vector length in NEON: #{@total_size} (#{@size} x 8 x #{@vector_length})!" if @total_size * 8 != 64 or @total_size * 8 != 128
|
130
|
-
return "float#{@size*8}x#{@vector_length}_t"
|
131
|
-
else
|
132
|
-
raise "Unsupported architecture!"
|
133
|
-
end
|
114
|
+
return get_vector_decl(self)
|
134
115
|
elsif [CL, CUDA].include?( lang ) and @vector_length > 1 then
|
135
116
|
return "float#{@vector_length}" if @size == 4
|
136
117
|
return "double#{@vector_length}" if @size == 8
|
@@ -177,15 +158,9 @@ module BOAST
|
|
177
158
|
else
|
178
159
|
@signed = get_default_int_signed
|
179
160
|
end
|
180
|
-
# @getters = {}
|
181
|
-
# @setters = {}
|
182
161
|
if hash[:vector_length] and hash[:vector_length] > 1 then
|
183
162
|
@vector_length = hash[:vector_length]
|
184
|
-
|
185
|
-
# @getters["s#{indx}"] = indx
|
186
|
-
# @setters["s#{indx}="] = indx
|
187
|
-
# }
|
188
|
-
raise "Vectors need to have their element size specified!" if not @size
|
163
|
+
raise "Vectors need to have their element size specified!" if not @size
|
189
164
|
else
|
190
165
|
@vector_length = 1
|
191
166
|
end
|
@@ -220,75 +195,39 @@ module BOAST
|
|
220
195
|
return s+"int#{8*@size}_t" if @size
|
221
196
|
return s+"int"
|
222
197
|
elsif @vector_length > 1 then
|
223
|
-
|
224
|
-
return "__m#{@total_size*8}#{@total_size*8>64 ? "i" : ""}"
|
225
|
-
elsif get_architecture == ARM then
|
226
|
-
raise "Unsupported vector length in NEON: #{@total_size*8} (#{@size} x 8 x #{@vector_length})!" if @total_size * 8 != 64 and @total_size * 8 != 128
|
227
|
-
return "#{ @signed ? "" : "u"}int#{@size*8}x#{@vector_length}_t"
|
228
|
-
else
|
229
|
-
raise "Unsupported architecture!"
|
230
|
-
end
|
198
|
+
return get_vector_decl(self)
|
231
199
|
end
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
200
|
+
else
|
201
|
+
s =""
|
202
|
+
s += "u" if not @signed
|
203
|
+
s += "nsigned " if not @signed and lang == CUDA and @vector_length == 1
|
236
204
|
case @size
|
237
205
|
when 1
|
238
|
-
|
206
|
+
s += "char"
|
239
207
|
when 2
|
240
|
-
|
208
|
+
s += "short"
|
241
209
|
when 4
|
242
|
-
|
210
|
+
s += "int"
|
243
211
|
when 8
|
244
|
-
|
212
|
+
if lang == CUDA
|
213
|
+
case @vector_length
|
214
|
+
when 1
|
215
|
+
s += "long long"
|
216
|
+
else
|
217
|
+
s += "longlong"
|
218
|
+
end
|
219
|
+
else
|
220
|
+
s += "long"
|
221
|
+
end
|
245
222
|
when nil
|
246
|
-
|
223
|
+
s += "int"
|
247
224
|
else
|
248
225
|
raise "Unsupported integer size!"
|
249
226
|
end
|
250
227
|
if @vector_length > 1 then
|
251
|
-
|
252
|
-
end
|
253
|
-
return char
|
254
|
-
elsif lang == CUDA then
|
255
|
-
if @vector_length > 1 then
|
256
|
-
char=""
|
257
|
-
char += "u" if not @signed
|
258
|
-
case @size
|
259
|
-
when 1
|
260
|
-
char += "char"
|
261
|
-
when 2
|
262
|
-
char += "short"
|
263
|
-
when 4
|
264
|
-
char += "int"
|
265
|
-
when 8
|
266
|
-
char += "longlong"
|
267
|
-
when nil
|
268
|
-
char += "int"
|
269
|
-
else
|
270
|
-
raise "Unsupported integer size!"
|
271
|
-
end
|
272
|
-
return char + "#{@vector_length}"
|
273
|
-
else
|
274
|
-
char = ""
|
275
|
-
char += "unsigned " if not @signed
|
276
|
-
case @size
|
277
|
-
when 1
|
278
|
-
char += "char"
|
279
|
-
when 2
|
280
|
-
char += "short"
|
281
|
-
when 4
|
282
|
-
char += "int"
|
283
|
-
when 8
|
284
|
-
char += "longlong"
|
285
|
-
when nil
|
286
|
-
char += "int"
|
287
|
-
else
|
288
|
-
raise "Unsupported integer size!"
|
289
|
-
end
|
290
|
-
return char
|
228
|
+
s += "#{@vector_length}"
|
291
229
|
end
|
230
|
+
return s
|
292
231
|
end
|
293
232
|
end
|
294
233
|
|
data/lib/BOAST/Language/Index.rb
CHANGED
@@ -19,6 +19,18 @@ module BOAST
|
|
19
19
|
return var
|
20
20
|
end
|
21
21
|
|
22
|
+
def set(x)
|
23
|
+
return to_var === Set(x,to_var)
|
24
|
+
end
|
25
|
+
|
26
|
+
def copy(*args)
|
27
|
+
return to_var.copy(*args)
|
28
|
+
end
|
29
|
+
|
30
|
+
def type
|
31
|
+
return to_var.type
|
32
|
+
end
|
33
|
+
|
22
34
|
def to_s
|
23
35
|
if get_replace_constants then
|
24
36
|
begin
|
@@ -1,22 +1,114 @@
|
|
1
|
+
require 'os'
|
2
|
+
require 'yaml'
|
3
|
+
require 'rgl/adjacency'
|
4
|
+
require 'rgl/dijkstra'
|
5
|
+
|
1
6
|
module BOAST
|
2
7
|
|
3
8
|
X86 = 1
|
4
9
|
ARM = 2
|
5
10
|
|
11
|
+
native_flags = nil
|
12
|
+
|
13
|
+
if OS.mac? then
|
14
|
+
native_flags = `sysctl -n machdep.cpu.features`.split
|
15
|
+
else
|
16
|
+
native_flags = YAML::load(`cat /proc/cpuinfo`)["flags"].upcase.gsub("_",".").split
|
17
|
+
end
|
18
|
+
|
19
|
+
MODELS={ "native" => native_flags }
|
20
|
+
MODELS.update(X86architectures)
|
21
|
+
INSTRUCTIONS = {}
|
22
|
+
INSTRUCTIONS.update(X86CPUID_by_name)
|
23
|
+
|
6
24
|
module Intrinsics
|
25
|
+
extend PrivateStateAccessor
|
7
26
|
INTRINSICS = Hash::new { |h, k| h[k] = Hash::new { |h2, k2| h2[k2] = {} } }
|
27
|
+
CONVERSIONS = Hash::new { |h, k| h[k] = Hash::new { |h2, k2| h2[k2] = {} } }
|
28
|
+
|
29
|
+
def supported(intr_symbol, type, type2=nil)
|
30
|
+
instruction = intrinsics(intr_symbol, type, type2)
|
31
|
+
return false unless instruction
|
32
|
+
INSTRUCTIONS[instruction.to_s].each { |flag|
|
33
|
+
return true if MODELS[get_model].include?(flag)
|
34
|
+
}
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
|
38
|
+
module_function :supported
|
39
|
+
|
40
|
+
def intrinsics_by_vector_name(intr_symbol, type, type2=nil)
|
41
|
+
return INTRINSICS[get_architecture][intr_symbol][type][type2] if type2
|
42
|
+
return INTRINSICS[get_architecture][intr_symbol][type]
|
43
|
+
end
|
44
|
+
|
45
|
+
module_function :intrinsics_by_vector_name
|
8
46
|
|
9
|
-
def intrinsics
|
10
|
-
return INTRINSICS
|
47
|
+
def intrinsics(intr_symbol, type, type2=nil)
|
48
|
+
return INTRINSICS[get_architecture][intr_symbol][get_vector_name(type)][get_vector_name(type2)] if type2
|
49
|
+
return INTRINSICS[get_architecture][intr_symbol][get_vector_name(type)]
|
11
50
|
end
|
12
51
|
|
13
52
|
module_function :intrinsics
|
14
53
|
|
54
|
+
def get_conversion_path(type_dest, type_orig)
|
55
|
+
return CONVERSIONS[get_architecture][get_vector_name(type_dest)][get_vector_name(type_orig)]
|
56
|
+
end
|
57
|
+
|
58
|
+
module_function :get_conversion_path
|
59
|
+
|
60
|
+
def get_vector_decl_X86( data_type )
|
61
|
+
raise "Unsupported vector size on X86: #{data_type.total_size*8}!" unless [64,128,256].include?( data_type.total_size*8 )
|
62
|
+
s = "__m#{data_type.total_size*8}"
|
63
|
+
case data_type
|
64
|
+
when Int
|
65
|
+
raise "Unsupported data size for int vector on X86: #{data_type.size*8}!" unless [1,2,4,8].include?( data_type.size )
|
66
|
+
return s+= "#{data_type.total_size*8>64 ? "i" : ""}"
|
67
|
+
when Real
|
68
|
+
return s if data_type.size == 4
|
69
|
+
return s += "d" if data_type.size == 8
|
70
|
+
raise "Unsupported data size for real vector on X86: #{data_type.size*8}!"
|
71
|
+
else
|
72
|
+
raise "Unsupported data type #{data_type} for vector!"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module_function :get_vector_decl_X86
|
77
|
+
|
78
|
+
def get_vector_decl_ARM( data_type )
|
79
|
+
raise "Unsupported vector size on ARM: #{data_type.total_size*8}!" unless [64,128].include?( data_type.total_size*8 )
|
80
|
+
case data_type
|
81
|
+
when Int
|
82
|
+
raise "Unsupported data size for int vector on ARM: #{data_type.size*8}!" unless [1,2,4,8].include?( data_type.size )
|
83
|
+
return get_vector_name( data_type ).to_s
|
84
|
+
when Real
|
85
|
+
raise "Unsupported data size for real vector on ARM: #{data_type.size*8}!" if data_type.size != 4
|
86
|
+
return get_vector_name( data_type ).to_s
|
87
|
+
else
|
88
|
+
raise "Unsupported data type #{data_type} for vector on ARM!"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
module_function :get_vector_decl_ARM
|
93
|
+
|
94
|
+
def get_vector_decl( data_type )
|
95
|
+
case get_architecture
|
96
|
+
when X86
|
97
|
+
get_vector_decl_X86( data_type )
|
98
|
+
when ARM
|
99
|
+
get_vector_decl_ARM( data_type )
|
100
|
+
else
|
101
|
+
return get_vector_name( data_type )
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
module_function :get_vector_decl
|
106
|
+
|
15
107
|
def get_vector_name( type )
|
16
108
|
s = ""
|
17
109
|
case type
|
18
110
|
when Int
|
19
|
-
s += "u"
|
111
|
+
s += "u" unless type.signed?
|
20
112
|
s += "int"
|
21
113
|
when Real
|
22
114
|
s += "float"
|
@@ -24,7 +116,7 @@ module BOAST
|
|
24
116
|
raise "Undefined vector type!"
|
25
117
|
end
|
26
118
|
s += "#{type.size*8}"
|
27
|
-
s += "x#{type.vector_length}"
|
119
|
+
s += "x#{type.vector_length}_t"
|
28
120
|
return s.to_sym
|
29
121
|
end
|
30
122
|
|
@@ -48,7 +140,7 @@ module BOAST
|
|
48
140
|
raise "Invalid type!"
|
49
141
|
end
|
50
142
|
s += "#{size}"
|
51
|
-
s += "x#{vector_size/size}"
|
143
|
+
s += "x#{vector_size/size}_t"
|
52
144
|
return s.to_sym
|
53
145
|
end
|
54
146
|
|
@@ -79,9 +171,9 @@ module BOAST
|
|
79
171
|
|
80
172
|
def type_name_X86( type, size, vector_size, sign = :signed )
|
81
173
|
s = ""
|
82
|
-
e = ( vector_size > 64 ? "e" : "" )
|
83
174
|
case type
|
84
175
|
when :int
|
176
|
+
e = ( vector_size > 64 ? "e" : "" )
|
85
177
|
s += "#{e}p"
|
86
178
|
case sign
|
87
179
|
when :signed
|
@@ -126,6 +218,7 @@ module BOAST
|
|
126
218
|
}
|
127
219
|
if size == 64 and vector_size < 512 then
|
128
220
|
INTRINSICS[X86][:SET1][vtype] = "_mm#{vs}_set1_#{type}x".to_sym
|
221
|
+
INTRINSICS[X86][:SET][vtype] = "_mm#{vs}_setr_#{type}x".to_sym
|
129
222
|
end
|
130
223
|
}
|
131
224
|
}
|
@@ -144,9 +237,9 @@ module BOAST
|
|
144
237
|
[[:ADD, "add"], [:SUB, "sub"], [:MUL, "mul"], [:DIV, "div"],
|
145
238
|
[:FMADD, "fmadd"], [:FMSUB, "fmsub"], [:FNMADD, "fnmadd"], [:FNMSUB, "fnmsub"],
|
146
239
|
[:ADDSUB, "addsub"], [:FMADDSUB, "fmaddsub"], [:FMSUBADD, "fmsubadd"],
|
147
|
-
[:LOAD, "loadu"], [:LOADA, "load"],
|
148
|
-
[:STORE, "storeu"], [:STOREA, "store"],
|
149
|
-
[:SET, "
|
240
|
+
[:LOAD, "loadu"], [:LOADA, "load"], [:MASKLOAD, "maskload"],
|
241
|
+
[:STORE, "storeu"], [:STOREA, "store"], [:MASKSTORE, "maskstore"],
|
242
|
+
[:SET, "setr"], [:SET1, "set1"] ].each { |cl, ins|
|
150
243
|
vtype = vector_type_name( :float, size, vector_size)
|
151
244
|
type = type_name_X86( :float, size, vector_size )
|
152
245
|
INTRINSICS[X86][cl][vtype] = "_mm#{vs}_#{ins}_#{type}".to_sym
|
@@ -170,6 +263,28 @@ module BOAST
|
|
170
263
|
ssize /= 2
|
171
264
|
end
|
172
265
|
}
|
266
|
+
[64].each { |bsize|
|
267
|
+
ssize = bsize/2
|
268
|
+
svsize = (bvsize/bsize)*ssize
|
269
|
+
stype = type_name_X86( :float, ssize, 128 )
|
270
|
+
btype = type_name_X86( :float, bsize, bvsize )
|
271
|
+
svtype = vector_type_name( :float, ssize, svsize )
|
272
|
+
bvtype = vector_type_name( :float, bsize, bvsize )
|
273
|
+
vs = ( bvsize < 256 ? "" : "#{bvsize}" )
|
274
|
+
INTRINSICS[X86][:CVT][bvtype][svtype] = "_mm#{vs}_cvt#{stype}_#{btype}".to_sym
|
275
|
+
INTRINSICS[X86][:CVT][svtype][bvtype] = "_mm#{vs}_cvt#{btype}_#{stype}".to_sym
|
276
|
+
}
|
277
|
+
[64].each { |fsize|
|
278
|
+
[32].each { |isize|
|
279
|
+
ftype = type_name_X86( :float, fsize, bvsize )
|
280
|
+
itype = type_name_X86( :int, isize, isize*(bvsize/fsize), :signed )
|
281
|
+
fvtype = vector_type_name( :float, fsize, bvsize )
|
282
|
+
ivtype = vector_type_name( :int, isize, isize*(bvsize/fsize), :signed )
|
283
|
+
vs = ( bvsize < 256 ? "" : "#{bvsize}" )
|
284
|
+
INTRINSICS[X86][:CVT][fvtype][ivtype] = "_mm#{vs}_cvt#{itype}_#{ftype}".to_sym
|
285
|
+
INTRINSICS[X86][:CVT][ivtype][fvtype] = "_mm#{vs}_cvt#{ftype}_#{itype}".to_sym
|
286
|
+
}
|
287
|
+
}
|
173
288
|
}
|
174
289
|
|
175
290
|
|
@@ -180,7 +295,7 @@ module BOAST
|
|
180
295
|
vtype = vector_type_name( :int, size, vector_size, sign )
|
181
296
|
type = type_name_ARM( :int, size, sign )
|
182
297
|
instructions = [[:ADD, "add"], [:SUB, "sub"]]
|
183
|
-
instructions.push( [:MUL, "mul"], [:FMADD, "mla"], [:
|
298
|
+
instructions.push( [:MUL, "mul"], [:FMADD, "mla"], [:FNMADD, "mls"] ) if size < 64
|
184
299
|
instructions.push( [:LOAD, "ldl"], [:LOADA, "ldl"] )
|
185
300
|
instructions.push( [:STORE, "stl"], [:STOREA, "stl"] )
|
186
301
|
instructions.each { |cl, ins|
|
@@ -236,6 +351,29 @@ module BOAST
|
|
236
351
|
}
|
237
352
|
}
|
238
353
|
|
354
|
+
[X86, ARM].each { |arch|
|
355
|
+
cvt_dgraph = RGL::DirectedAdjacencyGraph::new
|
356
|
+
INTRINSICS[arch][:CVT].each { |dest, origs|
|
357
|
+
origs.each { |orig, intrinsic|
|
358
|
+
cvt_dgraph.add_edge(orig, dest)
|
359
|
+
}
|
360
|
+
}
|
361
|
+
cvt_dgraph.vertices.each { |source|
|
362
|
+
paths = cvt_dgraph.dijkstra_shortest_paths(cvt_dgraph.edges.map { |e| [e.to_a,1]}.to_h, source )
|
363
|
+
paths.each { |dest, path|
|
364
|
+
CONVERSIONS[arch][dest][source] = path if path
|
365
|
+
}
|
366
|
+
}
|
367
|
+
types = []
|
368
|
+
INTRINSICS[arch].each { |intrinsic, instructions|
|
369
|
+
types += instructions.keys
|
370
|
+
}
|
371
|
+
types.uniq
|
372
|
+
types.each { |type|
|
373
|
+
CONVERSIONS[arch][type][type] = [type]
|
374
|
+
}
|
375
|
+
}
|
376
|
+
|
239
377
|
end
|
240
378
|
|
241
379
|
end
|