Class: Ikra::TypeInference::CommandInference

Inherits:
Symbolic::Visitor show all
Defined in:
lib/types/inference/command_inference.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Symbolic::Visitor

#visit_array_combine_command, #visit_array_host_section_command, #visit_array_reduce_command, #visit_array_select_command, #visit_array_stencil_command, #visit_fixed_size_array_in_host_section_command

Class Method Details

.process_command(command) ⇒ Object



4
5
6
# File 'lib/types/inference/command_inference.rb', line 4

def self.process_command(command)
    return command.accept(CommandInference.new)
end

Instance Method Details

#process_block(block_def_node:, lexical_variables: {}, block_parameters:) ⇒ Object

Processes a parallel section, i.e., a [BlockDefNode]. Performs the following steps:

  1. Gather parameter types and names in a hash map.

  2. Set lexical variables on [BlockDefNode].

  3. Perform type inference, i.e., annotate [BlockDefNode] AST with types.

  4. Return result type of the block.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/types/inference/command_inference.rb', line 13

def process_block(
    block_def_node:, 
    lexical_variables: {}, 
    block_parameters:)

    # Build hash of parameter name -> type mappings
    block_parameter_types = {}
    for variable in block_parameters
        block_parameter_types[variable.name] = variable.type
    end

    parameter_types_string = "[" + block_parameter_types.map do |id, type| "#{id}: #{type}" end.join(", ") + "]"
    Log.info("Type inference for block with input types #{parameter_types_string}")

    # Add information to block_def_node
    block_def_node.parameters_names_and_types = block_parameter_types

    # Lexical variables
    lexical_variables.each do |name, value|
        block_def_node.lexical_variables_names_and_types[name] = value.ikra_type.to_union_type
    end

    # Type inference
    type_inference_visitor = TypeInference::Visitor.new
    return_type = type_inference_visitor.process_block(block_def_node)

    return return_type
end

#process_entire_input(command) ⇒ Object

Processes all input commands. This is similar to ‘translate_entire_input`, but it performs only type inference and does not generate any source code.



44
45
46
47
48
49
50
51
52
53
# File 'lib/types/inference/command_inference.rb', line 44

def process_entire_input(command)
    input_parameters = command.input.each_with_index.map do |input, index|
        input.get_parameters(
            parent_command: command,
            # Assuming that every input consumes exactly one parameter
            start_eat_params_offset: index)
    end

    return input_parameters.reduce(:+)
end

#visit_array_command(command) ⇒ Object

Process block and dependent computations. This method is used for all array commands that do not have a separate Visitor method.



57
58
59
60
61
62
# File 'lib/types/inference/command_inference.rb', line 57

def visit_array_command(command)
    return process_block(
        block_def_node: command.block_def_node,
        lexical_variables: command.lexical_externals,
        block_parameters: process_entire_input(command))
end

#visit_array_identity_command(command) ⇒ Object



68
69
70
# File 'lib/types/inference/command_inference.rb', line 68

def visit_array_identity_command(command)
    return command.base_type
end

#visit_array_in_host_section_command(command) ⇒ Object



64
65
66
# File 'lib/types/inference/command_inference.rb', line 64

def visit_array_in_host_section_command(command)
    return command.base_type
end

#visit_array_index_command(command) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/types/inference/command_inference.rb', line 72

def visit_array_index_command(command)
    num_dims = command.dimensions.size

    if num_dims > 1
        # Build Ikra struct type
        zipped_type_singleton = Types::ZipStructType.new(
            *([Types::UnionType.create_int] * command.dimensions.size))
        return zipped_type_singleton.to_union_type
    else
        return Types::UnionType.create_int
    end
end

#visit_array_zip_command(command) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/types/inference/command_inference.rb', line 85

def visit_array_zip_command(command)
    input_types = command.input.each_with_index.map do |input, index|
        input.get_parameters(
            parent_command: command,
            # Assuming that every input consumes exactly one parameter
            start_eat_params_offset: index).map do |variable|
                variable.type
            end
    end.reduce(:+)

    # Build Ikra struct type
    zipped_type_singleton = Types::ZipStructType.new(*input_types)
    return zipped_type_singleton.to_union_type
end