Nodecl::NodeclBase handle_task_statements( Nodecl::NodeclBase construct, Nodecl::NodeclBase task_statements, Nodecl::NodeclBase& task_placeholder, // Do not remove the reference TL::Source &new_stmts_src, // It should be a const reference const std::map<TL::Symbol, std::string> &reduction_symbols_map) { if (IS_FORTRAN_LANGUAGE) Source::source_language = SourceLanguage::C; Nodecl::NodeclBase new_statements = new_stmts_src.parse_statement(construct); if (IS_FORTRAN_LANGUAGE) Source::source_language = SourceLanguage::Current; TL::Scope new_scope = ReferenceScope(task_placeholder).get_scope(); std::map<TL::Symbol, Nodecl::NodeclBase> reduction_symbol_to_nodecl_map; for (std::map<TL::Symbol, std::string>::const_iterator it = reduction_symbols_map.begin(); it != reduction_symbols_map.end(); ++it) { TL::Symbol reduction_sym = it->first; std::string storage_name = it->second; TL::Symbol storage_sym = new_scope.get_symbol_from_name(storage_name); ERROR_CONDITION(!storage_sym.is_valid(), "This symbol is not valid", 0); Nodecl::NodeclBase deref_storage = Nodecl::Dereference::make( storage_sym.make_nodecl(/* set_ref_type */ true, storage_sym.get_locus()), storage_sym.get_type().points_to()); reduction_symbol_to_nodecl_map[reduction_sym] = deref_storage; } ReplaceReductionSymbols visitor(reduction_symbol_to_nodecl_map); Nodecl::NodeclBase copied_statements = task_statements.shallow_copy(); visitor.walk(copied_statements); task_placeholder.replace(copied_statements); return new_statements; }
static Symbol create_new_function_opencl_allocate( Nodecl::NodeclBase expr_stmt, Symbol subscripted_symbol, Type element_type, int num_dimensions, bool is_allocatable) { std::string alloca_or_pointer = is_allocatable ? "ALLOCATABLE" : "POINTER"; TL::Source dummy_arguments_bounds, dimension_attr, allocate_dims; dimension_attr << "DIMENSION("; for (int i = 1; i <= num_dimensions; ++i) { if (i != 1) { allocate_dims << ", "; dummy_arguments_bounds <<", "; dimension_attr << ", "; } dummy_arguments_bounds <<"LB" << i <<", " << "UB" << i; dimension_attr << ":"; allocate_dims << "LB" << i << ":" << "UB" << i; } dimension_attr << ")"; size_t size_of_array_descriptor = fortran_size_of_array_descriptor( fortran_get_rank0_type(subscripted_symbol.get_type().get_internal_type()), fortran_get_rank_of_type(subscripted_symbol.get_type().get_internal_type())); TL::Source new_function_name; new_function_name << "NANOX_OPENCL_ALLOCATE_INTERNAL_" << (ptrdiff_t) subscripted_symbol.get_internal_symbol() ; Nodecl::NodeclBase nodecl_body; TL::Source new_function; new_function << "SUBROUTINE " << new_function_name << "(ARR, " << dummy_arguments_bounds << ")\n" << as_type(element_type) << ", " << dimension_attr << ", " << alloca_or_pointer << " :: ARR\n" << as_type(element_type) << ", " << dimension_attr << ", ALLOCATABLE :: TMP\n" << "INTEGER :: " << dummy_arguments_bounds << "\n" << "INTEGER :: ERR \n" << "ALLOCATE(TMP(" << allocate_dims << "))\n" << statement_placeholder(nodecl_body) << "DEALLOCATE(TMP)\n" << "END SUBROUTINE " << new_function_name << "\n" ; Nodecl::NodeclBase function_code = new_function.parse_global(expr_stmt.retrieve_context().get_global_scope()); TL::Scope inside_function = ReferenceScope(nodecl_body).get_scope(); TL::Symbol new_function_sym = inside_function.get_symbol_from_name(strtolower(new_function_name.get_source().c_str())); TL::Symbol arr_sym = inside_function.get_symbol_from_name("arr"); TL::Symbol tmp_sym = inside_function.get_symbol_from_name("tmp"); TL::Symbol ptr_of_arr_sym = get_function_ptr_of(arr_sym, inside_function); TL::Symbol ptr_of_tmp_sym = get_function_ptr_of(tmp_sym, inside_function); TL::Source aux; aux << "ERR = NANOS_MEMCPY(" << ptr_of_arr_sym.get_name() << "(ARR)," << ptr_of_tmp_sym.get_name() << "(TMP)," << "INT(" << size_of_array_descriptor << "," << type_get_size(get_ptrdiff_t_type()) << "))\n" << "CALL NANOS_OPENCL_ALLOCATE_FORTRAN(" << "SIZEOF(TMP)," << ptr_of_arr_sym.get_name() << "(ARR))\n" ; nodecl_body.replace(aux.parse_statement(inside_function)); Nodecl::Utils::prepend_to_enclosing_top_level_location(expr_stmt, function_code); return new_function_sym; }
void LoweringPhase::fortran_preprocess_api(DTO& dto) { ERROR_CONDITION(!IS_FORTRAN_LANGUAGE, "This is only for Fortran", 0); Nodecl::NodeclBase top_level = *std::static_pointer_cast<Nodecl::NodeclBase>(dto["nodecl"]); const char** old_preprocessor_options = CURRENT_CONFIGURATION->preprocessor_options; int num_orig_args = count_null_ended_array((void**)old_preprocessor_options); int num_args = num_orig_args; // -x c num_args += 2; // NULL ended num_args += 1; const char** preprocessor_options = new const char*[num_args]; for (int i = 0; i < num_orig_args; i++) { preprocessor_options[i] = old_preprocessor_options[i]; } // We add -x c since we want /dev/null be preprocessed as an empty C file // FIXME - This is very gcc specific preprocessor_options[num_args - 3] = "-x"; preprocessor_options[num_args - 2] = "c"; preprocessor_options[num_args - 1] = NULL; CURRENT_CONFIGURATION->preprocessor_options = preprocessor_options; const char* output_filename = preprocess_file("/dev/null"); delete[] preprocessor_options; // Restore old flags CURRENT_CONFIGURATION->preprocessor_options = old_preprocessor_options; TL::Source src; std::ifstream preproc_file(output_filename); if (preproc_file.is_open()) { std::string str; while (preproc_file.good()) { std::getline(preproc_file, str); src << str << "\n"; } preproc_file.close(); } else { fatal_error("Could not open Nanos++ include"); } Source::source_language = SourceLanguage::C; Nodecl::NodeclBase new_tree = src.parse_global(top_level); // This is actually a top level tree! new_tree = Nodecl::TopLevel::make(new_tree); // FIXME - keep this? Source::source_language = SourceLanguage::Current; }
void LoweringVisitor::visit(const Nodecl::OpenMP::TaskExpression& task_expr) { Nodecl::NodeclBase join_task = task_expr.get_join_task(); Nodecl::List task_calls = task_expr.get_task_calls().as<Nodecl::List>(); if (!_lowering->final_clause_transformation_disabled() && Nanos::Version::interface_is_at_least("master", 5024)) { ERROR_CONDITION(!task_expr.get_parent().is<Nodecl::ExpressionStatement>(), "Unexpected node", 0); Nodecl::NodeclBase expr_stmt = task_expr.get_parent(); TL::Source code; code << "{" << as_type(TL::Type::get_bool_type()) << "mcc_is_in_final;" << "nanos_err_t mcc_err_in_final = nanos_in_final(&mcc_is_in_final);" << "if (mcc_err_in_final != NANOS_OK) nanos_handle_error(mcc_err_in_final);" << "if (mcc_is_in_final)" << "{" << as_statement(task_expr.get_sequential_code()) << "}" << "else" << "{" << as_statement(Nodecl::ExpressionStatement::make(task_expr)) << "}" << "}" ; std::cout << "In expression\n"; if (IS_FORTRAN_LANGUAGE) Source::source_language = SourceLanguage::C; Nodecl::NodeclBase if_else_tree = code.parse_statement(expr_stmt); if (IS_FORTRAN_LANGUAGE) Source::source_language = SourceLanguage::Current; expr_stmt.replace(if_else_tree); } Nodecl::NodeclBase placeholder_task_expr_transformation; if (join_task.is<Nodecl::OpenMP::Task>()) { // Note: don't walk over the OpenMP::Task node because Its visitor ignores // the placeholder and sets to false the 'inside_task_expression' boolean visit_task( join_task.as<Nodecl::OpenMP::Task>(), /* inside_task_expression */ true, &placeholder_task_expr_transformation); } else if (join_task.is<Nodecl::ExpressionStatement>() && join_task.as<Nodecl::ExpressionStatement>().get_nest().is<Nodecl::OpenMP::TaskCall>()) { visit_task_call( join_task.as<Nodecl::ExpressionStatement>().get_nest().as<Nodecl::OpenMP::TaskCall>(), /* inside_task_expression */ true, &placeholder_task_expr_transformation); } else { internal_error("Unreachable code", 0); } // Note: don't walk over the OpenMP::TaskCall because It's visitor sets to // false the 'inside_task_expression' boolean for (Nodecl::List::iterator it = task_calls.begin(); it != task_calls.end(); ++it) { Nodecl::ExpressionStatement current_expr_stmt = it->as<Nodecl::ExpressionStatement>(); Nodecl::OpenMP::TaskCall current_task_call = current_expr_stmt.get_nest().as<Nodecl::OpenMP::TaskCall>(); visit_task_call(current_task_call, /* inside_task_expression */ true, /* placeholder_task_expr_transformation */ NULL); Nodecl::Utils::prepend_items_before(placeholder_task_expr_transformation, *it); } ERROR_CONDITION(!task_expr.get_parent().is<Nodecl::ExpressionStatement>(), "Unexpected node", 0); Nodecl::NodeclBase expr_stmt = task_expr.get_parent(); Nodecl::Utils::prepend_items_before(expr_stmt, task_expr.get_join_task()); // Finally, remove from the tree the TaskExpression node Nodecl::Utils::remove_from_enclosing_list(expr_stmt); }