BOAST 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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