BOAST 1.0.7 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- if get_architecture == X86 then
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
- # @vector_length.times{ |indx|
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
- if get_architecture == X86 then
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
- elsif lang == CL then
233
- #char="cl_"
234
- char=""
235
- char += "u" if not @signed
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
- char += "char"
206
+ s += "char"
239
207
  when 2
240
- char += "short"
208
+ s += "short"
241
209
  when 4
242
- char += "int"
210
+ s += "int"
243
211
  when 8
244
- char += "long"
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
- char += "int"
223
+ s += "int"
247
224
  else
248
225
  raise "Unsupported integer size!"
249
226
  end
250
227
  if @vector_length > 1 then
251
- char += "#{@vector_length}"
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
 
@@ -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,7 +1,7 @@
1
1
  module BOAST
2
2
 
3
3
  boolean_state_accessor :boast_inspect
4
- @@boast_inspect = false
4
+ default_state_getter :boast_inspect, false, nil, :INSPECT
5
5
 
6
6
  module Inspectable
7
7
 
@@ -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" if type.signed?
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, "set"], [:SET1, "set1"] ].each { |cl, ins|
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"], [:FNMSUB, "mls"] ) if size < 64
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