BOAST 1.0.6 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/BOAST.gemspec +1 -1
- data/lib/BOAST.rb +1 -0
- data/lib/BOAST/Language/Algorithm.rb +2 -2
- data/lib/BOAST/Language/DataTypes.rb +6 -2
- data/lib/BOAST/Language/Expression.rb +3 -3
- data/lib/BOAST/Language/If.rb +1 -1
- data/lib/BOAST/Language/Index.rb +6 -1
- data/lib/BOAST/Language/Intrinsics.rb +241 -0
- data/lib/BOAST/Language/Operators.rb +117 -277
- data/lib/BOAST/Language/Procedure.rb +30 -13
- data/lib/BOAST/Language/Variable.rb +86 -17
- data/lib/BOAST/Language/Vector.rb +6 -0
- data/lib/BOAST/Runtime/CKernel.rb +1 -0
- data/lib/BOAST/Runtime/CRuntime.rb +3 -0
- data/lib/BOAST/Runtime/Config.rb +1 -0
- data/lib/BOAST/Runtime/FFIRuntime.rb +7 -7
- data/lib/BOAST/Runtime/MAQAO.rb +2 -2
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f11eacd12c0e6cfa7268db8d77718b8ea7264077
|
4
|
+
data.tar.gz: 2edec679ab6ac265fb66a3190b7693b5cde5fce7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1da1fdca526a8ecc1d82164e4621b271714f82cc210718d6bcd70bb6482c74366ea8e14fdd7f44d7338a8724c68ebb7746ddd2e49d964c978ba94d911cac114c
|
7
|
+
data.tar.gz: 76d2966d546378fa0901656711d76703218649e601534f7da7acfeae2d50e89604737f27924c97888d472ae77f7646596ed474a5fb9c0e87a608237864de0760
|
data/BOAST.gemspec
CHANGED
data/lib/BOAST.rb
CHANGED
@@ -3,6 +3,7 @@ require 'BOAST/Language/Functors.rb'
|
|
3
3
|
require 'BOAST/Language/Inspectable.rb'
|
4
4
|
require 'BOAST/Language/Transitions.rb'
|
5
5
|
require 'BOAST/Language/Arithmetic.rb'
|
6
|
+
require 'BOAST/Language/Intrinsics.rb'
|
6
7
|
require 'BOAST/Language/Operators.rb'
|
7
8
|
require 'BOAST/Language/DataTypes.rb'
|
8
9
|
require 'BOAST/Language/Expression.rb'
|
@@ -95,7 +95,7 @@ module BOAST
|
|
95
95
|
else
|
96
96
|
@vector_length = 1
|
97
97
|
end
|
98
|
-
@total_size = @vector_length
|
98
|
+
@total_size = @size*@vector_length
|
99
99
|
@signed = true
|
100
100
|
end
|
101
101
|
|
@@ -189,7 +189,7 @@ module BOAST
|
|
189
189
|
else
|
190
190
|
@vector_length = 1
|
191
191
|
end
|
192
|
-
@total_size = @vector_length
|
192
|
+
@total_size = @size*@vector_length
|
193
193
|
end
|
194
194
|
|
195
195
|
def to_hash
|
@@ -351,9 +351,11 @@ module BOAST
|
|
351
351
|
s = indent
|
352
352
|
s += decl_c + " {"
|
353
353
|
output.puts s
|
354
|
+
increment_indent_level
|
354
355
|
@members_array.each { |value|
|
355
356
|
value.decl
|
356
357
|
}
|
358
|
+
decrement_indent_level
|
357
359
|
s = indent
|
358
360
|
s += "}"
|
359
361
|
s += finalize
|
@@ -365,9 +367,11 @@ module BOAST
|
|
365
367
|
s = indent
|
366
368
|
s += "TYPE :: #{@name}\n"
|
367
369
|
output.puts s
|
370
|
+
increment_indent_level
|
368
371
|
@members_array.each { |value|
|
369
372
|
value.decl
|
370
373
|
}
|
374
|
+
decrement_indent_level
|
371
375
|
s = indent
|
372
376
|
s += "END TYPE #{@name}"
|
373
377
|
s += finalize
|
@@ -49,13 +49,13 @@ module BOAST
|
|
49
49
|
if op1 and op2 then
|
50
50
|
r_t, oper = transition(op1, op2, @operator)
|
51
51
|
res_exp = to_s_base(op1, op2, oper, r_t)
|
52
|
-
return r_t.copy(res_exp, :const => nil, :constant => nil, :direction => nil, :dir => nil)
|
52
|
+
return r_t.copy(res_exp, :const => nil, :constant => nil, :direction => nil, :dir => nil, :align => nil)
|
53
53
|
elsif op2
|
54
54
|
res_exp = to_s_base(@operand1, op2, @operator)
|
55
|
-
return op2.copy(res_exp, :const => nil, :constant => nil, :direction => nil, :dir => nil)
|
55
|
+
return op2.copy(res_exp, :const => nil, :constant => nil, :direction => nil, :dir => nil, :align => nil)
|
56
56
|
elsif op1
|
57
57
|
res_exp = to_s_base(op1, @operand2, @operator)
|
58
|
-
return op1.copy(res_exp, :const => nil, :constant => nil, :direction => nil, :dir => nil)
|
58
|
+
return op1.copy(res_exp, :const => nil, :constant => nil, :direction => nil, :dir => nil, :align => nil)
|
59
59
|
else
|
60
60
|
STDERR.puts "#{@operand1} #{@operand2}"
|
61
61
|
raise "Expression on no operand!"
|
data/lib/BOAST/Language/If.rb
CHANGED
data/lib/BOAST/Language/Index.rb
CHANGED
@@ -3,14 +3,19 @@ module BOAST
|
|
3
3
|
class Index < Expression
|
4
4
|
attr_reader :source
|
5
5
|
attr_reader :indexes
|
6
|
+
attr_accessor :align
|
6
7
|
|
7
8
|
def initialize(source, indexes)
|
8
9
|
@source = source
|
9
10
|
@indexes = indexes
|
10
11
|
end
|
11
12
|
|
13
|
+
def align?
|
14
|
+
return !!@align
|
15
|
+
end
|
16
|
+
|
12
17
|
def to_var
|
13
|
-
var = @source.copy("#{self}", :const => nil, :constant => nil, :dim => nil, :dimension => nil, :direction => nil, :dir => nil)
|
18
|
+
var = @source.copy("#{self}", :const => nil, :constant => nil, :dim => nil, :dimension => nil, :direction => nil, :dir => nil, :align => align)
|
14
19
|
return var
|
15
20
|
end
|
16
21
|
|
@@ -0,0 +1,241 @@
|
|
1
|
+
module BOAST
|
2
|
+
|
3
|
+
X86 = 1
|
4
|
+
ARM = 2
|
5
|
+
|
6
|
+
module Intrinsics
|
7
|
+
INTRINSICS = Hash::new { |h, k| h[k] = Hash::new { |h2, k2| h2[k2] = {} } }
|
8
|
+
|
9
|
+
def intrinsics
|
10
|
+
return INTRINSICS
|
11
|
+
end
|
12
|
+
|
13
|
+
module_function :intrinsics
|
14
|
+
|
15
|
+
def get_vector_name( type )
|
16
|
+
s = ""
|
17
|
+
case type
|
18
|
+
when Int
|
19
|
+
s += "u" if type.signed?
|
20
|
+
s += "int"
|
21
|
+
when Real
|
22
|
+
s += "float"
|
23
|
+
else
|
24
|
+
raise "Undefined vector type!"
|
25
|
+
end
|
26
|
+
s += "#{type.size*8}"
|
27
|
+
s += "x#{type.vector_length}"
|
28
|
+
return s.to_sym
|
29
|
+
end
|
30
|
+
|
31
|
+
module_function :get_vector_name
|
32
|
+
|
33
|
+
def vector_type_name( type, size, vector_size, sign = :signed )
|
34
|
+
s = ""
|
35
|
+
case type
|
36
|
+
when :int
|
37
|
+
case sign
|
38
|
+
when :signed
|
39
|
+
s += "int"
|
40
|
+
when :unsigned
|
41
|
+
s += "uint"
|
42
|
+
else
|
43
|
+
raise "Invalid sign!"
|
44
|
+
end
|
45
|
+
when :float
|
46
|
+
s += "float"
|
47
|
+
else
|
48
|
+
raise "Invalid type!"
|
49
|
+
end
|
50
|
+
s += "#{size}"
|
51
|
+
s += "x#{vector_size/size}"
|
52
|
+
return s.to_sym
|
53
|
+
end
|
54
|
+
|
55
|
+
module_function :vector_type_name
|
56
|
+
|
57
|
+
def type_name_ARM( type, size, sign = :signed )
|
58
|
+
s = ""
|
59
|
+
case type
|
60
|
+
when :int
|
61
|
+
case sign
|
62
|
+
when :signed
|
63
|
+
s += "s"
|
64
|
+
when :unsigned
|
65
|
+
s += "u"
|
66
|
+
else
|
67
|
+
raise "Invalid sign!"
|
68
|
+
end
|
69
|
+
when :float
|
70
|
+
s += "f"
|
71
|
+
else
|
72
|
+
raise "Invalid type!"
|
73
|
+
end
|
74
|
+
s += "#{size}"
|
75
|
+
return s
|
76
|
+
end
|
77
|
+
|
78
|
+
module_function :type_name_ARM
|
79
|
+
|
80
|
+
def type_name_X86( type, size, vector_size, sign = :signed )
|
81
|
+
s = ""
|
82
|
+
e = ( vector_size > 64 ? "e" : "" )
|
83
|
+
case type
|
84
|
+
when :int
|
85
|
+
s += "#{e}p"
|
86
|
+
case sign
|
87
|
+
when :signed
|
88
|
+
s += "i"
|
89
|
+
when :unsigned
|
90
|
+
s += "u"
|
91
|
+
else
|
92
|
+
raise "Invalid sign!"
|
93
|
+
end
|
94
|
+
s += "#{size}"
|
95
|
+
when :float
|
96
|
+
s += "p"
|
97
|
+
case size
|
98
|
+
when 32
|
99
|
+
s += "s"
|
100
|
+
when 64
|
101
|
+
s += "d"
|
102
|
+
else
|
103
|
+
raise "Invalid size!"
|
104
|
+
end
|
105
|
+
else
|
106
|
+
raise "Invalid type!"
|
107
|
+
end
|
108
|
+
return s
|
109
|
+
end
|
110
|
+
|
111
|
+
module_function :type_name_X86
|
112
|
+
|
113
|
+
[64, 128, 256].each { |vector_size|
|
114
|
+
vs = ( vector_size < 256 ? "" : "#{vector_size}" )
|
115
|
+
sizes = [8, 16, 32]
|
116
|
+
sizes.push( 64 ) if vector_size > 64
|
117
|
+
sizes.each { |size|
|
118
|
+
[:signed, :unsigned].each { |sign|
|
119
|
+
vtype = vector_type_name( :int, size, vector_size, sign )
|
120
|
+
type = type_name_X86( :int, size, vector_size )
|
121
|
+
instructions = [[:ADD, "add"], [:SUB, "sub"]]
|
122
|
+
instructions.push( [:SET, "setr"], [:SET1, "set1"] )
|
123
|
+
instructions.push( [:MUL, "mullo"] ) if vector_size > 64 and size >= 16 and size <= 32
|
124
|
+
instructions.each { |cl, ins|
|
125
|
+
INTRINSICS[X86][cl][vtype] = "_mm#{vs}_#{ins}_#{type}".to_sym
|
126
|
+
}
|
127
|
+
if size == 64 and vector_size < 512 then
|
128
|
+
INTRINSICS[X86][:SET1][vtype] = "_mm#{vs}_set1_#{type}x".to_sym
|
129
|
+
end
|
130
|
+
}
|
131
|
+
}
|
132
|
+
[8, 16, 32, 64].each { |size|
|
133
|
+
[:signed, :unsigned].each { |sign|
|
134
|
+
vtype = vector_type_name( :int, size, vector_size, sign )
|
135
|
+
[[:LOAD, "loadu"], [:LOADA, "load"],
|
136
|
+
[:STORE, "storeu"], [:STOREA, "store"]].each { |cl, ins|
|
137
|
+
INTRINSICS[X86][cl][vtype] = "_mm#{vs}_#{ins}_si#{vector_size}".to_sym
|
138
|
+
}
|
139
|
+
}
|
140
|
+
} if vector_size > 64
|
141
|
+
sizes = []
|
142
|
+
sizes.push( 32, 64 ) if vector_size > 64
|
143
|
+
sizes.each { |size|
|
144
|
+
[[:ADD, "add"], [:SUB, "sub"], [:MUL, "mul"], [:DIV, "div"],
|
145
|
+
[:FMADD, "fmadd"], [:FMSUB, "fmsub"], [:FNMADD, "fnmadd"], [:FNMSUB, "fnmsub"],
|
146
|
+
[:ADDSUB, "addsub"], [:FMADDSUB, "fmaddsub"], [:FMSUBADD, "fmsubadd"],
|
147
|
+
[:LOAD, "loadu"], [:LOADA, "load"],
|
148
|
+
[:STORE, "storeu"], [:STOREA, "store"],
|
149
|
+
[:SET, "set"], [:SET1, "set1"] ].each { |cl, ins|
|
150
|
+
vtype = vector_type_name( :float, size, vector_size)
|
151
|
+
type = type_name_X86( :float, size, vector_size )
|
152
|
+
INTRINSICS[X86][cl][vtype] = "_mm#{vs}_#{ins}_#{type}".to_sym
|
153
|
+
}
|
154
|
+
}
|
155
|
+
}
|
156
|
+
INTRINSICS[X86][:CVT] = Hash::new { |h,k| h[k] = {} }
|
157
|
+
[128, 256].each { |bvsize|
|
158
|
+
[16, 32, 64].each { |bsize|
|
159
|
+
ssize = bsize/2
|
160
|
+
while ssize >= 8
|
161
|
+
svsize = (bvsize/bsize)*ssize
|
162
|
+
[:signed, :unsigned].each { |sign|
|
163
|
+
stype = type_name_X86( :int, ssize, 128, sign )
|
164
|
+
btype = type_name_X86( :int, bsize, bvsize, :signed )
|
165
|
+
svtype = vector_type_name( :int, ssize, svsize, sign )
|
166
|
+
bvtype = vector_type_name( :int, bsize, bvsize, :signed )
|
167
|
+
vs = ( bvsize < 256 ? "" : "#{bvsize}" )
|
168
|
+
INTRINSICS[X86][:CVT][bvtype][svtype] = "_mm#{vs}_cvt#{stype}_#{btype}".to_sym
|
169
|
+
}
|
170
|
+
ssize /= 2
|
171
|
+
end
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
|
176
|
+
[64, 128].each { |vector_size|
|
177
|
+
q = (vector_size == 128 ? "q" : "")
|
178
|
+
[8, 16, 32, 64].each { |size|
|
179
|
+
[:signed, :unsigned].each { |sign|
|
180
|
+
vtype = vector_type_name( :int, size, vector_size, sign )
|
181
|
+
type = type_name_ARM( :int, size, sign )
|
182
|
+
instructions = [[:ADD, "add"], [:SUB, "sub"]]
|
183
|
+
instructions.push( [:MUL, "mul"], [:FMADD, "mla"], [:FNMSUB, "mls"] ) if size < 64
|
184
|
+
instructions.push( [:LOAD, "ldl"], [:LOADA, "ldl"] )
|
185
|
+
instructions.push( [:STORE, "stl"], [:STOREA, "stl"] )
|
186
|
+
instructions.each { |cl, ins|
|
187
|
+
INTRINSICS[ARM][cl][vtype] = "v#{ins}#{q}_#{type}".to_sym
|
188
|
+
}
|
189
|
+
[[:SET1, "dup"]].each { |cl, ins|
|
190
|
+
INTRINSICS[ARM][cl][vtype] = "v#{ins}#{q}_n_#{type}".to_sym
|
191
|
+
}
|
192
|
+
[[:SET_LANE, "set"]].each { |cl, ins|
|
193
|
+
INTRINSICS[ARM][cl][vtype] = "v#{ins}#{q}_lane_#{type}".to_sym
|
194
|
+
}
|
195
|
+
}
|
196
|
+
}
|
197
|
+
[32].each { |size|
|
198
|
+
vtype = vector_type_name( :float, size, vector_size )
|
199
|
+
type = type_name_ARM( :float, size )
|
200
|
+
[[:ADD, "add"], [:SUB, "sub"], [:MUL, "mul"],
|
201
|
+
[:FMADD, "mla"], [:FNMSUB, "mls"],
|
202
|
+
[:LOAD, "ldl"], [:LOADA, "ldl"],
|
203
|
+
[:STORE, "stl"], [:STOREA, "stl"]].each { |cl, ins|
|
204
|
+
INTRINSICS[ARM][cl][vtype] = "v#{ins}#{q}_#{type}".to_sym
|
205
|
+
}
|
206
|
+
[[:SET1, "dup"]].each { |cl, ins|
|
207
|
+
INTRINSICS[ARM][cl][vtype] = "v#{ins}#{q}_n_#{type}".to_sym
|
208
|
+
}
|
209
|
+
}
|
210
|
+
}
|
211
|
+
INTRINSICS[ARM][:CVT] = Hash::new { |h,k| h[k] = {} }
|
212
|
+
[64, 128].each { |vector_size|
|
213
|
+
int_size = 32
|
214
|
+
float_size = 32
|
215
|
+
q = (vector_size == 128 ? "q" : "")
|
216
|
+
[:signed, :unsigned].each { |sign|
|
217
|
+
fvtype = vector_type_name( :float, float_size, vector_size )
|
218
|
+
ivtype = vector_type_name( :int, int_size, vector_size, sign )
|
219
|
+
ftype = type_name_ARM( :float, float_size )
|
220
|
+
itype = type_name_ARM( :int, int_size, sign )
|
221
|
+
INTRINSICS[ARM][:CVT][fvtype][ivtype] = "vcvt#{q}_#{itype}_#{ftype}".to_sym
|
222
|
+
INTRINSICS[ARM][:CVT][ivtype][fvtype] = "vcvt#{q}_#{ftype}_#{itype}".to_sym
|
223
|
+
}
|
224
|
+
}
|
225
|
+
svsize = 64
|
226
|
+
bvsize = 128
|
227
|
+
[16, 32, 64].each { |bsize|
|
228
|
+
ssize = bsize/2
|
229
|
+
[:signed, :unsigned].each { |sign|
|
230
|
+
stype = type_name_ARM( :int, ssize, sign )
|
231
|
+
btype = type_name_ARM( :int, bsize, sign )
|
232
|
+
svtype = vector_type_name( :int, ssize, svsize, sign )
|
233
|
+
bvtype = vector_type_name( :int, bsize, bvsize, sign )
|
234
|
+
INTRINSICS[ARM][:CVT][svtype][bvtype] = "vmovl_#{stype}".to_sym
|
235
|
+
INTRINSICS[ARM][:CVT][bvtype][svtype] = "vmovn_#{btype}".to_sym
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
@@ -2,113 +2,18 @@ module BOAST
|
|
2
2
|
|
3
3
|
class Operator
|
4
4
|
extend PrivateStateAccessor
|
5
|
+
extend Intrinsics
|
5
6
|
|
6
7
|
def Operator.inspect
|
7
8
|
return "#{name}"
|
8
9
|
end
|
9
10
|
|
10
|
-
def Operator.get_vector_name(type)
|
11
|
-
case get_architecture
|
12
|
-
when X86
|
13
|
-
case type
|
14
|
-
when Int
|
15
|
-
size = "#{type.size*8}"
|
16
|
-
name = ""
|
17
|
-
if type.total_size*8 > 64
|
18
|
-
name += "e"
|
19
|
-
end
|
20
|
-
if type.vector_length > 1 then
|
21
|
-
name += "p"
|
22
|
-
else
|
23
|
-
name = "s"
|
24
|
-
end
|
25
|
-
if type.signed then
|
26
|
-
name += "i"
|
27
|
-
else
|
28
|
-
name += "u"
|
29
|
-
end
|
30
|
-
return name += size
|
31
|
-
when Real
|
32
|
-
case type.size
|
33
|
-
when 4
|
34
|
-
return "ps" if type.vector_length > 1
|
35
|
-
return "ss"
|
36
|
-
when 8
|
37
|
-
return "pd" if type.vector_length > 1
|
38
|
-
return "sd"
|
39
|
-
end
|
40
|
-
else
|
41
|
-
raise "Undefined vector type!"
|
42
|
-
end
|
43
|
-
when ARM
|
44
|
-
case type
|
45
|
-
when Int
|
46
|
-
name = "#{ type.signed ? "s" : "u" }"
|
47
|
-
name += "#{ type.size * 8}"
|
48
|
-
return name
|
49
|
-
when Real
|
50
|
-
return "f#{type.size*8}"
|
51
|
-
else
|
52
|
-
raise "Undefined vector type!"
|
53
|
-
end
|
54
|
-
else
|
55
|
-
raise "Unsupported architecture!"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
11
|
def Operator.convert(arg, type)
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
n2 = get_vector_name(type)
|
66
|
-
if s1 <= 128 and s2 <= 128 then
|
67
|
-
return "_mm_cvt#{n1}_#{n2}( #{arg} )"
|
68
|
-
elsif [s1, s2].max <= 256 then
|
69
|
-
return "_mm256_cvt#{n1}_#{n2}( #{arg} )"
|
70
|
-
elsif [s1, s2].max <= 512 then
|
71
|
-
return "_mm512_cvt#{n1}_#{n2}( #{arg} )"
|
72
|
-
end
|
73
|
-
when ARM
|
74
|
-
if type.class != arg.type.class then
|
75
|
-
if type.size == arg.type.size then
|
76
|
-
s = type.total_size*8
|
77
|
-
n1 = get_vector_name(arg.type)
|
78
|
-
n2 = get_vector_name(type)
|
79
|
-
return "vcvt#{ s == 128 ? "q" : "" }_#{n2}_#{n1}( #{arg} )"
|
80
|
-
elsif type.class == Real then
|
81
|
-
intr = convert(arg, arg.type.copy(:size=>type.size))
|
82
|
-
return convert(arg.copy(intr, :size => type.size ), type)
|
83
|
-
else
|
84
|
-
n1 = get_vector_name(arg.type)
|
85
|
-
s = type.total_size*8
|
86
|
-
t2 = type.copy(:size => arg.type.size)
|
87
|
-
n2 = get_vector_name( t2 )
|
88
|
-
intr = "vcvt#{ s == 128 ? "q" : "" }_#{n2}_#{n1}( #{arg} )"
|
89
|
-
return convert(Variable::from_type(intr, t2), type)
|
90
|
-
end
|
91
|
-
elsif type.class != Real then
|
92
|
-
n = get_vector_name(arg.type)
|
93
|
-
if type.size == arg.type.size then
|
94
|
-
if type.signed == arg.type.signed then
|
95
|
-
return "#{arg}"
|
96
|
-
else
|
97
|
-
n2 = get_vector_name(type)
|
98
|
-
return "vreinterpret_#{n2}_#{n}( #{arg} )"
|
99
|
-
end
|
100
|
-
elsif type.size < arg.type.size then
|
101
|
-
intr = "vmovn_#{n}( #{arg} )"
|
102
|
-
s = arg.type.size/2
|
103
|
-
else
|
104
|
-
intr = "vmovl_#{n}( #{arg} )"
|
105
|
-
s = arg.type.size*2
|
106
|
-
end
|
107
|
-
return convert(arg.copy(intr, :size => s), type)
|
108
|
-
end
|
109
|
-
else
|
110
|
-
raise "Unsupported architecture!"
|
111
|
-
end
|
12
|
+
return "convert_#{type.decl}( #{arg} )" if lang == CL
|
13
|
+
|
14
|
+
instruction = intrinsics[get_architecture][:CVT][get_vector_name(type)][get_vector_name(arg.type)]
|
15
|
+
raise "Unavailable conversion from #{get_vector_name(arg.type)} to #{get_vector_name(type)}!" if not instruction
|
16
|
+
return "#{instruction}( #{arg} )"
|
112
17
|
end
|
113
18
|
|
114
19
|
end
|
@@ -120,44 +25,11 @@ module BOAST
|
|
120
25
|
if lang == C and (arg1.class == Variable and arg2.class == Variable) and (arg1.type.vector_length > 1 or arg2.type.vector_length > 1) then
|
121
26
|
raise "Vectors have different length: #{arg1} #{arg1.type.vector_length}, #{arg2} #{arg2.type.vector_length}" if arg1.type.vector_length != arg2.type.vector_length
|
122
27
|
#puts "#{arg1.type.signed} #{arg2.type.signed} #{return_type.type.signed}"
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
a1 = convert(arg1, return_type.type)
|
129
|
-
else
|
130
|
-
a1 = "#{arg1}"
|
131
|
-
end
|
132
|
-
if arg2.type != return_type.type
|
133
|
-
a2 = convert(arg2, return_type.type)
|
134
|
-
else
|
135
|
-
a2 = "#{arg2}"
|
136
|
-
end
|
137
|
-
intr_name = "_mm"
|
138
|
-
if size > 128 then
|
139
|
-
intr_name += "#{size}"
|
140
|
-
end
|
141
|
-
intr_name += "_#{intr_name_X86}_#{return_name}"
|
142
|
-
return "#{intr_name}( #{a1}, #{a2} )"
|
143
|
-
when ARM
|
144
|
-
if arg1.type.class != return_type.type.class then
|
145
|
-
a1 = convert(arg1, return_type.type)
|
146
|
-
else
|
147
|
-
a1 = "#{arg1}"
|
148
|
-
end
|
149
|
-
if arg2.type.class != return_type.type.class then
|
150
|
-
a2 = convert(arg2, return_type.type)
|
151
|
-
else
|
152
|
-
a2 = "#{arg2}"
|
153
|
-
end
|
154
|
-
intr_name = "#{intr_name_ARM}"
|
155
|
-
intr_name += "q" if size == 128
|
156
|
-
intr_name += "_" + return_name + "( #{a1}, #{a2} )"
|
157
|
-
return intr_name
|
158
|
-
else
|
159
|
-
raise "Unsupported architecture!"
|
160
|
-
end
|
28
|
+
instruction = intrinsics[get_architecture][intr_symbol][get_vector_name(return_type.type)]
|
29
|
+
raise "Unavailable operator #{symbol} for #{get_vector_name(return_type.type)}!" unless instruction
|
30
|
+
a1 = ( arg1.type != return_type.type ? convert(arg1, return_type.type) : "#{arg1}" )
|
31
|
+
a2 = ( arg2.type != return_type.type ? convert(arg2, return_type.type) : "#{arg2}" )
|
32
|
+
return "#{instruction}( #{a1}, #{a2} )"
|
161
33
|
else
|
162
34
|
return basic_usage( arg1, arg2 )
|
163
35
|
end
|
@@ -168,31 +40,34 @@ module BOAST
|
|
168
40
|
class Set < Operator
|
169
41
|
|
170
42
|
def Set.to_s(arg1, arg2, return_type)
|
171
|
-
if lang == C then
|
43
|
+
if lang == C or lang == CL then
|
172
44
|
if arg1.class == Variable and arg1.type.vector_length > 1 then
|
173
|
-
if
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
intr_name = "_mm"
|
187
|
-
if size > 128 then
|
188
|
-
intr_name += "#{size}"
|
189
|
-
end
|
190
|
-
intr_name += "_set1_#{get_vector_name(arg1.type).gsub("u","")}"
|
191
|
-
intr_name += "x" if arg1.type.class == Int and arg1.type.size == 8
|
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}"
|
192
58
|
else
|
193
|
-
|
59
|
+
return "#{arg1} = #{instruction}( #{arg2.join(", ")} )"
|
194
60
|
end
|
195
|
-
|
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)}"
|
196
71
|
else
|
197
72
|
raise "Unknown convertion between vector of different length!"
|
198
73
|
end
|
@@ -223,111 +98,92 @@ module BOAST
|
|
223
98
|
|
224
99
|
end
|
225
100
|
|
226
|
-
class
|
227
|
-
|
228
|
-
def
|
229
|
-
if lang == C then
|
230
|
-
if arg1
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
a2 = "&" + a2
|
241
|
-
else
|
242
|
-
a2 = a2[1..-1]
|
243
|
-
end
|
244
|
-
case get_architecture
|
245
|
-
when ARM
|
246
|
-
intr_name = "vldl"
|
247
|
-
intr_name += "q" if size == 128
|
248
|
-
intr_name += "_#{get_vector_name(arg1.type)}"
|
249
|
-
when X86
|
250
|
-
if arg1.type.class == Int and size == 64 then
|
251
|
-
return "#{arg1} = _m_from_int64( *((int64_t * ) #{a2} ) )"
|
252
|
-
end
|
253
|
-
intr_name = "_mm"
|
254
|
-
if size > 128 then
|
255
|
-
intr_name += "#{size}"
|
256
|
-
end
|
257
|
-
intr_name += "_load_"
|
258
|
-
if arg1.type.class == Int then
|
259
|
-
intr_name += "si#{size}"
|
260
|
-
else
|
261
|
-
intr_name += "#{get_vector_name(arg1.type)}"
|
262
|
-
end
|
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)}"
|
263
115
|
else
|
264
|
-
raise "
|
116
|
+
raise "Unknown convertion between vectors of different length!"
|
265
117
|
end
|
266
|
-
return "#{arg1} = #{intr_name}( (#{arg1.type.decl} * ) #{a2} )"
|
267
118
|
else
|
268
|
-
|
119
|
+
Affectation.basic_usage(arg1, arg2)
|
269
120
|
end
|
270
|
-
elsif arg2.class == Variable and arg2.type.vector_length
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
a1 = "&" + a1
|
121
|
+
elsif arg2.class == Variable and arg2.type.vector_length == 1 then
|
122
|
+
a2 = "#{arg2}"
|
123
|
+
if a2[0] != "*" then
|
124
|
+
a2 = "&" + a2
|
275
125
|
else
|
276
|
-
|
126
|
+
a2 = a2[1..-1]
|
277
127
|
end
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
if arg2.type.class == Int and size == 64 then
|
285
|
-
return " *((int64_t * ) #{a1}) = _m_to_int64( #{arg2} )"
|
286
|
-
end
|
287
|
-
intr_name = "_mm"
|
288
|
-
if size > 128 then
|
289
|
-
intr_name += "#{size}"
|
290
|
-
end
|
291
|
-
intr_name += "_store_"
|
292
|
-
if arg2.type.class == Int then
|
293
|
-
intr_name += "si#{size}"
|
294
|
-
else
|
295
|
-
intr_name += "#{get_vector_name(arg2.type)}"
|
296
|
-
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)]
|
297
134
|
else
|
298
|
-
|
135
|
+
instruction = intrinsics[get_architecture][:LOAD][get_vector_name(return_type.type)]
|
299
136
|
end
|
300
|
-
|
137
|
+
raise "Unavailable operator load for #{get_vector_name(return_type.type)}!" unless instruction
|
138
|
+
return "#{instruction}( #{a2} )"
|
301
139
|
else
|
302
|
-
return
|
140
|
+
return "#{arg2}"
|
303
141
|
end
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
a1 = "#{arg1}"
|
319
|
-
if a1[0] != "*" then
|
320
|
-
a1 = "&" + a1
|
321
|
-
else
|
322
|
-
a1 = a1[1..-1]
|
323
|
-
end
|
324
|
-
return "vstore#{arg2.type.vector_length}(#{arg2}, 0, #{a1})"
|
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
|
325
156
|
else
|
326
|
-
|
157
|
+
a1 = a1[1..-1]
|
327
158
|
end
|
328
|
-
|
329
|
-
return
|
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} )"
|
330
172
|
end
|
173
|
+
return Affectation.basic_usage(arg1, arg2)
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
class Affectation < Operator
|
179
|
+
|
180
|
+
def Affectation.to_s(arg1, arg2, return_type)
|
181
|
+
if arg1.class == Variable and arg1.type.vector_length > 1 then
|
182
|
+
return Load.to_s(arg1, arg2, return_type)
|
183
|
+
elsif arg2.class == Variable and arg2.type.vector_length > 1 then
|
184
|
+
return Store.to_s(arg1, arg2, return_type)
|
185
|
+
end
|
186
|
+
return basic_usage(arg1, arg2)
|
331
187
|
end
|
332
188
|
|
333
189
|
def Affectation.basic_usage(arg1, arg2)
|
@@ -344,12 +200,8 @@ module BOAST
|
|
344
200
|
return "*"
|
345
201
|
end
|
346
202
|
|
347
|
-
def
|
348
|
-
return
|
349
|
-
end
|
350
|
-
|
351
|
-
def intr_name_ARM
|
352
|
-
return "vmul"
|
203
|
+
def intr_symbol
|
204
|
+
return :MUL
|
353
205
|
end
|
354
206
|
|
355
207
|
def basic_usage(arg1, arg2)
|
@@ -368,14 +220,10 @@ module BOAST
|
|
368
220
|
return "+"
|
369
221
|
end
|
370
222
|
|
371
|
-
def
|
372
|
-
return
|
223
|
+
def intr_symbol
|
224
|
+
return :ADD
|
373
225
|
end
|
374
226
|
|
375
|
-
def intr_name_ARM
|
376
|
-
return "vadd"
|
377
|
-
end
|
378
|
-
|
379
227
|
def basic_usage(arg1, arg2)
|
380
228
|
return "#{arg1} + #{arg2}"
|
381
229
|
end
|
@@ -392,14 +240,10 @@ module BOAST
|
|
392
240
|
return "-"
|
393
241
|
end
|
394
242
|
|
395
|
-
def
|
396
|
-
return
|
243
|
+
def intr_symbol
|
244
|
+
return :SUB
|
397
245
|
end
|
398
246
|
|
399
|
-
def intr_name_ARM
|
400
|
-
return "vsub"
|
401
|
-
end
|
402
|
-
|
403
247
|
def basic_usage(arg1, arg2)
|
404
248
|
return "#{arg1} - (#{arg2})"
|
405
249
|
end
|
@@ -416,14 +260,10 @@ module BOAST
|
|
416
260
|
return "/"
|
417
261
|
end
|
418
262
|
|
419
|
-
def
|
420
|
-
return
|
263
|
+
def intr_symbol
|
264
|
+
return :DIV
|
421
265
|
end
|
422
266
|
|
423
|
-
def intr_name_ARM
|
424
|
-
raise "Neon doesn't support division!"
|
425
|
-
end
|
426
|
-
|
427
267
|
def basic_usage(arg1, arg2)
|
428
268
|
return "(#{arg1}) / (#{arg2})"
|
429
269
|
end
|
@@ -89,22 +89,23 @@ module BOAST
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def close_c
|
92
|
-
decrement_indent_level
|
93
92
|
s = ""
|
94
|
-
s += "
|
95
|
-
|
93
|
+
s += indent + "return #{@properties[:return]};\n" if @properties[:return]
|
94
|
+
decrement_indent_level
|
95
|
+
s += indent + "}"
|
96
96
|
output.puts s
|
97
97
|
return self
|
98
98
|
end
|
99
99
|
|
100
100
|
def close_fortran
|
101
|
-
decrement_indent_level
|
102
101
|
s = ""
|
103
102
|
if @properties[:return] then
|
104
|
-
s += "
|
105
|
-
|
103
|
+
s += indent + "#{@name} = #{@properties[:return]}\n"
|
104
|
+
decrement_indent_level
|
105
|
+
s += indent + "END FUNCTION #{@name}"
|
106
106
|
else
|
107
|
-
|
107
|
+
decrement_indent_level
|
108
|
+
s += indent + "END SUBROUTINE #{@name}"
|
108
109
|
end
|
109
110
|
output.puts s
|
110
111
|
return self
|
@@ -125,7 +126,13 @@ module BOAST
|
|
125
126
|
end
|
126
127
|
|
127
128
|
def decl_fortran
|
128
|
-
|
129
|
+
output.puts indent + "INTERFACE"
|
130
|
+
increment_indent_level
|
131
|
+
open_fortran
|
132
|
+
close_fortran
|
133
|
+
decrement_indent_level
|
134
|
+
output.puts indent + "END INTERFACE"
|
135
|
+
return self
|
129
136
|
end
|
130
137
|
|
131
138
|
def decl_c_s
|
@@ -152,6 +159,13 @@ module BOAST
|
|
152
159
|
s += "__launch_bounds__(#{wgs[0]}*#{wgs[1]}*#{wgs[2]}) "
|
153
160
|
end
|
154
161
|
end
|
162
|
+
elsif lang == C then
|
163
|
+
if @properties[:local] then
|
164
|
+
s += "static "
|
165
|
+
end
|
166
|
+
if @properties[:inline] then
|
167
|
+
s+= "inline "
|
168
|
+
end
|
155
169
|
end
|
156
170
|
if @properties[:qualifiers] then
|
157
171
|
s += "#{@properties[:qualifiers]} "
|
@@ -173,7 +187,7 @@ module BOAST
|
|
173
187
|
end
|
174
188
|
|
175
189
|
def decl_c
|
176
|
-
s = decl_c_s + ";"
|
190
|
+
s = indent + decl_c_s + ";"
|
177
191
|
output.puts s
|
178
192
|
return self
|
179
193
|
end
|
@@ -196,10 +210,13 @@ module BOAST
|
|
196
210
|
s += "SUBROUTINE "
|
197
211
|
end
|
198
212
|
s += "#{@name}("
|
199
|
-
s += parameters.join(", ")
|
213
|
+
s += parameters.collect(&:name).join(", ")
|
200
214
|
s += ")"
|
201
215
|
end
|
202
216
|
|
217
|
+
def pr_align
|
218
|
+
end
|
219
|
+
|
203
220
|
def open_c
|
204
221
|
s = decl_c_s + "{"
|
205
222
|
output.puts s
|
@@ -209,14 +226,14 @@ module BOAST
|
|
209
226
|
}
|
210
227
|
if lang == C then
|
211
228
|
parameters.each { |p|
|
212
|
-
p.
|
229
|
+
p.pr_align
|
213
230
|
}
|
214
231
|
end
|
215
232
|
return self
|
216
233
|
end
|
217
234
|
|
218
235
|
def open_fortran
|
219
|
-
s = to_s_fortran
|
236
|
+
s = indent + to_s_fortran
|
220
237
|
s += "\n"
|
221
238
|
increment_indent_level
|
222
239
|
s += indent + "integer, parameter :: wp=kind(1.0d0)"
|
@@ -226,7 +243,7 @@ module BOAST
|
|
226
243
|
}
|
227
244
|
parameters.each { |p|
|
228
245
|
p.decl
|
229
|
-
p.
|
246
|
+
p.pr_align
|
230
247
|
}
|
231
248
|
return self
|
232
249
|
end
|
@@ -137,7 +137,9 @@ module BOAST
|
|
137
137
|
attr_reader :texture
|
138
138
|
attr_reader :sampler
|
139
139
|
attr_reader :restrict
|
140
|
-
attr_reader :
|
140
|
+
attr_reader :deferred_shape
|
141
|
+
attr_reader :optional
|
142
|
+
attr_accessor :align
|
141
143
|
attr_accessor :replace_constant
|
142
144
|
attr_accessor :force_replace_constant
|
143
145
|
|
@@ -177,10 +179,18 @@ module BOAST
|
|
177
179
|
!!@scalar_output
|
178
180
|
end
|
179
181
|
|
182
|
+
def optional?
|
183
|
+
!!@optional
|
184
|
+
end
|
185
|
+
|
180
186
|
def align?
|
181
187
|
!!@align
|
182
188
|
end
|
183
189
|
|
190
|
+
def deferred_shape?
|
191
|
+
!!@deferred_shape
|
192
|
+
end
|
193
|
+
|
184
194
|
def initialize(name,type,hash={})
|
185
195
|
@name = name.to_s
|
186
196
|
@direction = hash[:direction] ? hash[:direction] : hash[:dir]
|
@@ -191,6 +201,8 @@ module BOAST
|
|
191
201
|
@allocate = hash[:allocate]
|
192
202
|
@restrict = hash[:restrict]
|
193
203
|
@align = hash[:align]
|
204
|
+
@deferred_shape = hash[:deferred_shape]
|
205
|
+
@optional = hash[:optional]
|
194
206
|
@force_replace_constant = false
|
195
207
|
if not hash[:replace_constant].nil? then
|
196
208
|
@replace_constant = hash[:replace_constant]
|
@@ -303,7 +315,7 @@ module BOAST
|
|
303
315
|
return s
|
304
316
|
end
|
305
317
|
|
306
|
-
def decl_ffi(alloc
|
318
|
+
def decl_ffi(alloc, lang)
|
307
319
|
return :pointer if lang == FORTRAN and not alloc
|
308
320
|
return :pointer if dimension?
|
309
321
|
return :pointer if @direction == :out or @direction == :inout and not alloc
|
@@ -335,7 +347,7 @@ module BOAST
|
|
335
347
|
}.join("][")
|
336
348
|
s += "]"
|
337
349
|
else
|
338
|
-
if dimension? and not constant? and not allocate? and (not local? or (local? and device)) then
|
350
|
+
if dimension? and not constant? and not ( allocate? and @allocate != :heap ) and (not local? or (local? and device)) then
|
339
351
|
s += " *"
|
340
352
|
if restrict? and not decl_module? then
|
341
353
|
if lang == CL
|
@@ -352,13 +364,13 @@ module BOAST
|
|
352
364
|
if dimension? and constant? then
|
353
365
|
s += "[]"
|
354
366
|
end
|
355
|
-
if dimension? and ((local? and not device) or (allocate? and not constant?)) then
|
367
|
+
if dimension? and ((local? and not device) or ( ( allocate? and @allocate != :heap ) and not constant?)) then
|
356
368
|
s +="[("
|
357
369
|
s += @dimension.collect{ |d| d.to_s }.reverse.join(")*(")
|
358
370
|
s +=")]"
|
359
371
|
end
|
360
372
|
end
|
361
|
-
if dimension? and (align? or default_align > 1) and (constant? or allocate?) then
|
373
|
+
if dimension? and (align? or default_align > 1) and (constant? or (allocate? and @allocate != :heap ) ) then
|
362
374
|
a = ( align? ? align : 1 )
|
363
375
|
a = ( a >= default_align ? a : default_align )
|
364
376
|
s+= " __attribute((aligned(#{a})))"
|
@@ -399,54 +411,111 @@ module BOAST
|
|
399
411
|
return self
|
400
412
|
end
|
401
413
|
|
402
|
-
def
|
414
|
+
def pr_align_c_s(a)
|
403
415
|
return "__assume_aligned(#{@name}, #{a})"
|
404
416
|
end
|
405
417
|
|
406
|
-
def
|
418
|
+
def pr_align_c(a)
|
407
419
|
s = ""
|
408
420
|
s += indent
|
409
|
-
s +=
|
421
|
+
s += pr_align_c_s(a)
|
410
422
|
s += finalize
|
411
423
|
output.print s
|
412
424
|
return self
|
413
425
|
end
|
414
426
|
|
415
|
-
def
|
427
|
+
def pr_align_fortran_s(a)
|
416
428
|
return "!DIR$ ASSUME_ALIGNED #{@name}: #{a}"
|
417
429
|
end
|
418
430
|
|
419
|
-
def
|
431
|
+
def pr_align_fortran(a)
|
420
432
|
s = ""
|
421
433
|
s += indent
|
422
|
-
s +=
|
434
|
+
s += pr_align_fortran_s(a)
|
423
435
|
s += finalize
|
424
436
|
output.print s
|
425
437
|
return self
|
426
438
|
end
|
427
439
|
|
428
|
-
def
|
440
|
+
def pr_align
|
429
441
|
if dimension? then
|
430
442
|
if align? or default_align > 1 then
|
431
443
|
a = ( align? ? align : 1 )
|
432
444
|
a = ( a >= default_align ? a : default_align )
|
433
|
-
return
|
434
|
-
return
|
445
|
+
return pr_align_c(a) if lang == C
|
446
|
+
return pr_align_fortran(a) if lang == FORTRAN
|
435
447
|
end
|
436
448
|
end
|
437
449
|
end
|
438
450
|
|
451
|
+
def alloc_fortran( dims = nil )
|
452
|
+
s = ""
|
453
|
+
s += indent
|
454
|
+
s += "allocate( #{name}("
|
455
|
+
s += dims.collect { |d| d.to_s }.join(", ")
|
456
|
+
s += ") )"
|
457
|
+
s += finalize
|
458
|
+
output.print s
|
459
|
+
return self
|
460
|
+
end
|
461
|
+
|
462
|
+
def alloc_c( dims = nil )
|
463
|
+
s = ""
|
464
|
+
s += indent
|
465
|
+
s += "#{name} = (#{@type.decl} *)malloc( sizeof(#{@type.decl})*("
|
466
|
+
s += dims.collect { |d| d.to_s }.reverse.join(")*(")
|
467
|
+
s += ") )"
|
468
|
+
s += finalize
|
469
|
+
output.print s
|
470
|
+
return self
|
471
|
+
end
|
472
|
+
|
473
|
+
def alloc( dims = nil )
|
474
|
+
@dimension = [dims].flatten if dims
|
475
|
+
dims = @dimension
|
476
|
+
raise "Cannot allocate array with unknown dimension!" unless dims
|
477
|
+
return alloc_fortran(dims) if lang == FORTRAN
|
478
|
+
return alloc_c(dims) if lang == C
|
479
|
+
end
|
480
|
+
|
481
|
+
def dealloc_fortran
|
482
|
+
s = ""
|
483
|
+
s += indent
|
484
|
+
s += "deallocate( #{name} )"
|
485
|
+
s += finalize
|
486
|
+
output.print s
|
487
|
+
return self
|
488
|
+
end
|
489
|
+
|
490
|
+
def dealloc_c
|
491
|
+
s = ""
|
492
|
+
s += indent
|
493
|
+
s += "free( #{name} )"
|
494
|
+
s += finalize
|
495
|
+
output.print s
|
496
|
+
return self
|
497
|
+
end
|
498
|
+
|
499
|
+
def dealloc
|
500
|
+
return dealloc_fortran if lang == FORTRAN
|
501
|
+
return dealloc_c if lang == C
|
502
|
+
end
|
503
|
+
|
439
504
|
def decl_fortran
|
440
505
|
s = ""
|
441
506
|
s += indent
|
442
507
|
s += @type.decl
|
443
|
-
s += ", intent(#{@direction})" if @direction
|
508
|
+
s += ", intent(#{@direction})" if @direction
|
509
|
+
s += ", optional" if optional?
|
510
|
+
s += ", allocatable" if allocate? and @allocate == :heap
|
444
511
|
s += ", parameter" if constant?
|
445
512
|
if dimension? then
|
446
513
|
s += ", dimension("
|
447
514
|
s += @dimension.collect { |d|
|
448
515
|
dim = d.to_s
|
449
|
-
if
|
516
|
+
if deferred_shape? or ( allocate? and @allocate == :heap )
|
517
|
+
":"
|
518
|
+
elsif dim then
|
450
519
|
dim.to_s
|
451
520
|
else
|
452
521
|
"*"
|
@@ -461,7 +530,7 @@ module BOAST
|
|
461
530
|
end
|
462
531
|
s += finalize
|
463
532
|
output.print s
|
464
|
-
if dimension? and (align? or default_align > 1) and (constant? or allocate?) then
|
533
|
+
if dimension? and (align? or default_align > 1) and (constant? or ( allocate? and @allocate != :heap ) ) then
|
465
534
|
a = ( align? ? align : 1 )
|
466
535
|
a = ( a >= default_align ? a : default_align )
|
467
536
|
s = ""
|
data/lib/BOAST/Runtime/Config.rb
CHANGED
@@ -29,7 +29,7 @@ module BOAST
|
|
29
29
|
module #{module_name}
|
30
30
|
extend FFI::Library
|
31
31
|
ffi_lib "#{library_path}"
|
32
|
-
attach_function :#{method_name}, [ #{@procedure.parameters.collect{ |p| ":"+p.decl_ffi.to_s }.join(", ")} ], :#{@procedure.properties[:return] ? @procedure.properties[:return].type.decl_ffi : "void" }
|
32
|
+
attach_function :#{method_name}, [ #{@procedure.parameters.collect{ |p| ":"+p.decl_ffi(false,@lang).to_s }.join(", ")} ], :#{@procedure.properties[:return] ? @procedure.properties[:return].type.decl_ffi(false,@lang) : "void" }
|
33
33
|
def run(*args)
|
34
34
|
if args.length < @procedure.parameters.length or args.length > @procedure.parameters.length + 1 then
|
35
35
|
raise "Wrong number of arguments for \#{@procedure.name} (\#{args.length} for \#{@procedure.parameters.length})"
|
@@ -47,9 +47,9 @@ module BOAST
|
|
47
47
|
r_args = {}
|
48
48
|
if @lang == FORTRAN then
|
49
49
|
@procedure.parameters.each_with_index { |p, i|
|
50
|
-
if p.decl_ffi(true) != :pointer then
|
51
|
-
arg_p = FFI::MemoryPointer::new(p.decl_ffi(true))
|
52
|
-
arg_p.send("write_\#{p.decl_ffi(true)}",args[i])
|
50
|
+
if p.decl_ffi(true,@lang) != :pointer then
|
51
|
+
arg_p = FFI::MemoryPointer::new(p.decl_ffi(true, @lang))
|
52
|
+
arg_p.send("write_\#{p.decl_ffi(true, @lang)}",args[i])
|
53
53
|
t_args.push(arg_p)
|
54
54
|
r_args[p] = arg_p if p.scalar_output?
|
55
55
|
else
|
@@ -59,8 +59,8 @@ module BOAST
|
|
59
59
|
else
|
60
60
|
@procedure.parameters.each_with_index { |p, i|
|
61
61
|
if p.scalar_output? then
|
62
|
-
arg_p = FFI::MemoryPointer::new(p.decl_ffi(true))
|
63
|
-
arg_p.send("write_\#{p.decl_ffi(true)}",args[i])
|
62
|
+
arg_p = FFI::MemoryPointer::new(p.decl_ffi(true, @lang))
|
63
|
+
arg_p.send("write_\#{p.decl_ffi(true,@lang)}",args[i])
|
64
64
|
t_args.push(arg_p)
|
65
65
|
r_args[p] = arg_p
|
66
66
|
else
|
@@ -87,7 +87,7 @@ module BOAST
|
|
87
87
|
if r_args.length > 0 then
|
88
88
|
ref_return = {}
|
89
89
|
r_args.each { |p, p_arg|
|
90
|
-
ref_return[p.name.to_sym] = p_arg.send("read_\#{p.decl_ffi(true)}")
|
90
|
+
ref_return[p.name.to_sym] = p_arg.send("read_\#{p.decl_ffi(true, @lang)}")
|
91
91
|
}
|
92
92
|
results[:reference_return] = ref_return
|
93
93
|
end
|
data/lib/BOAST/Runtime/MAQAO.rb
CHANGED
@@ -16,9 +16,9 @@ module BOAST
|
|
16
16
|
f2.close
|
17
17
|
|
18
18
|
if verbose? then
|
19
|
-
puts "#{compiler_options[:MAQAO]} cqa #{f1.path} --fct=#{@procedure.name}"
|
19
|
+
puts "#{compiler_options[:MAQAO]} cqa #{f1.path} --fct=#{@procedure.name} #{compiler_options[:MAQAO_FLAGS]}"
|
20
20
|
end
|
21
|
-
result = `#{compiler_options[:MAQAO]} cqa #{f1.path} --fct=#{@procedure.name}`
|
21
|
+
result = `#{compiler_options[:MAQAO]} cqa #{f1.path} --fct=#{@procedure.name} #{compiler_options[:MAQAO_FLAGS]}`
|
22
22
|
File::unlink(library_object)
|
23
23
|
File::unlink(library_source)
|
24
24
|
return result
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: BOAST
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brice Videau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: narray
|
@@ -188,6 +188,7 @@ files:
|
|
188
188
|
- lib/BOAST/Language/If.rb
|
189
189
|
- lib/BOAST/Language/Index.rb
|
190
190
|
- lib/BOAST/Language/Inspectable.rb
|
191
|
+
- lib/BOAST/Language/Intrinsics.rb
|
191
192
|
- lib/BOAST/Language/OpenMP.rb
|
192
193
|
- lib/BOAST/Language/Operators.rb
|
193
194
|
- lib/BOAST/Language/Optimization.rb
|
@@ -199,6 +200,7 @@ files:
|
|
199
200
|
- lib/BOAST/Language/State.rb
|
200
201
|
- lib/BOAST/Language/Transitions.rb
|
201
202
|
- lib/BOAST/Language/Variable.rb
|
203
|
+
- lib/BOAST/Language/Vector.rb
|
202
204
|
- lib/BOAST/Language/While.rb
|
203
205
|
- lib/BOAST/Runtime/CKernel.rb
|
204
206
|
- lib/BOAST/Runtime/CRuntime.rb
|