Class: Ikra::Symbolic::ArrayStencilCommand

Inherits:
Object
  • Object
show all
Includes:
ArrayCommand
Defined in:
lib/symbolic/visitor.rb,
lib/symbolic/symbolic.rb

Defined Under Namespace

Classes: FlattenIndexNodeVisitor

Instance Attribute Summary collapse

Attributes included from ArrayCommand

#block, #block_size, #generator_node, #gpu_result_pointer, #input, #keep, #unique_id

Instance Method Summary collapse

Methods included from ArrayCommand

#[], #block_def_node, #block_parameter_names, #command_binding, #command_translator_class, #dimensions, #each, #eql?, #execute, #externals, #has_previous_result?, #hash, #ikra_type, included, #lexical_externals, #pack, #post_execute, reset_unique_id, #result_type, #set_unique_id, #to_c_type, #to_command, #to_ffi_type, #to_ruby_type, #to_s, #with_index

Methods included from Types::RubyType

#class_id, #eql?, #hash, #inspect, #is_primitive?, #is_union_type?, #should_generate_self_arg?, #to_array_type, #to_c_type, #to_ruby_type, #to_str, #to_union_type

Methods included from ParallelOperations

#&, #*, #+, #-, #/, #<, #<=, #>, #>=, #^, #pcombine, #pmap, #preduce, #pstencil, #pzip, #|

Constructor Details

#initialize(target, offsets, out_of_range_value, block, ast: nil, block_size: DEFAULT_BLOCK_SIZE, keep: false, use_parameter_array: true, generator_node: nil, with_index: false, command_binding: nil) ⇒ ArrayStencilCommand

Returns a new instance of ArrayStencilCommand.



627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
# File 'lib/symbolic/symbolic.rb', line 627

def initialize(
    target, 
    offsets, 
    out_of_range_value, 
    block, 
    ast: nil,
    block_size: DEFAULT_BLOCK_SIZE, 
    keep: false, 
    use_parameter_array: true,
    generator_node: nil,
    with_index: false,
    command_binding: nil)

    super(block: block, block_ast: ast, block_size: block_size, keep: keep, generator_node: generator_node, command_binding: command_binding)

    if offsets.first == "G"
        # A stencil will be generated
        dims = target.to_command.dimensions.size

        directions = offsets[1]
        # Directions says how many of the dimensions can be used in the stencil. E.g.: in 2D directions = 1 would relate in a stencil that only has up, down, left, right offsets, but no diagonals  
        distance = offsets[2]
        # Distance says how many steps can be made into the directions distance = 2 in the example before would mean 1 or 2 up/down/left/right 

        if directions > dims
            raise ArgumentError.new(
                "Directions should not be higher than the number of dimensions")
        end

        singles = [0]
        # Building the numbers that can be part of an offset
        for i in 1..distance
            singles = singles + [i] + [-i]
        end

        offsets = []

        # Iterate all possibilities
        for i in 0..singles.size**dims-1
            # Transform current permutation to according string / base representation
            base = i.to_s(singles.size)

            # Fill up zeroes
            sizedif = (singles.size**dims-1).to_s(singles.size).size - base.size
            base = "0" * sizedif + base

            # Check whether offset is allowed (concerning directions)
            if base.gsub(/[^0]/, "").size >= dims - directions
                new_offset = []
                for j in 0..dims-1
                    new_offset.push(singles[base[j].to_i])
                end
                offsets.push(new_offset)
            end
        end
    end

    if not offsets.first.is_a?(Array)
        offsets = offsets.map do |offset|
            [offset]
        end
    end

    # Read more than just one element, fall back to `:entire` for now

    @out_of_range_value = out_of_range_value
    @use_parameter_array = use_parameter_array

    if use_parameter_array
        @input = [StencilArrayInput.new(
            command: target.to_command,
            pattern: :entire,
            offsets: offsets,
            out_of_bounds_value: out_of_range_value)]
    else
        @input = [StencilSingleInput.new(
            command: target.to_command,
            pattern: :entire,
            offsets: offsets,
            out_of_bounds_value: out_of_range_value)]
    end

    if with_index
        @input.push(SingleInput.new(
            command: ArrayIndexCommand.new(dimensions: dimensions),
            pattern: :tid))
    end
    
    # Offsets should be arrays
    for offset in offsets
        if !offset.is_a?(Array)
            raise ArgumentError.new("Array expected but #{offset.class} found")
        end

        if offset.size != dimensions.size
            raise ArgumentError.new("#{dimensions.size} indices expected")
        end
    end
    
    @offsets = offsets

    # Translate relative indices to 1D-indicies starting by 0
    if block_def_node != nil
        if use_parameter_array
            offsets_mapped = Hash.new
            for i in 0..offsets.size-1
                offsets_mapped[offsets[i]] = i
            end

            # Do not modify the original AST
            @ast = block_def_node.clone
            @ast.accept(FlattenIndexNodeVisitor.new(
                block_parameter_names.first, offsets_mapped, self))
        end
    end
end

Instance Attribute Details

#offsetsObject (readonly)

Returns the value of attribute offsets.



623
624
625
# File 'lib/symbolic/symbolic.rb', line 623

def offsets
  @offsets
end

#out_of_range_valueObject (readonly)

Returns the value of attribute out_of_range_value.



624
625
626
# File 'lib/symbolic/symbolic.rb', line 624

def out_of_range_value
  @out_of_range_value
end

#use_parameter_arrayObject (readonly)

Returns the value of attribute use_parameter_array.



625
626
627
# File 'lib/symbolic/symbolic.rb', line 625

def use_parameter_array
  @use_parameter_array
end

Instance Method Details

#==(other) ⇒ Object



744
745
746
747
748
# File 'lib/symbolic/symbolic.rb', line 744

def ==(other)
    return super(other) && offsets == other.offsets && 
        out_of_range_value == other.out_of_range_value &&
        use_parameter_array == other.use_parameter_array
end

#accept(visitor) ⇒ Object



22
23
24
# File 'lib/symbolic/visitor.rb', line 22

def accept(visitor)
    visitor.visit_array_stencil_command(self)
end

#max_offsetObject



758
759
760
# File 'lib/symbolic/symbolic.rb', line 758

def max_offset
    return offsets.max
end

#min_offsetObject



754
755
756
# File 'lib/symbolic/symbolic.rb', line 754

def min_offset
    return offsets.min
end

#sizeObject



750
751
752
# File 'lib/symbolic/symbolic.rb', line 750

def size
    return input.first.command.size
end