BOAST 1.0.6 → 1.0.7
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 +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
|