class Ikra::Symbolic::ArrayStencilCommand::FlattenIndexNodeVisitor

This visitor executes the check_parents_index function on every local variable If the local variable is the “stencil array” then its indices will get modified/corrected for the 1D array access

Attributes

command[R]
name[R]
offsets[R]

Public Class Methods

new(name, offsets, command) click to toggle source
# File lib/symbolic/symbolic.rb, line 549
def initialize(name, offsets, command)
    @name = name
    @offsets = offsets
    @command = command
end

Public Instance Methods

check_index(name, offsets, node) click to toggle source
# File lib/symbolic/symbolic.rb, line 566
def check_index(name, offsets, node)
    if node.identifier == name
        # This is the array-variable used in the stencil

        send_node = node
        index_combination = []
        is_literal = true

        # Build the index off this access in index_combination
        for i in 0..command.dimensions.size-1
            send_node = send_node.parent
            if not (send_node.is_a?(AST::SendNode) && send_node.selector == :[])
                raise AssertionError.new(
                    "This has to be a SendNode and Array-selector")
            end
            index_combination[i] = send_node.arguments.first
            if not index_combination[i].is_a?(AST::IntLiteralNode)
                is_literal = false
            end
        end

        if is_literal
            # The index consists of only literals so we can translate it easily by mapping the index onto the offsets

            index_combination = index_combination.map do |x|
                x.value
            end

            replacement = AST::IntLiteralNode.new(
                value: offsets[index_combination])
        else
            # This handles the case where non-literals have to be translated with the Ternary Node

            offset_arr = offsets.to_a
            replacement = AST::IntLiteralNode.new(value: offset_arr[0][1])
            for i in 1..offset_arr.size-1
                # Build combination of ternary nodes

                ternary_build = AST::SendNode.new(receiver: AST::IntLiteralNode.new(value: offset_arr[i][0][0]), selector: :==, arguments: [index_combination[0]])
                for j in 1..index_combination.size-1

                    next_eq = AST::SendNode.new(receiver: AST::IntLiteralNode.new(value: offset_arr[i][0][j]), selector: :==, arguments: [index_combination[j]])
                    ternary_build = AST::SendNode.new(receiver: next_eq, selector: :"&&", arguments: [ternary_build])
                end
                replacement = AST::TernaryNode.new(condition: ternary_build, true_val: AST::IntLiteralNode.new(value: offset_arr[i][1]), false_val: replacement)
            end
        end

        #Replace outer array access with new 1D array access

        send_node.replace(AST::SendNode.new(receiver: node, selector: :[], arguments: [replacement]))
    end
end
visit_lvar_read_node(node) click to toggle source
Calls superclass method Ikra::AST::Visitor#visit_lvar_read_node
# File lib/symbolic/symbolic.rb, line 555
def visit_lvar_read_node(node)
    super(node)
    check_index(name, offsets, node)
end
visit_lvar_write_node(node) click to toggle source
# File lib/symbolic/symbolic.rb, line 560
def visit_lvar_write_node(node)
    super(node)
    check_index(name, offsets, node)
end