BOAST 0.995 → 0.996

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.
@@ -245,1526 +245,6 @@ module BOAST
245
245
  return @@array_start
246
246
  end
247
247
 
248
- class Pragma
249
- def self.parens(*args,&block)
250
- return self::new(*args,&block)
251
- end
252
-
253
- attr_reader :name
254
- attr_reader :options
255
-
256
- def initialize(name, options)
257
- @name = name
258
- @options = options
259
- end
260
-
261
- def to_s
262
- self.to_str
263
- end
264
-
265
- def to_str
266
- s = ""
267
- if BOAST::get_lang == FORTRAN then
268
- s += "$!"
269
- else
270
- s += "#pragma"
271
- end
272
- @options.each{ |opt|
273
- s += " #{opt}"
274
- }
275
- return s
276
- end
277
-
278
- def print(final = true)
279
- s=""
280
- s += self.to_str
281
- BOAST::get_output.puts s if final
282
- return s
283
- end
284
- end
285
-
286
- def BOAST::Return(value)
287
- return Expression("return",nil, value)
288
- end
289
-
290
- class Expression
291
- def self.parens(*args,&block)
292
- return self::new(*args,&block)
293
- end
294
-
295
- attr_reader :operator
296
- attr_reader :operand1
297
- attr_reader :operand2
298
- def initialize(operator, operand1, operand2)
299
- @operator = operator
300
- @operand1 = operand1
301
- @operand2 = operand2
302
- end
303
- def to_s
304
- self.to_str
305
- end
306
-
307
- def ===(x)
308
- return Expression::new(BOAST::Affectation,self,x)
309
- end
310
-
311
- def ==(x)
312
- return Expression::new("==",self,x)
313
- end
314
-
315
- def !=(x)
316
- return Expression::new(BOAST::Different,self,x)
317
- end
318
-
319
- def +(x)
320
- return Expression::new(BOAST::Addition,self,x)
321
- end
322
-
323
- def >(x)
324
- return Expression::new(">",self,x)
325
- end
326
-
327
- def <(x)
328
- return Expression::new("<",self,x)
329
- end
330
-
331
- def >=(x)
332
- return Expression::new(">=",self,x)
333
- end
334
-
335
- def *(x)
336
- return Expression::new(BOAST::Multiplication,self,x)
337
- end
338
-
339
- def /(x)
340
- return Expression::new(BOAST::Division,self,x)
341
- end
342
-
343
- def address
344
- return Expression::new("&",nil,self)
345
- end
346
-
347
- def dereference
348
- return Expression::new("*",nil,self)
349
- end
350
-
351
- def struct_reference(x)
352
- return Expression::new(".",self,x)
353
- end
354
-
355
- def -(x)
356
- return Expression::new(BOAST::Substraction,self,x)
357
- end
358
-
359
- def !
360
- return Expression::new(BOAST::Not,nil,self)
361
- end
362
-
363
- def -@
364
- return Expression::new(BOAST::Minus,nil,self)
365
- end
366
-
367
- def Expression.to_str_base(op1, op2, oper, return_type = nil)
368
- return oper.to_s(op1,op2, return_type) if not oper.kind_of?(String)
369
- s = ""
370
- if op1 then
371
- s += "(" if (oper == "*" or oper == "/")
372
- s += op1.to_s
373
- s += ")" if (oper == "*" or oper == "/")
374
- end
375
- s += " " unless oper == "++" or oper == "."
376
- s += oper unless ( oper == "&" and BOAST::get_lang == BOAST::FORTRAN )
377
- s += " " unless oper == "." or oper == "&" or ( oper == "*" and op1.nil? )
378
- if op2 then
379
- s += "(" if (oper == "*" or oper == "/" or oper == "-")
380
- s += op2.to_s
381
- s += ")" if (oper == "*" or oper == "/" or oper == "-")
382
- end
383
- return s
384
- end
385
-
386
- def to_var
387
- op1 = nil
388
- op1 = @operand1.to_var if @operand1.respond_to?(:to_var)
389
- op2 = nil
390
- op2 = @operand2.to_var if @operand2.respond_to?(:to_var)
391
- if op1 and op2 then
392
- r_t, oper = BOAST::transition(op1, op2, @operator)
393
- res_exp = BOAST::Expression::to_str_base(op1, op2, oper, r_t)
394
- return r_t.copy(res_exp, :const => nil, :constant => nil)
395
- elsif op2
396
- res_exp = BOAST::Expression::to_str_base(@operand1, op2, @operator)
397
- return op2.copy(res_exp, :const => nil, :constant => nil)
398
- elsif op1
399
- res_exp = BOAST::Expression::to_str_base(op1, @operand2, @operator)
400
- return op1.copy(res_exp, :const => nil, :constant => nil)
401
- else
402
- STDERR.puts "#{@operand1} #{@operand2}"
403
- raise "Expression on no operand!"
404
- end
405
- end
406
-
407
- def to_str
408
- op1 = nil
409
- op1 = @operand1.to_var if @operand1.respond_to?(:to_var)
410
- op2 = nil
411
- op2 = @operand2.to_var if @operand2.respond_to?(:to_var)
412
- r_t = nil
413
- if op1 and op2 then
414
- r_t, oper = BOAST::transition(op1, op2, @operator)
415
- else
416
- oper = @operator
417
- end
418
-
419
- op1 = @operand1 if op1.nil?
420
- op2 = @operand2 if op2.nil?
421
-
422
- return BOAST::Expression::to_str_base(op1, op2, oper, r_t)
423
- end
424
-
425
- def print(final=true)
426
- s=""
427
- s += " "*BOAST::get_indent_level if final
428
- s += self.to_str
429
- s += ";" if final and [C, CL, CUDA].include?( BOAST::get_lang )
430
- BOAST::get_output.puts s if final
431
- return s
432
- end
433
- end
434
-
435
- class Index < Expression
436
- attr_reader :source
437
- attr_reader :indexes
438
- def initialize(source, indexes)
439
- @source = source
440
- @indexes = indexes
441
- end
442
-
443
- def to_var
444
- return @source.copy("#{self}", :const => nil, :constant => nil, :dim => nil, :dimension => nil)
445
- end
446
-
447
- def to_s
448
- self.to_str
449
- end
450
- def to_str
451
- return self.to_str_fortran if BOAST::get_lang == FORTRAN
452
- return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
453
- end
454
- def to_str_fortran
455
- s = ""
456
- s += "#{@source}(#{@indexes.join(", ")})"
457
- return s
458
- end
459
- def to_str_texture
460
- raise "Unsupported language #{BOAST::get_lang} for texture!" if not [CL, CUDA].include?( BOAST::get_lang )
461
- raise "Write is unsupported for textures!" if not ( @source.constant or @source.direction == :in )
462
- dim_number = 1
463
- if @source.dimension then
464
- dim_number == @source.dimension.size
465
- end
466
- raise "Unsupported number of dimension: #{dim_number}!" if dim_number > 3
467
- s = ""
468
- if BOAST::get_lang == CL then
469
- s += "as_#{@source.type.decl}("
470
- s += "read_imageui(#{@source}, #{@source.sampler}, "
471
- if dim_number == 1 then
472
- s += "int2(#{@indexes[0]},0)"
473
- else
474
- if dim_number == 2 then
475
- s += "int2("
476
- else
477
- s += "int3("
478
- end
479
- s += "#{@indexes.join(", ")})"
480
- end
481
- s += ")"
482
- if @source.type.size == 4 then
483
- s += ".x"
484
- elsif @source.type.size == 8 then
485
- s += ".xy"
486
- end
487
- s += ")"
488
- else
489
- s += "tex#{dim_number}Dfetch(#{@source},"
490
- if dim_number == 1 then
491
- s += "#{@indexes[0]}"
492
- else
493
- if dim_number == 2 then
494
- s += "int2("
495
- else
496
- s += "int3("
497
- end
498
- s += "#{@indexes.join(", ")})"
499
- end
500
- s += ")"
501
- end
502
- return s
503
- end
504
- def to_str_c
505
- return to_str_texture if @source.texture
506
- dim = @source.dimension.first
507
- if dim.val2 then
508
- start = dim.val1
509
- else
510
- start = BOAST::get_array_start
511
- end
512
- sub = "#{@indexes.first} - (#{start})"
513
- i=1
514
- ss = ""
515
- @source.dimension[0..-2].each{ |d|
516
- if d.size then
517
- ss += " * (#{d.size})"
518
- elsif d.val2 then
519
- ss += " * (#{d.val2} - (#{d.val1}) + 1)"
520
- else
521
- raise "Unkwown dimension size!"
522
- end
523
- dim = @source.dimension[i]
524
- if dim.val2 then
525
- start = dim.val1
526
- else
527
- start = BOAST::get_array_start
528
- end
529
- sub += " + (#{@indexes[i]} - (#{start}))"+ss
530
- i+=1
531
- }
532
- if BOAST::get_replace_constants then
533
- begin
534
- # puts sub
535
- indx = eval(sub)
536
- indx = indx.to_i
537
- # puts indx
538
- return "#{@source.constant[indx]}"
539
- rescue Exception => e
540
- end
541
- end
542
- s = "#{@source}[" + sub + "]"
543
- return s
544
- end
545
- def print(final=true)
546
- s=""
547
- s += " "*BOAST::get_indent_level if final
548
- s += self.to_str
549
- s += ";" if final and [C, CL, CUDA].include?( BOAST::get_lang )
550
- BOAST::get_output.puts s if final
551
- return s
552
- end
553
- end
554
-
555
-
556
- class Variable
557
- alias_method :orig_method_missing, :method_missing
558
-
559
- def method_missing(m, *a, &b)
560
- return self.struct_reference(type.members[m.to_s]) if type.members[m.to_s]
561
- # return self.get_element(m.to_s) if type.getters[m.to_s]
562
- # return self.set_element(m.to_s) if type.setters[m.to_s]
563
- return self.orig_method_missing(m, *a, &b)
564
- end
565
-
566
- def self.parens(*args,&block)
567
- return self::new(*args,&block)
568
- end
569
-
570
- attr_reader :name
571
- attr_accessor :direction
572
- attr_accessor :constant
573
- attr_reader :allocate
574
- attr_reader :type
575
- attr_reader :dimension
576
- attr_reader :local
577
- attr_reader :texture
578
- attr_reader :sampler
579
- attr_reader :restrict
580
- attr_accessor :replace_constant
581
- attr_accessor :force_replace_constant
582
-
583
- def initialize(name,type,hash={})
584
- @name = name.to_s
585
- @direction = hash[:direction] ? hash[:direction] : hash[:dir]
586
- @constant = hash[:constant] ? hash[:constant] : hash[:const]
587
- @dimension = hash[:dimension] ? hash[:dimension] : hash[:dim]
588
- @local = hash[:local] ? hash[:local] : hash[:shared]
589
- @texture = hash[:texture]
590
- @allocate = hash[:allocate]
591
- @restrict = hash[:restrict]
592
- @force_replace_constant = false
593
- if not hash[:replace_constant].nil? then
594
- @replace_constant = hash[:replace_constant]
595
- else
596
- @replace_constant = true
597
- end
598
- if @texture and BOAST::get_lang == CL then
599
- @sampler = Variable::new("sampler_#{name}", BOAST::CustomType,:type_name => "sampler_t" ,:replace_constant => false, :constant => "CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST")
600
- else
601
- @sampler = nil
602
- end
603
- @type = type::new(hash)
604
- @hash = hash
605
- end
606
-
607
- def copy(name=@name,options={})
608
- hash = @hash.clone
609
- options.each { |k,v|
610
- hash[k] = v
611
- }
612
- return Variable::new(name, @type.class, hash)
613
- end
614
-
615
- def Variable.from_type(name, type, options={})
616
- hash = type.to_hash
617
- options.each { |k,v|
618
- hash[k] = v
619
- }
620
- return Variable::new(name, type.class, hash)
621
- end
622
-
623
- def to_s
624
- self.to_str
625
- end
626
-
627
- def to_str
628
- if @force_replace_constant or ( @replace_constant and @constant and BOAST::get_replace_constants and not @dimension ) then
629
- s = @constant.to_s
630
- s += "_wp" if BOAST::get_lang == FORTRAN and @type and @type.size == 8
631
- return s
632
- end
633
- return @name
634
- end
635
-
636
- def to_var
637
- return self
638
- end
639
-
640
- def set(x)
641
- return Expression::new(BOAST::Set, self, x)
642
- end
643
-
644
- def ===(x)
645
- return Expression::new(BOAST::Affectation,self,x)
646
- end
647
-
648
- def ==(x)
649
- return Expression::new("==",self,x)
650
- end
651
-
652
- def !=(x)
653
- return Expression::new(BOAST::Different,self,x)
654
- end
655
-
656
- def >(x)
657
- return Expression::new(">",self,x)
658
- end
659
-
660
- def <(x)
661
- return Expression::new("<",self,x)
662
- end
663
-
664
- def >=(x)
665
- return Expression::new(">=",self,x)
666
- end
667
-
668
- def +(x)
669
- return Expression::new(BOAST::Addition,self,x)
670
- end
671
-
672
- def *(x)
673
- return Expression::new(BOAST::Multiplication,self,x)
674
- end
675
-
676
- def /(x)
677
- return Expression::new(BOAST::Division,self,x)
678
- end
679
-
680
- def -(x)
681
- return Expression::new(BOAST::Substraction,self,x)
682
- end
683
-
684
- def !
685
- return Expression::new(BOAST::Not,nil,self)
686
- end
687
-
688
- def -@
689
- return Expression::new(BOAST::Minus,nil,self)
690
- end
691
-
692
- def address
693
- return Expression::new("&",nil,self)
694
- end
695
-
696
- def dereference
697
- return self.copy("*(#{self.name})", :dimension => false, :dim => false) if [C, CL, CUDA].include?( BOAST::get_lang )
698
- return self if BOAST::get_lang == FORTRAN
699
- #return Expression::new("*",nil,self)
700
- end
701
-
702
- def struct_reference(x)
703
- return x.copy(self.name+"."+x.name) if [C, CL, CUDA].include?( BOAST::get_lang )
704
- return x.copy(self.name+"%"+x.name) if BOAST::get_lang == FORTRAN
705
- end
706
-
707
- def inc
708
- return Expression::new("++",self,nil)
709
- end
710
-
711
- def [](*args)
712
- return Index::new(self,args)
713
- end
714
-
715
- def indent
716
- return " "*BOAST::get_indent_level
717
- end
718
-
719
- def finalize
720
- s = ""
721
- s += ";" if [C, CL, CUDA].include?( BOAST::get_lang )
722
- s+="\n"
723
- return s
724
- end
725
-
726
- def decl_c(final=true, device=false)
727
- return decl_texture(final) if @texture
728
- s = ""
729
- s += self.indent if final
730
- s += "const " if @constant or @direction == :in
731
- s += "__global " if @direction and @dimension and not (@hash[:register] or @hash[:private] or @local) and BOAST::get_lang == CL
732
- s += "__local " if @local and BOAST::get_lang == CL
733
- s += "__shared__ " if @local and not device and BOAST::get_lang == CUDA
734
- s += @type.decl
735
- if(@dimension and not @constant and not @allocate and (not @local or (@local and device))) then
736
- s += " *"
737
- if @restrict then
738
- if BOAST::get_lang == CL
739
- s += " restrict"
740
- else
741
- s += " __restrict__"
742
- end
743
- end
744
- end
745
- s += " #{@name}"
746
- if @dimension and @constant then
747
- s += "[]"
748
- end
749
- if @dimension and ((@local and not device) or (@allocate and not @constant)) then
750
- s +="["
751
- s += @dimension.reverse.join("*")
752
- s +="]"
753
- end
754
- s += " = #{@constant}" if @constant
755
- s += self.finalize if final
756
- BOAST::get_output.print s if final
757
- return s
758
- end
759
-
760
- def header(lang=C,final=true)
761
- return decl_texture(final) if @texture
762
- s = ""
763
- s += self.indent if final
764
- s += "const " if @constant or @direction == :in
765
- s += "__global " if @direction and @dimension and BOAST::get_lang == CL
766
- s += "__local " if @local and BOAST::get_lang == CL
767
- s += "__shared__ " if @local and BOAST::get_lang == CUDA
768
- s += @type.decl
769
- if(@dimension and not @constant and not @local) then
770
- s += " *"
771
- end
772
- if not @dimension and lang == FORTRAN then
773
- s += " *"
774
- end
775
- s += " #{@name}"
776
- if(@dimension and @constant) then
777
- s += "[]"
778
- end
779
- if(@dimension and @local) then
780
- s +="["
781
- s += @dimension.reverse.join("*")
782
- s +="]"
783
- end
784
- s += " = #{@constant}" if @constant
785
- s += self.finalize if final
786
- BOAST::get_output.print s if final
787
- return s
788
- end
789
-
790
- def decl(final=true,device=false)
791
- return self.decl_fortran(final) if BOAST::get_lang == FORTRAN
792
- return self.decl_c(final, device) if [C, CL, CUDA].include?( BOAST::get_lang )
793
- end
794
-
795
- def decl_texture(final=true)
796
- raise "Unsupported language #{BOAST::get_lang} for texture!" if not [CL, CUDA].include?( BOAST::get_lang )
797
- raise "Write is unsupported for textures!" if not (@constant or @direction == :in)
798
- dim_number = 1
799
- if @dimension then
800
- dim_number == @dimension.size
801
- end
802
- raise "Unsupported number of dimension: #{dim_number}!" if dim_number > 3
803
- s = ""
804
- s += self.indent if final
805
- if BOAST::get_lang == CL then
806
- s += "__read_only "
807
- if dim_number < 3 then
808
- s += "image2d_t " #from OCL 1.2+ image1d_t is defined
809
- else
810
- s += "image3d_t "
811
- end
812
- else
813
- s += "texture<#{@type.decl}, cudaTextureType#{dim_number}D, cudaReadModeElementType> "
814
- end
815
- s += @name
816
- s += self.finalize if final
817
- BOAST::get_output.print s if final
818
- return s
819
- end
820
-
821
-
822
- def decl_fortran(final=true)
823
- s = ""
824
- s += self.indent if final
825
- s += @type.decl
826
- s += ", intent(#{@direction})" if @direction
827
- s += ", parameter" if @constant
828
- if(@dimension) then
829
- s += ", dimension("
830
- dim = @dimension[0].to_str
831
- if dim then
832
- s += dim
833
- @dimension[1..-1].each { |d|
834
- s += ", "
835
- s += d
836
- }
837
- else
838
- s += "*"
839
- end
840
- s += ")"
841
- end
842
- s += " :: #{@name}"
843
- if @constant
844
- s += " = #{@constant}"
845
- s += "_wp" if not @dimension and @type and @type.size == 8
846
- end
847
- s += self.finalize if final
848
- BOAST::get_output.print s if final
849
- return s
850
- end
851
-
852
- end
853
-
854
- class CodeBlock
855
- def initialize(&block)
856
- @block = block
857
- end
858
-
859
- def print(final=true)
860
- s=""
861
- s += " "*BOAST::get_indent_level if final
862
- BOAST::increment_indent_level
863
- BOAST::get_output.puts s if final
864
- if @block then
865
- s += "\n"
866
- @block.call
867
- end
868
- return s
869
- end
870
- end
871
-
872
- class Procedure
873
- def self.parens(*args,&block)
874
- return self::new(*args,&block)
875
- end
876
-
877
- attr_reader :name
878
- attr_reader :parameters
879
- attr_reader :constants
880
- attr_reader :properties
881
- attr_reader :headers
882
- def initialize(name, parameters=[], constants=[], properties={}, &block)
883
- @name = name
884
- @parameters = parameters
885
- @constants = constants
886
- @block = block
887
- @properties = properties
888
- @headers = properties[:headers]
889
- @headers = [] if not @headers
890
- end
891
-
892
- def header(lang=C,final=true)
893
- s = ""
894
- headers.each { |h|
895
- s += "#include <#{h}>\n"
896
- }
897
- if BOAST::get_lang == CL then
898
- s += "__kernel "
899
- wgs = @properties[:reqd_work_group_size]
900
- if wgs then
901
- s += "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
902
- end
903
- end
904
- trailer = ""
905
- trailer += "_" if lang == FORTRAN
906
- trailer += "_wrapper" if lang == CUDA
907
- if @properties[:return] then
908
- s += "#{@properties[:return].type.decl} "
909
- elsif lang == CUDA
910
- s += "unsigned long long int "
911
- else
912
- s += "void "
913
- end
914
- s += "#{@name}#{trailer}("
915
- if parameters.first then
916
- s += parameters.first.header(lang,false)
917
- parameters[1..-1].each { |p|
918
- s += ", "
919
- s += p.header(lang,false)
920
- }
921
- end
922
- if lang == CUDA then
923
- s += ", " if parameters.first
924
- s += "size_t *block_number, size_t *block_size"
925
- end
926
- s += ")"
927
- s += ";\n" if final
928
- BOAST::get_output.print s if final
929
- return s
930
- end
931
-
932
- def call(*parameters)
933
- prefix = ""
934
- prefix += "call " if BOAST::get_lang==FORTRAN
935
- f = FuncCall::new(@name, *parameters)
936
- f.prefix = prefix
937
- return f
938
- end
939
- def decl(final=true)
940
- return self.decl_fortran(final) if BOAST::get_lang==FORTRAN
941
- return self.decl_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
942
- end
943
- def close(final=true)
944
- return self.close_fortran(final) if BOAST::get_lang==FORTRAN
945
- return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
946
- end
947
- def close_c(final=true)
948
- BOAST::decrement_indent_level
949
- s = ""
950
- s += " return #{@properties[:return]};\n" if @properties[:return]
951
- s += "}"
952
- BOAST::get_output.puts s if final
953
- return s
954
- end
955
- def close_fortran(final=true)
956
- BOAST::decrement_indent_level
957
- s = ""
958
- if @properties[:return] then
959
- s += " #{@name} = #{@properties[:return]}\n"
960
- s += "END FUNCTION #{@name}"
961
- else
962
- s += "END SUBROUTINE #{@name}"
963
- end
964
- BOAST::get_output.puts s if final
965
- return s
966
- end
967
-
968
- def print(final=true)
969
- s = self.decl
970
- if @block then
971
- @block.call
972
- s += self.close
973
- end
974
- return s
975
- end
976
-
977
- def decl_c(final=true)
978
- s = ""
979
- # s += self.header(BOAST::get_lang,false)
980
- # s += ";\n"
981
- if BOAST::get_lang == CL then
982
- if not @properties[:local] then
983
- s += "__kernel "
984
- wgs = @properties[:reqd_work_group_size]
985
- if wgs then
986
- s += "__attribute__((reqd_work_group_size(#{wgs[0]},#{wgs[1]},#{wgs[2]}))) "
987
- end
988
- end
989
- elsif BOAST::get_lang == CUDA then
990
- if @properties[:local] then
991
- s += "static __device__ "
992
- else
993
- s += "__global__ "
994
- wgs = @properties[:reqd_work_group_size]
995
- if wgs then
996
- s += "__launch_bounds__(#{wgs[0]}*#{wgs[1]}*#{wgs[2]}) "
997
- end
998
- end
999
- end
1000
- if @properties[:qualifiers] then
1001
- s += "#{@properties[:qualifiers]} "
1002
- end
1003
- if @properties[:return] then
1004
- s += "#{@properties[:return].type.decl} "
1005
- else
1006
- s += "void "
1007
- end
1008
- s += "#{@name}("
1009
- if parameters.first then
1010
- s += parameters.first.decl(false, @properties[:local])
1011
- parameters[1..-1].each { |p|
1012
- s += ", "+p.decl(false, @properties[:local])
1013
- }
1014
- end
1015
- s += "){\n"
1016
- BOAST::increment_indent_level
1017
- constants.each { |c|
1018
- s += " "*BOAST::get_indent_level
1019
- s += c.decl(false)
1020
- s += ";\n"
1021
- }
1022
- BOAST::get_output.print s if final
1023
- return s
1024
- end
1025
- def decl_fortran(final=true)
1026
- s = ""
1027
- if @properties[:return] then
1028
- s += "#{@properties[:return].type.decl} FUNCTION "
1029
- else
1030
- s += "SUBROUTINE "
1031
- end
1032
- s += "#{@name}("
1033
- if parameters.first then
1034
- s += parameters.first
1035
- parameters[1..-1].each { |p|
1036
- s += ", "+p
1037
- }
1038
- end
1039
- s += ")\n"
1040
- BOAST::increment_indent_level
1041
- s += " "*BOAST::get_indent_level + "integer, parameter :: wp=kind(1.0d0)\n"
1042
- constants.each { |c|
1043
- s += " "*BOAST::get_indent_level
1044
- s += c.decl(false)
1045
- s += "\n"
1046
- }
1047
- parameters.each { |p|
1048
- s += " "*BOAST::get_indent_level
1049
- s += p.decl(false)
1050
- s += "\n"
1051
- }
1052
- BOAST::get_output.print s if final
1053
- return s
1054
- end
1055
- end
1056
-
1057
- class Dimension
1058
- def self.parens(*args,&block)
1059
- return self::new(*args,&block)
1060
- end
1061
-
1062
- attr_reader :val1
1063
- attr_reader :val2
1064
- attr_reader :size
1065
- def initialize(v1=nil,v2=nil)
1066
- @size = nil
1067
- @val1 = nil
1068
- @val2 = nil
1069
- if v2.nil? and v1 then
1070
- @val1 = BOAST::get_array_start
1071
- @val2 = v1 + BOAST::get_array_start - 1
1072
- @size = v1
1073
- else
1074
- @val1 = v1
1075
- @val2 = v2
1076
- end
1077
- end
1078
- def to_str
1079
- s = ""
1080
- if @val2 then
1081
- if BOAST::get_lang == FORTRAN then
1082
- s += @val1.to_s
1083
- s += ":"
1084
- s += @val2.to_s
1085
- elsif [C, CL, CUDA].include?( BOAST::get_lang ) then
1086
- s += (@val2 - @val1 + 1).to_s
1087
- end
1088
- elsif @val1.nil? then
1089
- return nil
1090
- else
1091
- s += @val1.to_s
1092
- end
1093
- return s
1094
- end
1095
- def to_s
1096
- self.to_str
1097
- end
1098
- end
1099
-
1100
-
1101
- class ConstArray < Array
1102
- def initialize(array,type = nil)
1103
- super(array)
1104
- @type = type::new if type
1105
- end
1106
- def to_s
1107
- self.to_str
1108
- end
1109
- def to_str
1110
- return self.to_str_fortran if BOAST::get_lang == FORTRAN
1111
- return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
1112
- end
1113
- def to_str_fortran
1114
- s = ""
1115
- return s if self.first.nil?
1116
- s += "(/ &\n"
1117
- s += self.first.to_s
1118
- s += "_wp" if @type and @type.size == 8
1119
- self[1..-1].each { |v|
1120
- s += ", &\n"+v.to_s
1121
- s += "_wp" if @type and @type.size == 8
1122
- }
1123
- s += " /)"
1124
- end
1125
- def to_str_c
1126
- s = ""
1127
- return s if self.first.nil?
1128
- s += "{\n"
1129
- s += self.first.to_s
1130
- self[1..-1].each { |v|
1131
- s += ",\n"+v.to_s
1132
- }
1133
- s += "}"
1134
- end
1135
- end
1136
-
1137
- class Ternary
1138
-
1139
- def self.parens(*args,&block)
1140
- return self::new(*args,&block)
1141
- end
1142
-
1143
- attr_reader :operand1
1144
- attr_reader :operand2
1145
- attr_reader :operand3
1146
-
1147
- def initialize(x,y,z)
1148
- @operand1 = x
1149
- @operand2 = y
1150
- @operand3 = z
1151
- end
1152
-
1153
- def ==(x)
1154
- return Expression::new("==",self,x)
1155
- end
1156
-
1157
- def +(x)
1158
- return Expression::new("+",self,x)
1159
- end
1160
-
1161
- def <(x)
1162
- return Expression::new("<",self,x)
1163
- end
1164
-
1165
- def >=(x)
1166
- return Expression::new(">=",self,x)
1167
- end
1168
-
1169
- def *(x)
1170
- return Expression::new("*",self,x)
1171
- end
1172
-
1173
- def -(x)
1174
- return Expression::new("-",self,x)
1175
- end
1176
-
1177
- def -@
1178
- return Expression::new("-",nil,self)
1179
- end
1180
-
1181
- def [](*args)
1182
- return Index::new(self,args)
1183
- end
1184
-
1185
- def to_s
1186
- self.to_str
1187
- end
1188
-
1189
- def to_str
1190
- raise "Ternary operator unsupported in FORTRAN!" if BOAST::get_lang == FORTRAN
1191
- return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
1192
- end
1193
- def to_str_c
1194
- s = ""
1195
- s += "(#{@operand1} ? #{@operand2} : #{@operand3})"
1196
- end
1197
- def print(final=true)
1198
- s=""
1199
- s += " "*BOAST::get_indent_level if final
1200
- s += self.to_str
1201
- s += ";" if final and [C, CL, CUDA].include?( BOAST::get_lang )
1202
- BOAST::get_output.puts s if final
1203
- return s
1204
- end
1205
-
1206
- end
1207
-
1208
- class FuncCall
1209
- @return_type
1210
- @options
1211
- def self.parens(*args,&block)
1212
- return self::new(*args,&block)
1213
- end
1214
-
1215
- attr_reader :func_name
1216
- attr_reader :args
1217
- attr_accessor :prefix
1218
-
1219
- def initialize(func_name, *args)
1220
- @func_name = func_name
1221
- if args.last.kind_of?(Hash) then
1222
- @options = args.last
1223
- @args = args[0..-2]
1224
- else
1225
- @args = args
1226
- end
1227
- @return_type = @options[:returns] if @options
1228
- end
1229
-
1230
- def to_var
1231
- if @return_type then
1232
- if @return_type.kind_of?(Variable)
1233
- return @return_type.copy("#{self}")
1234
- else
1235
- return Variable::new("#{self}", @return_type)
1236
- end
1237
- end
1238
- return nil
1239
- end
1240
-
1241
- def to_s
1242
- self.to_str
1243
- end
1244
-
1245
- def ==(x)
1246
- return Expression::new("==",self,x)
1247
- end
1248
-
1249
- def +(x)
1250
- return Expression::new("+",self,x)
1251
- end
1252
-
1253
- def *(x)
1254
- return Expression::new("*",self,x)
1255
- end
1256
-
1257
- def /(x)
1258
- return Expression::new("/",self,x)
1259
- end
1260
-
1261
- def -(x)
1262
- return Expression::new("-",self,x)
1263
- end
1264
-
1265
- def -@
1266
- return Expression::new("-",nil,self)
1267
- end
1268
-
1269
- def [](*args)
1270
- return Index::new(self,args)
1271
- end
1272
-
1273
-
1274
- def to_str
1275
- return self.to_str_fortran if BOAST::get_lang == FORTRAN
1276
- return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
1277
- end
1278
- def to_str_fortran
1279
- s = ""
1280
- s += @prefix if @prefix
1281
- s += "#{func_name}(#{@args.join(", ")})"
1282
- end
1283
- def to_str_c
1284
- s = ""
1285
- s += @prefix if @prefix
1286
- s += "#{func_name}(#{@args.join(", ")})"
1287
- end
1288
- def print(final=true)
1289
- s=""
1290
- s += " "*BOAST::get_indent_level if final
1291
- s += self.to_str
1292
- s += ";" if final and [C, CL, CUDA].include?( BOAST::get_lang )
1293
- BOAST::get_output.puts s if final
1294
- return s
1295
- end
1296
- end
1297
-
1298
- class While
1299
- def self.parens(*args,&block)
1300
- return self::new(*args,&block)
1301
- end
1302
-
1303
- attr_reader :condition
1304
- def initialize(condition, &block)
1305
- @condition = condition
1306
- @block = block
1307
- end
1308
- def to_s
1309
- self.to_str
1310
- end
1311
- def to_str
1312
- return self.to_str_fortran if BOAST::get_lang == FORTRAN
1313
- return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
1314
- end
1315
- def to_str_fortran
1316
- s = ""
1317
- s += "do while( #{@condition} )"
1318
- return s
1319
- end
1320
- def to_str_c
1321
- s = ""
1322
- s += "while(#{@condition}){"
1323
- return s
1324
- end
1325
- def print(*args)
1326
- final = true
1327
- s=""
1328
- s += " "*BOAST::get_indent_level if final
1329
- s += self.to_str
1330
- BOAST::increment_indent_level
1331
- BOAST::get_output.puts s if final
1332
- if @block then
1333
- s += "\n"
1334
- @block.call(*args)
1335
- s += self.close
1336
- end
1337
- return s
1338
- end
1339
- def close(final=true)
1340
- return self.close_fortran(final) if BOAST::get_lang == FORTRAN
1341
- return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
1342
- end
1343
- def close_c(final=true)
1344
- s = ""
1345
- BOAST::decrement_indent_level
1346
- s += " "*BOAST::get_indent_level if final
1347
- s += "}"
1348
- BOAST::get_output.puts s if final
1349
- return s
1350
- end
1351
- def close_fortran(final=true)
1352
- s = ""
1353
- BOAST::decrement_indent_level
1354
- s += " "*BOAST::get_indent_level if final
1355
- s += "end do"
1356
- BOAST::get_output.puts s if final
1357
- return s
1358
- end
1359
-
1360
- end
1361
-
1362
- class Else
1363
- def self.parens(*args,&block)
1364
- return self::new(*args,&block)
1365
- end
1366
-
1367
- attr_reader :condition
1368
- def initialize(condition=nil, &block)
1369
- @condition = condition
1370
- @block = block
1371
- end
1372
- def to_s
1373
- self.to_str
1374
- end
1375
- def to_str
1376
- return self.to_str_fortran if BOAST::get_lang == FORTRAN
1377
- return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
1378
- end
1379
- def to_str_fortran
1380
- s = ""
1381
- if @condition then
1382
- s += "else if #{@condition} then"
1383
- else
1384
- s += "else"
1385
- end
1386
- return s
1387
- end
1388
- def to_str_c
1389
- s = ""
1390
- if @condition then
1391
- s += "else if(#{@condition}){"
1392
- else
1393
- s += "else {"
1394
- end
1395
- return s
1396
- end
1397
- def print(*args)
1398
- final = true
1399
- s=""
1400
- s += " "*BOAST::get_indent_level if final
1401
- s += self.to_str
1402
- BOAST::increment_indent_level
1403
- BOAST::get_output.puts s if final
1404
- if @block then
1405
- s += "\n"
1406
- @block.call(*args)
1407
- s += self.close
1408
- end
1409
- return s
1410
- end
1411
- def close(final=true)
1412
- return self.close_fortran(final) if BOAST::get_lang == FORTRAN
1413
- return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
1414
- end
1415
- def close_c(final=true)
1416
- s = ""
1417
- BOAST::decrement_indent_level
1418
- s += " "*BOAST::get_indent_level if final
1419
- s += "}"
1420
- BOAST::get_output.puts s if final
1421
- return s
1422
- end
1423
- def close_fortran(final=true)
1424
- s = ""
1425
- BOAST::decrement_indent_level
1426
- s += " "*BOAST::get_indent_level if final
1427
- s += "end if"
1428
- BOAST::get_output.puts s if final
1429
- return s
1430
- end
1431
-
1432
- end
1433
-
1434
- class Case
1435
- def self.parens(*args,&block)
1436
- return self::new(*args,&block)
1437
- end
1438
-
1439
- attr_reader :expression
1440
- attr_reader :constants_list
1441
-
1442
- def initialize(expression, *control)
1443
- @expression = expression
1444
- @constants_list = []
1445
- @blocks = []
1446
- if control.size < 1 then
1447
- raise "No block given!"
1448
- elsif control.size.even? then
1449
- (0..control.size-1).step(2) { |i|
1450
- @constants_list[i/2] = [control[i]].flatten
1451
- @blocks[i/2] = control[i+1]
1452
- }
1453
- else
1454
- (0..control.size-2).step(2) { |i|
1455
- @constants_list[i/2] = [control[i]].flatten
1456
- @blocks[i/2] = control[i+1]
1457
- }
1458
- @blocks.push(control.last)
1459
- end
1460
- end
1461
-
1462
- def to_s(*args)
1463
- self.to_str(*args)
1464
- end
1465
-
1466
- def to_str(constants, first= true)
1467
- return self.to_str_fortran(constants, first) if BOAST::get_lang == FORTRAN
1468
- return self.to_str_c(constants, first) if [C, CL, CUDA].include?( BOAST::get_lang )
1469
- end
1470
-
1471
- def to_str_fortran(constants, first)
1472
- s = ""
1473
- if first then
1474
- s += " "*BOAST::get_indent_level
1475
- s += "select case (#{@expression})\n"
1476
- BOAST::increment_indent_level
1477
- else
1478
- BOAST::decrement_indent_level
1479
- end
1480
- s += " "*BOAST::get_indent_level
1481
- if constants and constants.size>0 then
1482
- s += "case (#{constants.join(" : ")})"
1483
- else
1484
- s += "case default"
1485
- end
1486
- BOAST::increment_indent_level
1487
- return s
1488
- end
1489
-
1490
- def to_str_c(constants, first)
1491
- s = ""
1492
- if first then
1493
- s += " "*BOAST::get_indent_level
1494
- s += "switch(#{@expression}){\n"
1495
- BOAST::increment_indent_level
1496
- else
1497
- s += " "*BOAST::get_indent_level + "break;\n"
1498
- BOAST::decrement_indent_level
1499
- end
1500
- s += " "*BOAST::get_indent_level
1501
- if constants and constants.size>0 then
1502
- s += "case #{constants.join(" : case")} :"
1503
- else
1504
- s += "default :"
1505
- end
1506
- BOAST::increment_indent_level
1507
- return s
1508
- end
1509
-
1510
- def print(*args)
1511
- first = true
1512
- @blocks.each_index { |indx|
1513
- s = self.to_str(@constants_list[indx],first)
1514
- BOAST::get_output.puts s
1515
- @blocks[indx].call(*args)
1516
- first = false
1517
- }
1518
- self.close
1519
- return self
1520
- end
1521
- def close(final=true)
1522
- return self.close_fortran(final) if BOAST::get_lang == FORTRAN
1523
- return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
1524
- end
1525
- def close_c(final=true)
1526
- s = ""
1527
- s += " "*BOAST::get_indent_level if final
1528
- s += "break;\n"
1529
- BOAST::decrement_indent_level
1530
- s += " "*BOAST::get_indent_level if final
1531
- s += "}"
1532
- BOAST::decrement_indent_level
1533
- BOAST::get_output.puts s if final
1534
- return s
1535
- end
1536
- def close_fortran(final=true)
1537
- s = ""
1538
- BOAST::decrement_indent_level
1539
- s += " "*BOAST::get_indent_level if final
1540
- s += "end select"
1541
- BOAST::decrement_indent_level
1542
- BOAST::get_output.puts s if final
1543
- return s
1544
- end
1545
-
1546
- end
1547
- class If
1548
- def self.parens(*args,&block)
1549
- return self::new(*args,&block)
1550
- end
1551
-
1552
- attr_reader :conditions
1553
- def initialize(*conditions, &block)
1554
- @conditions = []
1555
- @blocks = []
1556
- if conditions.size == 0 then
1557
- raise "Illegal if construct!"
1558
- elsif conditions.size == 1 then
1559
- @conditions.push(conditions[0])
1560
- @blocks.push(block)
1561
- elsif conditions.size.even? then
1562
- (0..conditions.size-1).step(2) { |i|
1563
- @conditions[i/2] = conditions[i]
1564
- @blocks[i/2] = conditions[i+1]
1565
- }
1566
- else
1567
- (0..conditions.size-2).step(2) { |i|
1568
- @conditions[i/2] = conditions[i]
1569
- @blocks[i/2] = conditions[i+1]
1570
- }
1571
- @blocks.push(conditions.last)
1572
- end
1573
- end
1574
- def to_s(*args)
1575
- self.to_str(*args)
1576
- end
1577
- def to_str(condition, first= true)
1578
- return self.to_str_fortran(condition, first) if BOAST::get_lang == FORTRAN
1579
- return self.to_str_c(condition, first) if [C, CL, CUDA].include?( BOAST::get_lang )
1580
- end
1581
- def to_str_fortran(condition, first)
1582
- s = ""
1583
- if first then
1584
- s += "if ( #{condition} ) then"
1585
- else
1586
- if condition then
1587
- s += "else if ( #{condition} ) then"
1588
- else
1589
- s += "else"
1590
- end
1591
- end
1592
- return s
1593
- end
1594
- def to_str_c(condition, first)
1595
- s = ""
1596
- if first then
1597
- s += "if(#{condition}){"
1598
- else
1599
- if condition then
1600
- s += "} else if(#{condition}){"
1601
- else
1602
- s += "} else {"
1603
- end
1604
- end
1605
- return s
1606
- end
1607
- def print(*args)
1608
- s=""
1609
- s += " "*BOAST::get_indent_level
1610
- s += self.to_str(@conditions.first)
1611
- BOAST::increment_indent_level
1612
- BOAST::get_output.puts s
1613
- if @blocks.size > 0 then
1614
- if @blocks[0] then
1615
- @blocks[0].call(*args)
1616
- end
1617
- @blocks[1..-1].each_index { |indx|
1618
- BOAST::decrement_indent_level
1619
- s=""
1620
- s += " "*BOAST::get_indent_level
1621
- s += self.to_str(@conditions[1..-1][indx],false)
1622
- BOAST::increment_indent_level
1623
- BOAST::get_output.puts s
1624
- @blocks[1..-1][indx].call(*args)
1625
- }
1626
- self.close
1627
- end
1628
- return self
1629
- end
1630
- def close(final=true)
1631
- return self.close_fortran(final) if BOAST::get_lang == FORTRAN
1632
- return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
1633
- end
1634
- def close_c(final=true)
1635
- s = ""
1636
- BOAST::decrement_indent_level
1637
- s += " "*BOAST::get_indent_level if final
1638
- s += "}"
1639
- BOAST::get_output.puts s if final
1640
- return s
1641
- end
1642
- def close_fortran(final=true)
1643
- s = ""
1644
- BOAST::decrement_indent_level
1645
- s += " "*BOAST::get_indent_level if final
1646
- s += "end if"
1647
- BOAST::get_output.puts s if final
1648
- return s
1649
- end
1650
-
1651
- end
1652
-
1653
- class For
1654
- attr_reader :iterator
1655
- attr_reader :begin
1656
- attr_reader :end
1657
- attr_reader :step
1658
-
1659
- def self.parens(*args,&block)
1660
- return self::new(*args,&block)
1661
- end
1662
-
1663
- def initialize(i, b, e, s=1, &block)
1664
- @iterator = i
1665
- @begin = b
1666
- @end = e
1667
- @step = s
1668
- @block = block
1669
- end
1670
- def to_s
1671
- self.to_str
1672
- end
1673
- def to_str
1674
- return self.to_str_fortran if BOAST::get_lang == FORTRAN
1675
- return self.to_str_c if [C, CL, CUDA].include?( BOAST::get_lang )
1676
- end
1677
- def to_str_fortran
1678
- s = ""
1679
- s += "do #{@iterator}=#{@begin}, #{@end}"
1680
- s += ", #{@step}" if 1 != @step
1681
- return s
1682
- end
1683
- def to_str_c
1684
- s = ""
1685
- s += "for(#{@iterator}=#{@begin}; #{@iterator}<=#{@end}; #{@iterator}+=#{@step}){"
1686
- return s
1687
- end
1688
-
1689
- def unroll(*args)
1690
- raise "Block not given!" if not @block
1691
- BOAST::push_env( :replace_constants => true )
1692
- begin
1693
- if @begin.kind_of?(Variable) then
1694
- start = @begin.constant
1695
- elsif @begin.kind_of?(Expression) then
1696
- start = eval "#{@begin}"
1697
- else
1698
- start = @begin.to_i
1699
- end
1700
- if @end.kind_of?(Variable) then
1701
- e = @end.constant
1702
- elsif @end.kind_of?(Expression) then
1703
- e = eval "#{@end}"
1704
- else
1705
- e = @end.to_i
1706
- end
1707
- if @step.kind_of?(Variable) then
1708
- step = @step.constant
1709
- elsif @step.kind_of?(Expression) then
1710
- step = eval "#{@step}"
1711
- else
1712
- step = @step.to_i
1713
- end
1714
- raise "Invalid bounds (not constants)!" if not ( start and e and step )
1715
- rescue Exception => ex
1716
- if not ( start and e and step ) then
1717
- BOAST::pop_env( :replace_constants )
1718
- return self.print(*args) if not ( start and e and step )
1719
- end
1720
- end
1721
- BOAST::pop_env( :replace_constants )
1722
- range = start..e
1723
- @iterator.force_replace_constant = true
1724
- range.step(step) { |i|
1725
- @iterator.constant = i
1726
- @block.call(*args)
1727
- }
1728
- @iterator.force_replace_constant = false
1729
- @iterator.constant = nil
1730
- end
1731
-
1732
- def print(*args)
1733
- final = true
1734
- s=""
1735
- s += " "*BOAST::get_indent_level if final
1736
- s += self.to_str
1737
- BOAST::increment_indent_level
1738
- BOAST::get_output.puts s if final
1739
- if @block then
1740
- s += "\n"
1741
- @block.call(*args)
1742
- s += self.close
1743
- end
1744
- return s
1745
- end
1746
-
1747
- def close(final=true)
1748
- return self.close_fortran(final) if BOAST::get_lang == FORTRAN
1749
- return self.close_c(final) if [C, CL, CUDA].include?( BOAST::get_lang )
1750
- end
1751
- def close_c(final=true)
1752
- s = ""
1753
- BOAST::decrement_indent_level
1754
- s += " "*BOAST::get_indent_level if final
1755
- s += "}"
1756
- BOAST::get_output.puts s if final
1757
- return s
1758
- end
1759
- def close_fortran(final=true)
1760
- s = ""
1761
- BOAST::decrement_indent_level
1762
- s += " "*BOAST::get_indent_level if final
1763
- s += "enddo"
1764
- BOAST::get_output.puts s if final
1765
- return s
1766
- end
1767
- end
1768
248
  Var = Variable
1769
249
  Dim = Dimension
1770
250
  Call = FuncCall