Module: Ikra::Translator
- Defined in:
- lib/translator/translator.rb,
lib/translator/ast_translator.rb,
lib/translator/kernel_builder.rb,
lib/translator/program_builder.rb,
lib/translator/block_translator.rb,
lib/translator/input_translator.rb,
lib/translator/program_launcher.rb,
lib/translator/environment_builder.rb,
lib/translator/last_returns_visitor.rb,
lib/translator/commands/array_zip_command.rb,
lib/translator/commands/command_translator.rb,
lib/translator/host_section/ast_translator.rb,
lib/translator/variable_classifier_visitor.rb,
lib/translator/array_command_struct_builder.rb,
lib/translator/commands/array_index_command.rb,
lib/translator/host_section/program_builder.rb,
lib/translator/commands/array_reduce_command.rb,
lib/translator/commands/array_combine_command.rb,
lib/translator/commands/array_stencil_command.rb,
lib/translator/commands/array_identity_command.rb,
lib/translator/kernel_launcher/kernel_launcher.rb,
lib/translator/host_section/array_host_section_command.rb,
lib/translator/kernel_launcher/for_loop_kernel_launcher.rb,
lib/translator/host_section/array_in_host_section_command.rb,
lib/translator/kernel_launcher/while_loop_kernel_launcher.rb,
lib/translator/host_section/parallel_section_invocation_visitor.rb
Overview
This module contains functionality for translating Ruby code to CUDA (C++) code.
Defined Under Namespace
Modules: Constants, KernelLaunchArgumentGenerator Classes: ASTTranslator, ArrayCommandStructBuilder, BlockTranslationResult, CommandTranslator, EntireInputTranslationResult, EnvironmentBuilder, HostSectionASTTranslator, HostSectionCommandTranslator, InputTranslationResult, LastStatementReturnsVisitor, ParallelSectionInvocationVisitor, Variable, VariableClassifier
Constant Summary collapse
- BlockSelectorDummy =
:"<BLOCK>"
Class Method Summary collapse
-
.read_file(file_name:, replacements: {}) ⇒ Object
Reads a CUDA source code file and replaces identifiers by provided substitutes.
-
.translate_block(block_def_node:, environment_builder:, command_id:, lexical_variables: {}, entire_input_translation: nil, pre_execution: nil, override_block_parameters: nil, block_parameters: nil) ⇒ BlockTranslationResult
Translates a Ruby block to CUDA source code.
- .wrap_in_c_block(str) ⇒ Object
Class Method Details
.read_file(file_name:, replacements: {}) ⇒ Object
Reads a CUDA source code file and replaces identifiers by provided substitutes.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/translator/translator.rb', line 55 def read_file(file_name:, replacements: {}) full_name = Ikra::Configuration.resource_file_name(file_name) if !File.exist?(full_name) raise AssertionError.new("File does not exist: #{full_name}") end contents = File.open(full_name, "rb").read replacements.each do |s1, s2| replacement = "/*{#{s1}}*/" contents = contents.gsub(replacement, s2) end contents end |
.translate_block(block_def_node:, environment_builder:, command_id:, lexical_variables: {}, entire_input_translation: nil, pre_execution: nil, override_block_parameters: nil, block_parameters: nil) ⇒ BlockTranslationResult
Translates a Ruby block to CUDA source code. collecting information about lexical variables (environment) to the block accessed within the block block parameters that this block accepts. ‘translate_entire_input`
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/translator/block_translator.rb', line 54 def translate_block( block_def_node:, environment_builder:, command_id:, lexical_variables: {}, # One one of the two following parameter configurations is valid: # a) Either this parameter is given: entire_input_translation: nil, # b) or these parameters are given (some are optional): pre_execution: nil, override_block_parameters: nil, block_parameters: nil) # Check and prepare arguments if pre_execution != nil and entire_input_translation != nil raise ArgumentError.new("pre_execution and entire_input_translation given") elsif entire_input_translation != nil pre_execution = entire_input_translation.pre_execution elsif pre_execution == nil pre_execution = "" end if block_parameters != nil and entire_input_translation != nil raise ArgumentError.new("block_parameters and entire_input_translation given") elsif entire_input_translation != nil block_parameters = entire_input_translation.block_parameters elsif block_parameters == nil block_parameters = [] end if override_block_parameters != nil and entire_input_translation != nil raise ArgumentError.new("override_block_parameters and entire_input_translation given") elsif entire_input_translation != nil override_block_parameters = entire_input_translation.override_block_parameters elsif override_block_parameters == nil override_block_parameters = block_parameters end # 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("Translating 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) # Translation to source code ast_translator = ASTTranslator.new # Auxiliary methods are instance methods that are called by the block aux_methods = type_inference_visitor.all_methods.map do |method| ast_translator.translate_method(method) end # Generate method predeclarations aux_methods_predecl = type_inference_visitor.all_methods.map do |method| ast_translator.translate_method_predecl(method) end # Start with predeclarations aux_methods = aux_methods_predecl + aux_methods # Classify variables (lexical or local) block_def_node.accept(VariableClassifier.new( lexical_variable_names: lexical_variables.keys)) # Translate to CUDA/C++ code translation_result = ast_translator.translate_block(block_def_node) # Load environment variables lexical_variables.each do |name, value| type = value.ikra_type mangled_name = environment_builder.add_object(name, value) translation_result.prepend("#{type.to_c_type} #{Constants::LEXICAL_VAR_PREFIX}#{name} = #{Constants::ENV_IDENTIFIER}->#{mangled_name};\n") end # Declare local variables block_def_node.local_variables_names_and_types.each do |name, type| translation_result.prepend("#{type.to_c_type} #{name};\n") end # Function signature mangled_name = "_block_k_#{command_id}_" function_parameters = ["environment_t *#{Constants::ENV_IDENTIFIER}"] parameter_decls = override_block_parameters.map do |variable| "#{variable.type.to_c_type} #{variable.name}" end function_parameters.push(*parameter_decls) translation_result = Translator.read_file( file_name: "block_function_head.cpp", replacements: { "name" => mangled_name, "result_type" => return_type.to_c_type, "parameters" => function_parameters.join(", "), "body" => wrap_in_c_block(pre_execution + "\n" + translation_result)}) # TODO: handle more than one result type return BlockTranslationResult.new( c_source: translation_result, result_type: return_type, function_name: mangled_name, aux_methods: aux_methods) end |
.wrap_in_c_block(str) ⇒ Object
48 49 50 |
# File 'lib/translator/translator.rb', line 48 def wrap_in_c_block(str) "{\n" + str.split("\n").map do |line| " " + line end.join("\n") + "\n}\n" end |