BOAST 0.6 → 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.
- data/BOAST.gemspec +2 -2
- data/lib/BOAST.rb +2 -0
- data/lib/BOAST/Algorithm.rb +70 -218
- data/lib/BOAST/DataTypes.rb +318 -0
- data/lib/BOAST/Operators.rb +391 -0
- data/lib/BOAST/Transitions.rb +6 -6
- metadata +4 -2
data/BOAST.gemspec
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'BOAST'
|
3
|
-
s.version = "0.
|
3
|
+
s.version = "0.7"
|
4
4
|
s.author = "Brice Videau"
|
5
5
|
s.email = "brice.videau@imag.fr"
|
6
6
|
s.homepage = "https://forge.imag.fr/projects/boast/"
|
7
7
|
s.summary = "BOAST is a computing kernel metaprogramming tool."
|
8
8
|
s.description = "BOAST aims at providing a framework to metaprogram, benchmark and validate computing kernels"
|
9
|
-
s.files = %w( BOAST.gemspec LICENSE lib/BOAST.rb lib/BOAST/Algorithm.rb lib/BOAST/CKernel.rb lib/BOAST/BOAST_OpenCL.rb lib/BOAST/Transitions.rb lib/BOAST/Parens.rb)
|
9
|
+
s.files = %w( BOAST.gemspec LICENSE lib/BOAST.rb lib/BOAST/Algorithm.rb lib/BOAST/CKernel.rb lib/BOAST/BOAST_OpenCL.rb lib/BOAST/Transitions.rb lib/BOAST/Parens.rb lib/BOAST/Operators.rb lib/BOAST/DataTypes.rb )
|
10
10
|
s.has_rdoc = true
|
11
11
|
s.license = 'BSD'
|
12
12
|
s.required_ruby_version = '>= 1.9.3'
|
data/lib/BOAST.rb
CHANGED
data/lib/BOAST/Algorithm.rb
CHANGED
@@ -6,6 +6,8 @@ module BOAST
|
|
6
6
|
C = 2
|
7
7
|
CL = 3
|
8
8
|
CUDA = 4
|
9
|
+
X86 = 1
|
10
|
+
ARM = 2
|
9
11
|
@@output = STDOUT
|
10
12
|
@@lang = FORTRAN
|
11
13
|
@@replace_constants = true
|
@@ -16,6 +18,7 @@ module BOAST
|
|
16
18
|
@@indent_increment = 2
|
17
19
|
@@array_start = 1
|
18
20
|
@@chain_code = false
|
21
|
+
@@architecture = X86
|
19
22
|
|
20
23
|
@@env = Hash.new{|h, k| h[k] = []}
|
21
24
|
|
@@ -55,6 +58,14 @@ module BOAST
|
|
55
58
|
a.close
|
56
59
|
end
|
57
60
|
|
61
|
+
def BOAST::set_architecture(arch)
|
62
|
+
@@architecture = arch
|
63
|
+
end
|
64
|
+
|
65
|
+
def BOAST::get_architecture
|
66
|
+
return @@architecture
|
67
|
+
end
|
68
|
+
|
58
69
|
def BOAST::set_indent_level(level)
|
59
70
|
@@indent_level = level
|
60
71
|
end
|
@@ -199,7 +210,7 @@ module BOAST
|
|
199
210
|
end
|
200
211
|
|
201
212
|
def ===(x)
|
202
|
-
return Expression::new(
|
213
|
+
return Expression::new(BOAST::Affectation,self,x)
|
203
214
|
end
|
204
215
|
|
205
216
|
def ==(x)
|
@@ -207,7 +218,7 @@ module BOAST
|
|
207
218
|
end
|
208
219
|
|
209
220
|
def +(x)
|
210
|
-
return Expression::new(
|
221
|
+
return Expression::new(BOAST::Addition,self,x)
|
211
222
|
end
|
212
223
|
|
213
224
|
def >(x)
|
@@ -223,11 +234,11 @@ module BOAST
|
|
223
234
|
end
|
224
235
|
|
225
236
|
def *(x)
|
226
|
-
return Expression::new(
|
237
|
+
return Expression::new(BOAST::Multiplication,self,x)
|
227
238
|
end
|
228
239
|
|
229
240
|
def /(x)
|
230
|
-
return Expression::new(
|
241
|
+
return Expression::new(BOAST::Division,self,x)
|
231
242
|
end
|
232
243
|
|
233
244
|
def dereference
|
@@ -239,18 +250,19 @@ module BOAST
|
|
239
250
|
end
|
240
251
|
|
241
252
|
def -(x)
|
242
|
-
return Expression::new(
|
253
|
+
return Expression::new(BOAST::Substraction,self,x)
|
243
254
|
end
|
244
255
|
|
245
256
|
def !
|
246
|
-
return Expression::new(
|
257
|
+
return Expression::new(BOAST::Not,nil,self)
|
247
258
|
end
|
248
259
|
|
249
260
|
def -@
|
250
|
-
return Expression::new(
|
261
|
+
return Expression::new(BOAST::Minus,nil,self)
|
251
262
|
end
|
252
263
|
|
253
|
-
def Expression.to_str_base(op1, op2, oper)
|
264
|
+
def Expression.to_str_base(op1, op2, oper, return_type = nil)
|
265
|
+
return oper.to_s(op1,op2, return_type) if not oper.kind_of?(String)
|
254
266
|
s = ""
|
255
267
|
if op1 then
|
256
268
|
s += "(" if (oper == "*" or oper == "/")
|
@@ -275,7 +287,7 @@ module BOAST
|
|
275
287
|
op2 = @operand2.to_var if @operand2.respond_to?(:to_var)
|
276
288
|
if op1 and op2 then
|
277
289
|
r_t, oper = BOAST::transition(op1, op2, @operator)
|
278
|
-
res_exp = BOAST::Expression::to_str_base(op1, op2, oper)
|
290
|
+
res_exp = BOAST::Expression::to_str_base(op1, op2, oper, r_t)
|
279
291
|
return r_t.copy(res_exp, :const => nil, :constant => nil)
|
280
292
|
elsif op2
|
281
293
|
res_exp = BOAST::Expression::to_str_base(@operand1, op2, @operator)
|
@@ -294,16 +306,17 @@ module BOAST
|
|
294
306
|
op1 = @operand1.to_var if @operand1.respond_to?(:to_var)
|
295
307
|
op2 = nil
|
296
308
|
op2 = @operand2.to_var if @operand2.respond_to?(:to_var)
|
309
|
+
r_t = nil
|
297
310
|
if op1 and op2 then
|
298
311
|
r_t, oper = BOAST::transition(op1, op2, @operator)
|
299
312
|
else
|
300
313
|
oper = @operator
|
301
314
|
end
|
302
315
|
|
303
|
-
op1 = @operand1 if
|
304
|
-
op2 = @operand2 if
|
316
|
+
op1 = @operand1 if op1.nil?
|
317
|
+
op2 = @operand2 if op2.nil?
|
305
318
|
|
306
|
-
return BOAST::Expression::to_str_base(op1, op2, oper)
|
319
|
+
return BOAST::Expression::to_str_base(op1, op2, oper, r_t)
|
307
320
|
end
|
308
321
|
|
309
322
|
def print(final=true)
|
@@ -316,24 +329,6 @@ module BOAST
|
|
316
329
|
end
|
317
330
|
end
|
318
331
|
|
319
|
-
class Mult < Expression
|
320
|
-
def initialize(operand1, operand2)
|
321
|
-
super("*", operand1, operand2)
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
class Add < Expression
|
326
|
-
def initialize(operand1, operand2)
|
327
|
-
super("+", operand1, operand2)
|
328
|
-
end
|
329
|
-
end
|
330
|
-
|
331
|
-
class Affect < Expression
|
332
|
-
def initialize(operand1, operand2)
|
333
|
-
super("=", operand1, operand2)
|
334
|
-
end
|
335
|
-
end
|
336
|
-
|
337
332
|
class Index < Expression
|
338
333
|
attr_reader :source
|
339
334
|
attr_reader :indexes
|
@@ -454,94 +449,14 @@ module BOAST
|
|
454
449
|
end
|
455
450
|
end
|
456
451
|
|
457
|
-
class CStruct
|
458
|
-
attr_reader :name, :members, :members_array
|
459
|
-
def self.parens(*args,&block)
|
460
|
-
return Variable::new(args[0], self, *args[1..-1], &block)
|
461
|
-
end
|
462
|
-
|
463
|
-
def initialize(hash={})
|
464
|
-
@name = hash[:type_name]
|
465
|
-
@members = {}
|
466
|
-
@members_array = []
|
467
|
-
hash[:members].each { |m|
|
468
|
-
mc = m.copy
|
469
|
-
@members_array.push(mc)
|
470
|
-
@members[mc.name] = mc
|
471
|
-
}
|
472
|
-
end
|
473
|
-
|
474
|
-
def decl
|
475
|
-
return "struct #{@name}" if [C, CL, CUDA].include?( BOAST::get_lang )
|
476
|
-
return "TYPE(#{@name})" if BOAST::get_lang == FORTRAN
|
477
|
-
end
|
478
|
-
|
479
|
-
def finalize
|
480
|
-
s = ""
|
481
|
-
s += ";" if [C, CL, CUDA].include?( BOAST::get_lang )
|
482
|
-
s+="\n"
|
483
|
-
return s
|
484
|
-
end
|
485
|
-
|
486
|
-
def indent
|
487
|
-
return " "*BOAST::get_indent_level
|
488
|
-
end
|
489
|
-
|
490
|
-
def header
|
491
|
-
return header_c if [C, CL, CUDA].include?( BOAST::get_lang )
|
492
|
-
return header_fortran if BOAST::get_lang == FORTRAN
|
493
|
-
raise "Unsupported language!"
|
494
|
-
end
|
495
|
-
|
496
|
-
def header_c(final = true)
|
497
|
-
s = ""
|
498
|
-
s += self.indent if final
|
499
|
-
s += self.decl + " {\n"
|
500
|
-
@members_array.each { |value|
|
501
|
-
s+= self.indent if final
|
502
|
-
s+= " "*BOAST::get_indent_increment + value.decl(false)+";\n"
|
503
|
-
}
|
504
|
-
s += self.indent if final
|
505
|
-
s += "}"
|
506
|
-
s += self.finalize if final
|
507
|
-
BOAST::get_output.print s if final
|
508
|
-
return s
|
509
|
-
end
|
510
|
-
|
511
|
-
def header_fortran(final = true)
|
512
|
-
s = ""
|
513
|
-
s += self.indent if final
|
514
|
-
s += "TYPE :: #{@name}\n"
|
515
|
-
members_array.each { |value|
|
516
|
-
s+= self.indent if final
|
517
|
-
s+= " "*BOAST::get_indent_increment + value.decl(false)+"\n"
|
518
|
-
}
|
519
|
-
s += self.indent if final
|
520
|
-
s += "END TYPE #{@name}"
|
521
|
-
s += self.finalize if final
|
522
|
-
BOAST::get_output.print s if final
|
523
|
-
return s
|
524
|
-
end
|
525
|
-
|
526
|
-
end
|
527
|
-
class CustomType
|
528
|
-
attr_reader :size, :name, :vector_length
|
529
|
-
def initialize(hash={})
|
530
|
-
@name = hash[:type_name]
|
531
|
-
@size = hash[:size]
|
532
|
-
@vector_length = hash[:vector_length]
|
533
|
-
end
|
534
|
-
def decl
|
535
|
-
return "#{@name}" if [C, CL, CUDA].include?( BOAST::get_lang )
|
536
|
-
end
|
537
|
-
end
|
538
|
-
|
539
452
|
|
540
453
|
class Variable
|
541
454
|
alias_method :orig_method_missing, :method_missing
|
542
455
|
|
543
456
|
def method_missing(m, *a, &b)
|
544
457
|
return self.struct_reference(type.members[m.to_s]) if type.members[m.to_s]
|
458
|
+
# return self.get_element(m.to_s) if type.getters[m.to_s]
|
459
|
+
# return self.set_element(m.to_s) if type.setters[m.to_s]
|
545
460
|
return self.orig_method_missing(m, *a, &b)
|
546
461
|
end
|
547
462
|
|
@@ -558,6 +473,7 @@ module BOAST
|
|
558
473
|
attr_reader :local
|
559
474
|
attr_reader :texture
|
560
475
|
attr_reader :sampler
|
476
|
+
attr_reader :restrict
|
561
477
|
attr_accessor :replace_constant
|
562
478
|
attr_accessor :force_replace_constant
|
563
479
|
|
@@ -569,6 +485,7 @@ module BOAST
|
|
569
485
|
@local = hash[:local] ? hash[:local] : hash[:shared]
|
570
486
|
@texture = hash[:texture]
|
571
487
|
@allocate = hash[:allocate]
|
488
|
+
@restrict = hash[:restrict]
|
572
489
|
@force_replace_constant = false
|
573
490
|
if not hash[:replace_constant].nil? then
|
574
491
|
@replace_constant = hash[:replace_constant]
|
@@ -591,6 +508,14 @@ module BOAST
|
|
591
508
|
}
|
592
509
|
return Variable::new(name, @type.class, hash)
|
593
510
|
end
|
511
|
+
|
512
|
+
def Variable.from_type(name, type, options={})
|
513
|
+
hash = type.to_hash
|
514
|
+
options.each { |k,v|
|
515
|
+
hash[k] = v
|
516
|
+
}
|
517
|
+
return Variable::new(name, type.class, hash)
|
518
|
+
end
|
594
519
|
|
595
520
|
def to_s
|
596
521
|
self.to_str
|
@@ -609,8 +534,12 @@ module BOAST
|
|
609
534
|
return self
|
610
535
|
end
|
611
536
|
|
537
|
+
def set(x)
|
538
|
+
return Expression::new(BOAST::Set, self, x)
|
539
|
+
end
|
540
|
+
|
612
541
|
def ===(x)
|
613
|
-
return Expression::new(
|
542
|
+
return Expression::new(BOAST::Affectation,self,x)
|
614
543
|
end
|
615
544
|
|
616
545
|
def ==(x)
|
@@ -630,27 +559,27 @@ module BOAST
|
|
630
559
|
end
|
631
560
|
|
632
561
|
def +(x)
|
633
|
-
return Expression::new(
|
562
|
+
return Expression::new(BOAST::Addition,self,x)
|
634
563
|
end
|
635
564
|
|
636
565
|
def *(x)
|
637
|
-
return Expression::new(
|
566
|
+
return Expression::new(BOAST::Multiplication,self,x)
|
638
567
|
end
|
639
568
|
|
640
569
|
def /(x)
|
641
|
-
return Expression::new(
|
570
|
+
return Expression::new(BOAST::Division,self,x)
|
642
571
|
end
|
643
572
|
|
644
573
|
def -(x)
|
645
|
-
return Expression::new(
|
574
|
+
return Expression::new(BOAST::Substraction,self,x)
|
646
575
|
end
|
647
576
|
|
648
577
|
def !
|
649
|
-
return Expression::new(
|
578
|
+
return Expression::new(BOAST::Not,nil,self)
|
650
579
|
end
|
651
580
|
|
652
581
|
def -@
|
653
|
-
return Expression::new(
|
582
|
+
return Expression::new(BOAST::Minus,nil,self)
|
654
583
|
end
|
655
584
|
|
656
585
|
def address
|
@@ -658,7 +587,9 @@ module BOAST
|
|
658
587
|
end
|
659
588
|
|
660
589
|
def dereference
|
661
|
-
return
|
590
|
+
return self.copy("*(#{self.name})", :dimension => false, :dim => false) if [C, CL, CUDA].include?( BOAST::get_lang )
|
591
|
+
return self if BOAST::get_lang == FORTRAN
|
592
|
+
#return Expression::new("*",nil,self)
|
662
593
|
end
|
663
594
|
|
664
595
|
def struct_reference(x)
|
@@ -696,6 +627,13 @@ module BOAST
|
|
696
627
|
s += @type.decl
|
697
628
|
if(@dimension and not @constant and not @allocate and (not @local or (@local and device))) then
|
698
629
|
s += " *"
|
630
|
+
if @restrict then
|
631
|
+
if BOAST::get_lang == CL
|
632
|
+
s += " restrict"
|
633
|
+
else
|
634
|
+
s += " __restrict__"
|
635
|
+
end
|
636
|
+
end
|
699
637
|
end
|
700
638
|
s += " #{@name}"
|
701
639
|
if @dimension and @constant then
|
@@ -806,38 +744,6 @@ module BOAST
|
|
806
744
|
|
807
745
|
end
|
808
746
|
|
809
|
-
|
810
|
-
|
811
|
-
class Real
|
812
|
-
def self.parens(*args,&block)
|
813
|
-
return Variable::new(args[0], self, *args[1..-1], &block)
|
814
|
-
end
|
815
|
-
|
816
|
-
attr_reader :size
|
817
|
-
def initialize(hash={})
|
818
|
-
if hash[:size] then
|
819
|
-
@size = hash[:size]
|
820
|
-
else
|
821
|
-
@size = BOAST::get_default_real_size
|
822
|
-
end
|
823
|
-
if hash[:vector_length] and hash[:vector_length] > 1 then
|
824
|
-
@vector_length = hash[:vector_length]
|
825
|
-
else
|
826
|
-
@vector_length = 1
|
827
|
-
end
|
828
|
-
end
|
829
|
-
def decl
|
830
|
-
return "real(kind=#{@size})" if BOAST::get_lang == FORTRAN
|
831
|
-
if [C, CL, CUDA].include?( BOAST::get_lang ) and @vector_length == 1 then
|
832
|
-
return "float" if @size == 4
|
833
|
-
return "double" if @size == 8
|
834
|
-
elsif [CL, CUDA].include?(BOAST::get_lang) and @vector_length > 1 then
|
835
|
-
return "float#{@vector_length}" if @size == 4
|
836
|
-
return "double#{@vector_length}" if @size == 8
|
837
|
-
end
|
838
|
-
end
|
839
|
-
end
|
840
|
-
|
841
747
|
class CodeBlock
|
842
748
|
def initialize(&block)
|
843
749
|
@block = block
|
@@ -968,18 +874,25 @@ module BOAST
|
|
968
874
|
if BOAST::get_lang == CL then
|
969
875
|
if not @properties[:local] then
|
970
876
|
s += "__kernel "
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
877
|
+
wgs = @properties[:reqd_work_group_size]
|
878
|
+
if wgs then
|
879
|
+
s += "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
|
880
|
+
end
|
975
881
|
end
|
976
882
|
elsif BOAST::get_lang == CUDA then
|
977
883
|
if @properties[:local] then
|
978
|
-
s += "__device__ "
|
884
|
+
s += "static __device__ "
|
979
885
|
else
|
980
886
|
s += "__global__ "
|
887
|
+
wgs = @properties[:reqd_work_group_size]
|
888
|
+
if wgs then
|
889
|
+
s += "__launch_bounds__(#{wgs[0]}*#{wgs[1]}*#{wgs[2]}) "
|
890
|
+
end
|
981
891
|
end
|
982
892
|
end
|
893
|
+
if @properties[:qualifiers] then
|
894
|
+
s += "#{@properties[:qualifiers]} "
|
895
|
+
end
|
983
896
|
if @properties[:return] then
|
984
897
|
s += "#{@properties[:return].type.decl} "
|
985
898
|
else
|
@@ -1077,67 +990,6 @@ module BOAST
|
|
1077
990
|
end
|
1078
991
|
end
|
1079
992
|
|
1080
|
-
class Sizet
|
1081
|
-
def self.parens(*args,&block)
|
1082
|
-
return Variable::new(args[0], self, *args[1..-1], &block)
|
1083
|
-
end
|
1084
|
-
|
1085
|
-
attr_reader :signed
|
1086
|
-
def initialize(hash={})
|
1087
|
-
if hash[:signed] != nil then
|
1088
|
-
@signed = hash[:signed]
|
1089
|
-
end
|
1090
|
-
end
|
1091
|
-
def decl
|
1092
|
-
return "integer(kind=#{BOAST::get_default_int_size})" if BOAST::get_lang == FORTRAN
|
1093
|
-
if not @signed then
|
1094
|
-
return "size_t" if [C, CL, CUDA].include?( BOAST::get_lang )
|
1095
|
-
else
|
1096
|
-
return "ptrdiff_t" if [C, CL, CUDA].include?( BOAST::get_lang )
|
1097
|
-
end
|
1098
|
-
end
|
1099
|
-
end
|
1100
|
-
|
1101
|
-
class Int
|
1102
|
-
def self.parens(*args,&block)
|
1103
|
-
return Variable::new(args[0], self, *args[1..-1], &block)
|
1104
|
-
end
|
1105
|
-
|
1106
|
-
attr_reader :size
|
1107
|
-
attr_reader :signed
|
1108
|
-
def initialize(hash={})
|
1109
|
-
if hash[:size] then
|
1110
|
-
@size = hash[:size]
|
1111
|
-
else
|
1112
|
-
@size = BOAST::get_default_int_size
|
1113
|
-
end
|
1114
|
-
if hash[:signed] != nil then
|
1115
|
-
@signed = hash[:signed]
|
1116
|
-
else
|
1117
|
-
@signed = BOAST::get_default_int_signed
|
1118
|
-
end
|
1119
|
-
end
|
1120
|
-
def decl
|
1121
|
-
return "integer(kind=#{@size})" if BOAST::get_lang == FORTRAN
|
1122
|
-
return "int#{8*@size}_t" if BOAST::get_lang == C
|
1123
|
-
if BOAST::get_lang == CL then
|
1124
|
-
#char="cl_"
|
1125
|
-
char=""
|
1126
|
-
char += "u" if not @signed
|
1127
|
-
return char += "char" if @size==1
|
1128
|
-
return char += "short" if @size==2
|
1129
|
-
return char += "int" if @size==4
|
1130
|
-
return char += "long" if @size==8
|
1131
|
-
elsif BOAST::get_lang == CUDA then
|
1132
|
-
char = ""
|
1133
|
-
char += "unsigned " if not @signed
|
1134
|
-
return char += "char" if @size==1
|
1135
|
-
return char += "short" if @size==2
|
1136
|
-
return char += "int" if @size==4
|
1137
|
-
return char += "long long" if @size==8
|
1138
|
-
end
|
1139
|
-
end
|
1140
|
-
end
|
1141
993
|
|
1142
994
|
class ConstArray < Array
|
1143
995
|
def initialize(array,type = nil)
|
@@ -0,0 +1,318 @@
|
|
1
|
+
module BOAST
|
2
|
+
|
3
|
+
class Sizet
|
4
|
+
def self.parens(*args,&block)
|
5
|
+
return Variable::new(args[0], self, *args[1..-1], &block)
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :signed
|
9
|
+
attr_reader :size
|
10
|
+
attr_reader :vector_length
|
11
|
+
def initialize(hash={})
|
12
|
+
if hash[:signed] != nil then
|
13
|
+
@signed = hash[:signed]
|
14
|
+
end
|
15
|
+
@size = nil
|
16
|
+
@vector_length = 1
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_hash
|
20
|
+
return { :signed => @signed }
|
21
|
+
end
|
22
|
+
|
23
|
+
def copy(options={})
|
24
|
+
hash = self.to_hash
|
25
|
+
options.each { |k,v|
|
26
|
+
hash[k] = v
|
27
|
+
}
|
28
|
+
return Sizet::new(hash)
|
29
|
+
end
|
30
|
+
|
31
|
+
def decl
|
32
|
+
return "integer(kind=#{BOAST::get_default_int_size})" if BOAST::get_lang == FORTRAN
|
33
|
+
if not @signed then
|
34
|
+
return "size_t" if [C, CL, CUDA].include?( BOAST::get_lang )
|
35
|
+
else
|
36
|
+
return "ptrdiff_t" if [C, CL, CUDA].include?( BOAST::get_lang )
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class Real
|
42
|
+
def self.parens(*args,&block)
|
43
|
+
return Variable::new(args[0], self, *args[1..-1], &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_reader :size
|
47
|
+
attr_reader :signed
|
48
|
+
attr_reader :vector_length
|
49
|
+
attr_reader :total_size
|
50
|
+
attr_reader :getters
|
51
|
+
attr_reader :setters
|
52
|
+
|
53
|
+
def ==(t)
|
54
|
+
return true if t.class == self.class and t.size == self.size and t.vector_length == self.vector_length
|
55
|
+
return false
|
56
|
+
end
|
57
|
+
|
58
|
+
def initialize(hash={})
|
59
|
+
if hash[:size] then
|
60
|
+
@size = hash[:size]
|
61
|
+
else
|
62
|
+
@size = BOAST::get_default_real_size
|
63
|
+
end
|
64
|
+
# @getters = {}
|
65
|
+
# @setters = {}
|
66
|
+
if hash[:vector_length] and hash[:vector_length] > 1 then
|
67
|
+
@vector_length = hash[:vector_length]
|
68
|
+
# @vector_length.times{ |indx|
|
69
|
+
# @getters["s#{indx}"] = indx
|
70
|
+
# @setters["s#{indx}="] = indx
|
71
|
+
# }
|
72
|
+
else
|
73
|
+
@vector_length = 1
|
74
|
+
end
|
75
|
+
@total_size = @vector_length*@size
|
76
|
+
@signed = true
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_hash
|
80
|
+
return { :size => @size, :vector_length => @vector_length }
|
81
|
+
end
|
82
|
+
|
83
|
+
def copy(options={})
|
84
|
+
hash = to_hash
|
85
|
+
options.each { |k,v|
|
86
|
+
hash[k] = v
|
87
|
+
}
|
88
|
+
return Real::new(hash)
|
89
|
+
end
|
90
|
+
|
91
|
+
def decl
|
92
|
+
return "real(kind=#{@size})" if BOAST::get_lang == FORTRAN
|
93
|
+
if [C, CL, CUDA].include?( BOAST::get_lang ) and @vector_length == 1 then
|
94
|
+
return "float" if @size == 4
|
95
|
+
return "double" if @size == 8
|
96
|
+
elsif BOAST::get_lang == C and @vector_length > 1 then
|
97
|
+
if BOAST::get_architecture == BOAST::X86 then
|
98
|
+
return "__m#{@total_size*8}" if @size == 4
|
99
|
+
return "__m#{@total_size*8}d" if @size == 8
|
100
|
+
elsif BOAST::get_architecture == BOAST::ARM then
|
101
|
+
raise "Unsupported data type in NEON: double!" if @size == 8
|
102
|
+
raise "Unsupported vector length in NEON: #{@total_size} (#{@size} x 8 x #{@vector_length})!" if @total_size * 8 != 64 or @total_size * 8 != 128
|
103
|
+
return "float#{@size*8}x#{@vector_length}_t"
|
104
|
+
else
|
105
|
+
raise "Unsupported architecture!"
|
106
|
+
end
|
107
|
+
elsif [CL, CUDA].include?( BOAST::get_lang ) and @vector_length > 1 then
|
108
|
+
return "float#{@vector_length}" if @size == 4
|
109
|
+
return "double#{@vector_length}" if @size == 8
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class Int
|
115
|
+
def self.parens(*args,&block)
|
116
|
+
return Variable::new(args[0], self, *args[1..-1], &block)
|
117
|
+
end
|
118
|
+
|
119
|
+
attr_reader :size
|
120
|
+
attr_reader :signed
|
121
|
+
attr_reader :vector_length
|
122
|
+
attr_reader :total_size
|
123
|
+
|
124
|
+
def ==(t)
|
125
|
+
return true if t.class == self.class and t.signed == self.signed and t.size == self.size and t.vector_length == self.vector_length
|
126
|
+
return false
|
127
|
+
end
|
128
|
+
|
129
|
+
def initialize(hash={})
|
130
|
+
if hash[:size] then
|
131
|
+
@size = hash[:size]
|
132
|
+
else
|
133
|
+
@size = BOAST::get_default_int_size
|
134
|
+
end
|
135
|
+
if hash[:signed] != nil then
|
136
|
+
@signed = hash[:signed]
|
137
|
+
else
|
138
|
+
@signed = BOAST::get_default_int_signed
|
139
|
+
end
|
140
|
+
# @getters = {}
|
141
|
+
# @setters = {}
|
142
|
+
if hash[:vector_length] and hash[:vector_length] > 1 then
|
143
|
+
@vector_length = hash[:vector_length]
|
144
|
+
# @vector_length.times{ |indx|
|
145
|
+
# @getters["s#{indx}"] = indx
|
146
|
+
# @setters["s#{indx}="] = indx
|
147
|
+
# }
|
148
|
+
else
|
149
|
+
@vector_length = 1
|
150
|
+
end
|
151
|
+
@total_size = @vector_length*@size
|
152
|
+
end
|
153
|
+
|
154
|
+
def to_hash
|
155
|
+
return { :size => @size, :vector_length => @vector_length, :signed => @signed }
|
156
|
+
end
|
157
|
+
|
158
|
+
def copy(options={})
|
159
|
+
hash = self.to_hash
|
160
|
+
options.each { |k,v|
|
161
|
+
hash[k] = v
|
162
|
+
}
|
163
|
+
return Int::new(hash)
|
164
|
+
end
|
165
|
+
|
166
|
+
def decl
|
167
|
+
return "integer(kind=#{@size})" if BOAST::get_lang == FORTRAN
|
168
|
+
if BOAST::get_lang == C then
|
169
|
+
if @vector_length == 1 then
|
170
|
+
s = ""
|
171
|
+
s += "u" if not @signed
|
172
|
+
return s+"int#{8*@size}_t"
|
173
|
+
elsif @vector_length > 1 then
|
174
|
+
if BOAST::get_architecture == BOAST::X86 then
|
175
|
+
return "__m#{@total_size*8}#{@total_size*8>64 ? "i" : ""}"
|
176
|
+
elsif BOAST::get_architecture == BOAST::ARM then
|
177
|
+
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
|
178
|
+
return "#{ @signed ? "" : "u"}int#{@size*8}x#{@vector_length}_t"
|
179
|
+
else
|
180
|
+
raise "Unsupported architecture!"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
elsif BOAST::get_lang == CL then
|
184
|
+
#char="cl_"
|
185
|
+
char=""
|
186
|
+
char += "u" if not @signed
|
187
|
+
case @size
|
188
|
+
when 1
|
189
|
+
char += "char"
|
190
|
+
when 2
|
191
|
+
char += "short"
|
192
|
+
when 4
|
193
|
+
char += "int"
|
194
|
+
when 8
|
195
|
+
char += "long"
|
196
|
+
else
|
197
|
+
raise "Unsupported integer size!"
|
198
|
+
end
|
199
|
+
if @vector_length > 1 then
|
200
|
+
char += "#{@vector_length}"
|
201
|
+
end
|
202
|
+
return char
|
203
|
+
elsif BOAST::get_lang == CUDA then
|
204
|
+
if @vector_length > 1 then
|
205
|
+
char=""
|
206
|
+
char += "u" if not @signed
|
207
|
+
case @size
|
208
|
+
when 1
|
209
|
+
char += "char"
|
210
|
+
when 2
|
211
|
+
char += "short"
|
212
|
+
when 4
|
213
|
+
char += "int"
|
214
|
+
when 8
|
215
|
+
char += "longlong"
|
216
|
+
else
|
217
|
+
raise "Unsupported integer size!"
|
218
|
+
end
|
219
|
+
return char + "#{@vector_length}"
|
220
|
+
else
|
221
|
+
char = ""
|
222
|
+
char += "unsigned " if not @signed
|
223
|
+
return char += "char" if @size==1
|
224
|
+
return char += "short" if @size==2
|
225
|
+
return char += "int" if @size==4
|
226
|
+
return char += "long long" if @size==8
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
class CStruct
|
233
|
+
attr_reader :name, :members, :members_array
|
234
|
+
def self.parens(*args,&block)
|
235
|
+
return Variable::new(args[0], self, *args[1..-1], &block)
|
236
|
+
end
|
237
|
+
|
238
|
+
def initialize(hash={})
|
239
|
+
@name = hash[:type_name]
|
240
|
+
@members = {}
|
241
|
+
@members_array = []
|
242
|
+
hash[:members].each { |m|
|
243
|
+
mc = m.copy
|
244
|
+
@members_array.push(mc)
|
245
|
+
@members[mc.name] = mc
|
246
|
+
}
|
247
|
+
end
|
248
|
+
|
249
|
+
def decl
|
250
|
+
return "struct #{@name}" if [C, CL, CUDA].include?( BOAST::get_lang )
|
251
|
+
return "TYPE(#{@name})" if BOAST::get_lang == FORTRAN
|
252
|
+
end
|
253
|
+
|
254
|
+
def finalize
|
255
|
+
s = ""
|
256
|
+
s += ";" if [C, CL, CUDA].include?( BOAST::get_lang )
|
257
|
+
s+="\n"
|
258
|
+
return s
|
259
|
+
end
|
260
|
+
|
261
|
+
def indent
|
262
|
+
return " "*BOAST::get_indent_level
|
263
|
+
end
|
264
|
+
|
265
|
+
def header
|
266
|
+
return header_c if [C, CL, CUDA].include?( BOAST::get_lang )
|
267
|
+
return header_fortran if BOAST::get_lang == FORTRAN
|
268
|
+
raise "Unsupported language!"
|
269
|
+
end
|
270
|
+
|
271
|
+
def header_c(final = true)
|
272
|
+
s = ""
|
273
|
+
s += self.indent if final
|
274
|
+
s += self.decl + " {\n"
|
275
|
+
@members_array.each { |value|
|
276
|
+
s+= self.indent if final
|
277
|
+
s+= " "*BOAST::get_indent_increment + value.decl(false)+";\n"
|
278
|
+
}
|
279
|
+
s += self.indent if final
|
280
|
+
s += "}"
|
281
|
+
s += self.finalize if final
|
282
|
+
BOAST::get_output.print s if final
|
283
|
+
return s
|
284
|
+
end
|
285
|
+
|
286
|
+
def header_fortran(final = true)
|
287
|
+
s = ""
|
288
|
+
s += self.indent if final
|
289
|
+
s += "TYPE :: #{@name}\n"
|
290
|
+
members_array.each { |value|
|
291
|
+
s+= self.indent if final
|
292
|
+
s+= " "*BOAST::get_indent_increment + value.decl(false)+"\n"
|
293
|
+
}
|
294
|
+
s += self.indent if final
|
295
|
+
s += "END TYPE #{@name}"
|
296
|
+
s += self.finalize if final
|
297
|
+
BOAST::get_output.print s if final
|
298
|
+
return s
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|
302
|
+
|
303
|
+
class CustomType
|
304
|
+
attr_reader :size, :name, :vector_length
|
305
|
+
def initialize(hash={})
|
306
|
+
@name = hash[:type_name]
|
307
|
+
@size = hash[:size]
|
308
|
+
@size = 0 if @size.nil?
|
309
|
+
@vector_length = hash[:vector_length]
|
310
|
+
@vector_length = 1 if @vector_length.nil?
|
311
|
+
@total_size = @vector_length*@size
|
312
|
+
end
|
313
|
+
def decl
|
314
|
+
return "#{@name}" if [C, CL, CUDA].include?( BOAST::get_lang )
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
end
|
@@ -0,0 +1,391 @@
|
|
1
|
+
module BOAST
|
2
|
+
|
3
|
+
class Operator
|
4
|
+
def Operator.get_vector_name(type)
|
5
|
+
case BOAST::get_architecture
|
6
|
+
when X86
|
7
|
+
case type
|
8
|
+
when Int
|
9
|
+
size = "#{type.size*8}"
|
10
|
+
name = ""
|
11
|
+
if type.total_size*8 > 64
|
12
|
+
name += "e"
|
13
|
+
end
|
14
|
+
if type.vector_length > 1 then
|
15
|
+
name += "p"
|
16
|
+
else
|
17
|
+
name = "s"
|
18
|
+
end
|
19
|
+
if type.signed then
|
20
|
+
name += "i"
|
21
|
+
else
|
22
|
+
name += "u"
|
23
|
+
end
|
24
|
+
return name += size
|
25
|
+
when Real
|
26
|
+
case type.size
|
27
|
+
when 4
|
28
|
+
return "ps" if type.vector_length > 1
|
29
|
+
return "ss"
|
30
|
+
when 8
|
31
|
+
return "pd" if type.vector_length > 1
|
32
|
+
return "sd"
|
33
|
+
end
|
34
|
+
else
|
35
|
+
raise "Undefined vector type!"
|
36
|
+
end
|
37
|
+
when ARM
|
38
|
+
case type
|
39
|
+
when Int
|
40
|
+
name = "#{ type.signed ? "s" : "u" }"
|
41
|
+
name += "#{ type.size * 8}"
|
42
|
+
return name
|
43
|
+
when Real
|
44
|
+
return "f#{type.size*8}"
|
45
|
+
else
|
46
|
+
raise "Undefined vector type!"
|
47
|
+
end
|
48
|
+
else
|
49
|
+
raise "Unsupported architecture!"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def Operator.convert(arg, type)
|
54
|
+
case BOAST::get_architecture
|
55
|
+
when X86
|
56
|
+
s1 = arg.type.total_size*8
|
57
|
+
s2 = type.total_size*8
|
58
|
+
n1 = get_vector_name(arg.type)
|
59
|
+
n2 = get_vector_name(type)
|
60
|
+
if s1 <= 128 and s2 <= 128 then
|
61
|
+
return "_mm_cvt#{n1}_#{n2}( #{arg} )"
|
62
|
+
elsif [s1, s2].max <= 256 then
|
63
|
+
return "_mm256_cvt#{n1}_#{n2}( #{arg} )"
|
64
|
+
elsif [s1, s2].max <= 512 then
|
65
|
+
return "_mm512_cvt#{n1}_#{n2}( #{arg} )"
|
66
|
+
end
|
67
|
+
when ARM
|
68
|
+
if type.class != arg.type.class then
|
69
|
+
if type.size == arg.type.size then
|
70
|
+
s = type.total_size*8
|
71
|
+
n1 = get_vector_name(arg.type)
|
72
|
+
n2 = get_vector_name(type)
|
73
|
+
return "vcvt#{ s == 128 ? "q" : "" }_#{n2}_#{n1}( #{arg} )"
|
74
|
+
elsif type.class == Real then
|
75
|
+
intr = convert(arg, arg.type.copy(:size=>type.size))
|
76
|
+
return convert(arg.copy(intr, :size => type.size ), type)
|
77
|
+
else
|
78
|
+
n1 = get_vector_name(arg.type)
|
79
|
+
s = type.total_size*8
|
80
|
+
t2 = type.copy(:size => arg.type.size)
|
81
|
+
n2 = get_vector_name( t2 )
|
82
|
+
intr = "vcvt#{ s == 128 ? "q" : "" }_#{n2}_#{n1}( #{arg} )"
|
83
|
+
return convert(Variable::from_type(intr, t2), type)
|
84
|
+
end
|
85
|
+
elsif type.class != Real then
|
86
|
+
n = get_vector_name(arg.type)
|
87
|
+
if type.size == arg.type.size then
|
88
|
+
if type.signed == arg.type.signed then
|
89
|
+
return "#{arg}"
|
90
|
+
else
|
91
|
+
n2 = get_vector_name(type)
|
92
|
+
return "vreinterpret_#{n2}_#{n}( #{arg} )"
|
93
|
+
end
|
94
|
+
elsif type.size < arg.type.size then
|
95
|
+
intr = "vmovn_#{n}( #{arg} )"
|
96
|
+
s = arg.type.size/2
|
97
|
+
else
|
98
|
+
intr = "vmovl_#{n}( #{arg} )"
|
99
|
+
s = arg.type.size*2
|
100
|
+
end
|
101
|
+
return convert(arg.copy(intr, :size => s), type)
|
102
|
+
end
|
103
|
+
else
|
104
|
+
raise "Unsupported architecture!"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class BasicBinaryOperator < Operator
|
110
|
+
|
111
|
+
def BasicBinaryOperator.to_s(arg1, arg2, return_type)
|
112
|
+
#puts "#{arg1.class} * #{arg2.class} : #{arg1} * #{arg2}"
|
113
|
+
if BOAST::get_lang == C and (arg1.class == Variable and arg2.class == Variable) and (arg1.type.vector_length > 1 or arg2.type.vector_length > 1) then
|
114
|
+
raise "Vectors have different length: #{arg1} #{arg1.type.vector_length}, #{arg2} #{arg2.type.vector_length}" if arg1.type.vector_length != arg2.type.vector_length
|
115
|
+
#puts "#{arg1.type.signed} #{arg2.type.signed} #{return_type.type.signed}"
|
116
|
+
return_name = get_vector_name(return_type.type)
|
117
|
+
size = return_type.type.total_size * 8
|
118
|
+
case BOAST::get_architecture
|
119
|
+
when X86
|
120
|
+
if arg1.type != return_type.type
|
121
|
+
a1 = convert(arg1, return_type.type)
|
122
|
+
else
|
123
|
+
a1 = "#{arg1}"
|
124
|
+
end
|
125
|
+
if arg2.type != return_type.type
|
126
|
+
a2 = convert(arg2, return_type.type)
|
127
|
+
else
|
128
|
+
a2 = "#{arg2}"
|
129
|
+
end
|
130
|
+
intr_name = "_mm"
|
131
|
+
if size > 128 then
|
132
|
+
intr_name += "#{size}"
|
133
|
+
end
|
134
|
+
intr_name += "_#{intr_name_X86}_#{return_name}"
|
135
|
+
return "#{intr_name}( #{a1}, #{a2} )"
|
136
|
+
when ARM
|
137
|
+
if arg1.type.class != return_type.type.class then
|
138
|
+
a1 = convert(arg1, return_type.type)
|
139
|
+
else
|
140
|
+
a1 = "#{arg1}"
|
141
|
+
end
|
142
|
+
if arg2.type.class != return_type.type.class then
|
143
|
+
a2 = convert(arg2, return_type.type)
|
144
|
+
else
|
145
|
+
a2 = "#{arg2}"
|
146
|
+
end
|
147
|
+
intr_name = "#{intr_name_ARM}"
|
148
|
+
intr_name += "q" if size == 128
|
149
|
+
intr_name += "_" + return_name + "( #{a1}, #{a2} )"
|
150
|
+
return intr_name
|
151
|
+
else
|
152
|
+
raise "Unsupported architecture!"
|
153
|
+
end
|
154
|
+
else
|
155
|
+
return basic_usage( arg1, arg2 )
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
class Set < Operator
|
161
|
+
|
162
|
+
def Set.to_s(arg1, arg2, return_type)
|
163
|
+
if BOAST::get_lang == C then
|
164
|
+
if arg1.class == Variable and arg1.type.vector_length > 1 then
|
165
|
+
if arg1.type == arg2.type then
|
166
|
+
return basic_usage(arg1, arg2)
|
167
|
+
elsif arg1.type.vector_length == arg2.type.vector_length then
|
168
|
+
return "(#{arg1} = #{convert(arg2, arg1.type)})"
|
169
|
+
elsif arg2.type.vector_length == 1 then
|
170
|
+
size = arg1.type.total_size*8
|
171
|
+
case BOAST::get_architecture
|
172
|
+
when ARM
|
173
|
+
intr_name = "vmov"
|
174
|
+
intr_name += "q" if size == 128
|
175
|
+
intr_name += "_n_#{get_vector_name(arg1.type)}"
|
176
|
+
when X86
|
177
|
+
return "(#{arg1} = _m_from_int64( #{a2} ))" if arg1.type.class == Int and arg1.type.size == 8 and size == 64
|
178
|
+
intr_name = "_mm"
|
179
|
+
if size > 128 then
|
180
|
+
intr_name += "#{size}"
|
181
|
+
end
|
182
|
+
intr_name += "_set1_#{get_vector_name(arg1.type).gsub("u","")}"
|
183
|
+
intr_name += "x" if arg1.type.class == Int and arg1.type.size == 8
|
184
|
+
else
|
185
|
+
raise "Unsupported architecture!"
|
186
|
+
end
|
187
|
+
return "(#{arg1} = #{intr_name}( #{arg2} ))"
|
188
|
+
else
|
189
|
+
raise "Unknown convertion between vector of different length!"
|
190
|
+
end
|
191
|
+
else
|
192
|
+
return basic_usage(arg1, arg2)
|
193
|
+
end
|
194
|
+
else
|
195
|
+
return basic_usage(arg1, arg2)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def Set.basic_usage(arg1, arg2)
|
200
|
+
return "(#{arg1} = #{arg2})"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
class Affectation < Operator
|
205
|
+
def Affectation.to_s(arg1, arg2, return_type)
|
206
|
+
if BOAST::get_lang == C then
|
207
|
+
if arg1.class == Variable and arg1.type.vector_length > 1 then
|
208
|
+
#puts "#{arg1.type.vector_length} #{arg2.type.vector_length}"
|
209
|
+
if arg1.type == arg2.type then
|
210
|
+
return basic_usage(arg1, arg2)
|
211
|
+
elsif arg1.type.vector_length == arg2.type.vector_length then
|
212
|
+
return "#{arg1} = #{convert(arg2, arg1.type)}"
|
213
|
+
elsif arg2.type.vector_length == 1 then
|
214
|
+
size = arg1.type.total_size*8
|
215
|
+
a2 = "#{arg2}"
|
216
|
+
if a2[0] != "*" then
|
217
|
+
a2 = "&" + a2
|
218
|
+
else
|
219
|
+
a2 = a2[1..-1]
|
220
|
+
end
|
221
|
+
case BOAST::get_architecture
|
222
|
+
when ARM
|
223
|
+
intr_name = "vldl"
|
224
|
+
intr_name += "q" if size == 128
|
225
|
+
intr_name += "_#{get_vector_name(arg1.type)}"
|
226
|
+
when X86
|
227
|
+
if arg1.type.class == Int and size == 64 then
|
228
|
+
return "#{arg1} = _m_from_int64( *((int64_t * ) #{a2} ) )"
|
229
|
+
end
|
230
|
+
intr_name = "_mm"
|
231
|
+
if size > 128 then
|
232
|
+
intr_name += "#{size}"
|
233
|
+
end
|
234
|
+
intr_name += "_load_"
|
235
|
+
if arg1.type.class == Int then
|
236
|
+
intr_name += "si#{size}"
|
237
|
+
else
|
238
|
+
intr_name += "#{get_vector_name(arg1.type)}"
|
239
|
+
end
|
240
|
+
else
|
241
|
+
raise "Unsupported architecture!"
|
242
|
+
end
|
243
|
+
return "#{arg1} = #{intr_name}( (#{arg1.type.decl} * ) #{a2} )"
|
244
|
+
else
|
245
|
+
raise "Unknown convertion between vectors of different length!"
|
246
|
+
end
|
247
|
+
elsif arg2.class == Variable and arg2.type.vector_length > 1 then
|
248
|
+
size = arg2.type.total_size*8
|
249
|
+
a1 = "#{arg1}"
|
250
|
+
if a1[0] != "*" then
|
251
|
+
a1 = "&" + a1
|
252
|
+
else
|
253
|
+
a1 = a1[1..-1]
|
254
|
+
end
|
255
|
+
case BOAST::get_architecture
|
256
|
+
when ARM
|
257
|
+
intr_name = "vstl"
|
258
|
+
intr_name += "q" if size == 128
|
259
|
+
intr_name += "_#{get_vector_name(arg2.type)}"
|
260
|
+
when X86
|
261
|
+
if arg2.type.class == Int and size == 64 then
|
262
|
+
return " *((int64_t * ) #{a1}) = _m_to_int64( #{arg2} )"
|
263
|
+
end
|
264
|
+
intr_name = "_mm"
|
265
|
+
if size > 128 then
|
266
|
+
intr_name += "#{size}"
|
267
|
+
end
|
268
|
+
intr_name += "_store_"
|
269
|
+
if arg2.type.class == Int then
|
270
|
+
intr_name += "si#{size}"
|
271
|
+
else
|
272
|
+
intr_name += "#{get_vector_name(arg2.type)}"
|
273
|
+
end
|
274
|
+
else
|
275
|
+
raise "Unsupported architecture!"
|
276
|
+
end
|
277
|
+
return "#{intr_name}((#{arg2.type.decl} * ) #{a1}, #{arg2} )"
|
278
|
+
else
|
279
|
+
return basic_usage(arg1, arg2)
|
280
|
+
end
|
281
|
+
else
|
282
|
+
return basic_usage(arg1, arg2)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
def Affectation.basic_usage(arg1, arg2)
|
287
|
+
return "#{arg1} = #{arg2}"
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
class Multiplication < BasicBinaryOperator
|
292
|
+
class << self
|
293
|
+
|
294
|
+
def symbol
|
295
|
+
return "*"
|
296
|
+
end
|
297
|
+
|
298
|
+
def intr_name_X86
|
299
|
+
return "mul"
|
300
|
+
end
|
301
|
+
|
302
|
+
def intr_name_ARM
|
303
|
+
return "vmul"
|
304
|
+
end
|
305
|
+
|
306
|
+
def basic_usage(arg1, arg2)
|
307
|
+
return "(#{arg1}) * (#{arg2})"
|
308
|
+
end
|
309
|
+
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
class Addition < BasicBinaryOperator
|
314
|
+
class << self
|
315
|
+
|
316
|
+
def symbol
|
317
|
+
return "+"
|
318
|
+
end
|
319
|
+
|
320
|
+
def intr_name_X86
|
321
|
+
return "add"
|
322
|
+
end
|
323
|
+
|
324
|
+
def intr_name_ARM
|
325
|
+
return "vadd"
|
326
|
+
end
|
327
|
+
|
328
|
+
def basic_usage(arg1, arg2)
|
329
|
+
return "#{arg1} + #{arg2}"
|
330
|
+
end
|
331
|
+
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
class Substraction < BasicBinaryOperator
|
336
|
+
class << self
|
337
|
+
|
338
|
+
def symbol
|
339
|
+
return "-"
|
340
|
+
end
|
341
|
+
|
342
|
+
def intr_name_X86
|
343
|
+
return "sub"
|
344
|
+
end
|
345
|
+
|
346
|
+
def intr_name_ARM
|
347
|
+
return "vsub"
|
348
|
+
end
|
349
|
+
|
350
|
+
def basic_usage(arg1, arg2)
|
351
|
+
return "#{arg1} - (#{arg2})"
|
352
|
+
end
|
353
|
+
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
class Division < BasicBinaryOperator
|
358
|
+
class << self
|
359
|
+
|
360
|
+
def symbol
|
361
|
+
return "/"
|
362
|
+
end
|
363
|
+
|
364
|
+
def intr_name_X86
|
365
|
+
return "div"
|
366
|
+
end
|
367
|
+
|
368
|
+
def intr_name_ARM
|
369
|
+
raise "Neon doesn't support division!"
|
370
|
+
end
|
371
|
+
|
372
|
+
def basic_usage(arg1, arg2)
|
373
|
+
return "(#{arg1}) / (#{arg2})"
|
374
|
+
end
|
375
|
+
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
class Minus < Operator
|
380
|
+
def Minus.to_s(arg1, arg2, return_type)
|
381
|
+
return " -(#{arg2})"
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
class Not < Operator
|
386
|
+
def Not.to_s(arg1, arg2, return_type)
|
387
|
+
return " ! #{arg2}"
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
end
|
data/lib/BOAST/Transitions.rb
CHANGED
@@ -20,15 +20,15 @@ module BOAST
|
|
20
20
|
def transition(var1, var2, operator)
|
21
21
|
signed = false
|
22
22
|
size = nil
|
23
|
+
vector_length = 1
|
23
24
|
return_type, operator = get_transition(var1.type.class, var2.type.class, operator)
|
24
25
|
#STDERR.puts "#{return_type} : #{var1.type.class} #{operator} #{var2.type.class}"
|
25
26
|
if var1.type.class == return_type and var2.type.class == return_type then
|
26
|
-
signed = signed or var1.type.signed
|
27
|
-
signed = signed or var2.type.signed
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
[BOAST::Variable::new("dummy", return_type, :size => size, :signed => signed), operator]
|
27
|
+
signed = (signed or var1.type.signed)
|
28
|
+
signed = (signed or var2.type.signed)
|
29
|
+
size = [var1.type.size, var2.type.size].max
|
30
|
+
vector_length = [var1.type.vector_length, var2.type.vector_length].max
|
31
|
+
[BOAST::Variable::new("dummy", return_type, :size => size, :signed => signed, :vector_length => vector_length), operator]
|
32
32
|
elsif var1.type.class == return_type then
|
33
33
|
return [var1, operator]
|
34
34
|
elsif var2.type.class == return_type then
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: BOAST
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.7'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-05-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: narray
|
@@ -74,6 +74,8 @@ files:
|
|
74
74
|
- lib/BOAST/BOAST_OpenCL.rb
|
75
75
|
- lib/BOAST/Transitions.rb
|
76
76
|
- lib/BOAST/Parens.rb
|
77
|
+
- lib/BOAST/Operators.rb
|
78
|
+
- lib/BOAST/DataTypes.rb
|
77
79
|
homepage: https://forge.imag.fr/projects/boast/
|
78
80
|
licenses:
|
79
81
|
- BSD
|