diff --git a/src/codegen/codegen_coreneuron_cpp_visitor.cpp b/src/codegen/codegen_coreneuron_cpp_visitor.cpp index dfe26b1c1..850d52cc1 100644 --- a/src/codegen/codegen_coreneuron_cpp_visitor.cpp +++ b/src/codegen/codegen_coreneuron_cpp_visitor.cpp @@ -218,41 +218,6 @@ void CodegenCoreneuronCppVisitor::print_net_init_acc_serial_annotation_block_end } -/** - * \details Depending programming model and compiler, we print compiler hint - * for parallelization. For example: - * - * \code - * #pragma omp simd - * for(int id = 0; id < nodecount; id++) { - * - * #pragma acc parallel loop - * for(int id = 0; id < nodecount; id++) { - * \endcode - */ -void CodegenCoreneuronCppVisitor::print_channel_iteration_block_parallel_hint( - BlockType /* type */, - const ast::Block* block) { - // ivdep allows SIMD parallelisation of a block/loop but doesn't provide - // a standard mechanism for atomics. Also, even with openmp 5.0, openmp - // atomics do not enable vectorisation under "omp simd" (gives compiler - // error with gcc < 9 if atomic and simd pragmas are nested). So, emit - // ivdep/simd pragma when no MUTEXLOCK/MUTEXUNLOCK/PROTECT statements - // are used in the given block. - std::vector> nodes; - if (block) { - nodes = collect_nodes(*block, - {ast::AstNodeType::PROTECT_STATEMENT, - ast::AstNodeType::MUTEX_LOCK, - ast::AstNodeType::MUTEX_UNLOCK}); - } - if (nodes.empty()) { - printer->add_line("#pragma omp simd"); - printer->add_line("#pragma ivdep"); - } -} - - bool CodegenCoreneuronCppVisitor::nrn_cur_reduction_loop_required() { return info.point_process; } diff --git a/src/codegen/codegen_coreneuron_cpp_visitor.hpp b/src/codegen/codegen_coreneuron_cpp_visitor.hpp index dc67cca21..989374e00 100644 --- a/src/codegen/codegen_coreneuron_cpp_visitor.hpp +++ b/src/codegen/codegen_coreneuron_cpp_visitor.hpp @@ -201,23 +201,6 @@ class CodegenCoreneuronCppVisitor: public CodegenCppVisitor { virtual void print_net_init_acc_serial_annotation_block_end(); - /** - * Print pragma annotations for channel iterations - * - * This can be overriden by backends to provide additonal annotations or pragmas to enable - * for example SIMD code generation (e.g. through \c ivdep) - * The default implementation prints - * - * \code - * #pragma ivdep - * \endcode - * - * \param type The block type - */ - virtual void print_channel_iteration_block_parallel_hint(BlockType type, - const ast::Block* block); - - /** * Check if reduction block in \c nrn\_cur required */ diff --git a/src/codegen/codegen_cpp_visitor.cpp b/src/codegen/codegen_cpp_visitor.cpp index 7c824b67f..88db19241 100644 --- a/src/codegen/codegen_cpp_visitor.cpp +++ b/src/codegen/codegen_cpp_visitor.cpp @@ -377,6 +377,41 @@ std::string CodegenCppVisitor::breakpoint_current(std::string current) const { return current; } + +/** + * \details Depending programming model and compiler, we print compiler hint + * for parallelization. For example: + * + * \code + * #pragma omp simd + * for(int id = 0; id < nodecount; id++) { + * + * #pragma acc parallel loop + * for(int id = 0; id < nodecount; id++) { + * \endcode + */ +void CodegenCppVisitor::print_channel_iteration_block_parallel_hint(BlockType /* type */, + const ast::Block* block) { + // ivdep allows SIMD parallelisation of a block/loop but doesn't provide + // a standard mechanism for atomics. Also, even with openmp 5.0, openmp + // atomics do not enable vectorisation under "omp simd" (gives compiler + // error with gcc < 9 if atomic and simd pragmas are nested). So, emit + // ivdep/simd pragma when no MUTEXLOCK/MUTEXUNLOCK/PROTECT statements + // are used in the given block. + std::vector> nodes; + if (block) { + nodes = collect_nodes(*block, + {ast::AstNodeType::PROTECT_STATEMENT, + ast::AstNodeType::MUTEX_LOCK, + ast::AstNodeType::MUTEX_UNLOCK}); + } + if (nodes.empty()) { + printer->add_line("#pragma omp simd"); + printer->add_line("#pragma ivdep"); + } +} + + /****************************************************************************************/ /* Routines for returning variable name */ /****************************************************************************************/ diff --git a/src/codegen/codegen_cpp_visitor.hpp b/src/codegen/codegen_cpp_visitor.hpp index 986dedbff..86d1ba6f7 100644 --- a/src/codegen/codegen_cpp_visitor.hpp +++ b/src/codegen/codegen_cpp_visitor.hpp @@ -791,6 +791,23 @@ class CodegenCppVisitor: public visitor::ConstAstVisitor { std::string breakpoint_current(std::string current) const; + /** + * Print pragma annotations for channel iterations + * + * This can be overriden by backends to provide additonal annotations or pragmas to enable + * for example SIMD code generation (e.g. through \c ivdep) + * The default implementation prints + * + * \code + * #pragma ivdep + * \endcode + * + * \param type The block type + */ + virtual void print_channel_iteration_block_parallel_hint(BlockType type, + const ast::Block* block); + + /****************************************************************************************/ /* Backend specific routines */ /****************************************************************************************/