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
@@ -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
|