User Guide
codegen_helper_visitor.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 Blue Brain Project, EPFL.
3  * See the top-level LICENSE file for details.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #pragma once
9 
10 /**
11  * \file
12  * \brief \copybrief nmodl::codegen::CodegenHelperVisitor
13  */
14 
15 #include <string>
16 
17 #include "codegen/codegen_info.hpp"
18 #include "symtab/symbol_table.hpp"
19 #include "visitors/ast_visitor.hpp"
20 
21 namespace nmodl {
22 namespace codegen {
23 
24 /**
25  * @addtogroup codegen_details
26  * @{
27  */
28 
29 /**
30  * \class CodegenHelperVisitor
31  * \brief Helper visitor to gather AST information to help code generation
32  *
33  * Code generation pass needs various information from AST and symbol
34  * table. Different code generation backends will need this information.
35  * This helper pass visit ast and collect all information into single
36  * class object of CodegenInfo.
37  *
38  * \todo
39  * - Determine `vectorize` as part of the pass
40  * - Determine `threadsafe` as part of the pass
41  * - Global variable order is not preserved, for example, below gives different order:
42  * - NEURON block: GLOBAL gq, gp
43  * - PARAMETER block: gp = 11, gq[2]
44  * - POINTER rng and if it's also assigned rng[4] then it is printed as one value.
45  * Need to check what is correct value.
46  */
48  using SymbolType = std::shared_ptr<symtab::Symbol>;
49  using SymbolVectorType = std::vector<std::shared_ptr<symtab::Symbol>>;
50 
51  /// holds all codegen related information
53 
54  /// Config variable for enabling/disabling CVODE, see `emit_cvode`.
56 
57  /// if visiting net receive block
59 
60  /// if visiting derivative block
61  bool under_derivative_block = false;
62 
63  /// if visiting breakpoint block
64  bool under_breakpoint_block = false;
65 
66  /// table statement found
67  bool table_statement_used = false;
68 
69  /// symbol table for the program
71 
72  /// lhs of assignment in derivative block
73  std::shared_ptr<ast::Expression> assign_lhs;
74 
75  void find_ion_variables(const ast::Program& node);
76  void find_table_variables();
77  void find_range_variables();
80  static void sort_with_mod2c_symbol_order(std::vector<SymbolType>& symbols);
81  void check_cvode_codegen(const ast::Program& node);
82 
83  public:
86 
87  /// run visitor and return information for code generation
89 
90  void visit_electrode_current(const ast::ElectrodeCurrent& node) override;
91  void visit_suffix(const ast::Suffix& node) override;
92  void visit_function_call(const ast::FunctionCall& node) override;
93  void visit_binary_expression(const ast::BinaryExpression& node) override;
94  void visit_conductance_hint(const ast::ConductanceHint& node) override;
95  void visit_procedure_block(const ast::ProcedureBlock& node) override;
96  void visit_function_block(const ast::FunctionBlock& node) override;
97  void visit_function_table_block(const ast::FunctionTableBlock& node) override;
100  void visit_statement_block(const ast::StatementBlock& node) override;
101  void visit_initial_block(const ast::InitialBlock& node) override;
102  void visit_constructor_block(const ast::ConstructorBlock& node) override;
103  void visit_destructor_block(const ast::DestructorBlock& node) override;
104  void visit_breakpoint_block(const ast::BreakpointBlock& node) override;
105  void visit_derivative_block(const ast::DerivativeBlock& node) override;
106  void visit_derivimplicit_callback(const ast::DerivimplicitCallback& node) override;
107  void visit_net_receive_block(const ast::NetReceiveBlock& node) override;
108  void visit_bbcore_pointer(const ast::BbcorePointer& node) override;
109  void visit_thread_safe(const ast::ThreadSafe&) override;
110  void visit_watch(const ast::Watch& node) override;
111  void visit_watch_statement(const ast::WatchStatement& node) override;
112  void visit_for_netcon(const ast::ForNetcon& node) override;
113  void visit_table_statement(const ast::TableStatement& node) override;
114  void visit_program(const ast::Program& node) override;
115  void visit_factor_def(const ast::FactorDef& node) override;
116  void visit_nrn_state_block(const ast::NrnStateBlock& node) override;
117  void visit_cvode_block(const ast::CvodeBlock& node) override;
118  void visit_linear_block(const ast::LinearBlock& node) override;
119  void visit_non_linear_block(const ast::NonLinearBlock& node) override;
120  void visit_discrete_block(const ast::DiscreteBlock& node) override;
121  void visit_update_dt(const ast::UpdateDt& node) override;
122  void visit_verbatim(const ast::Verbatim& node) override;
123  void visit_before_block(const ast::BeforeBlock& node) override;
124  void visit_after_block(const ast::AfterBlock& node) override;
126 };
127 
128 /** @} */ // end of codegen_details
129 
130 } // namespace codegen
131 } // namespace nmodl
nmodl::codegen::CodegenHelperVisitor::under_derivative_block
bool under_derivative_block
if visiting derivative block
Definition: codegen_helper_visitor.hpp:61
nmodl::ast::BeforeBlock
Represents a BEFORE block in NMODL.
Definition: before_block.hpp:38
nmodl::ast::Verbatim
Represents a C code block.
Definition: verbatim.hpp:38
nmodl::codegen::CodegenHelperVisitor::visit_eigen_newton_solver_block
void visit_eigen_newton_solver_block(const ast::EigenNewtonSolverBlock &node) override
visit node of type ast::EigenNewtonSolverBlock
Definition: codegen_helper_visitor.cpp:664
nmodl::codegen::CodegenHelperVisitor::visit_eigen_linear_solver_block
void visit_eigen_linear_solver_block(const ast::EigenLinearSolverBlock &node) override
visit node of type ast::EigenLinearSolverBlock
Definition: codegen_helper_visitor.cpp:677
nmodl::codegen::CodegenHelperVisitor::find_neuron_global_variables
void find_neuron_global_variables()
Definition: codegen_helper_visitor.cpp:547
nmodl::codegen::CodegenHelperVisitor::check_cvode_codegen
void check_cvode_codegen(const ast::Program &node)
Find whether or not we need to emit CVODE-related code for NEURON Notes: we generate CVODE-related co...
Definition: codegen_helper_visitor.cpp:185
nmodl::codegen::CodegenHelperVisitor::visit_breakpoint_block
void visit_breakpoint_block(const ast::BreakpointBlock &node) override
visit node of type ast::BreakpointBlock
Definition: codegen_helper_visitor.cpp:620
nmodl::visitor::ConstAstVisitor
Concrete constant visitor for all AST classes.
Definition: ast_visitor.hpp:168
nmodl::codegen::CodegenHelperVisitor::visit_update_dt
void visit_update_dt(const ast::UpdateDt &node) override
visit node of type ast::UpdateDt
Definition: codegen_helper_visitor.cpp:838
nmodl::ast::FactorDef
TODO.
Definition: factor_def.hpp:38
nmodl::codegen::CodegenHelperVisitor::visit_conductance_hint
void visit_conductance_hint(const ast::ConductanceHint &node) override
visit node of type ast::ConductanceHint
Definition: codegen_helper_visitor.cpp:694
nmodl::ast::Watch
TODO.
Definition: watch.hpp:38
nmodl::ast::FunctionBlock
TODO.
Definition: function_block.hpp:39
nmodl::ast::NetReceiveBlock
TODO.
Definition: net_receive_block.hpp:39
nmodl::codegen::CodegenHelperVisitor::visit_destructor_block
void visit_destructor_block(const ast::DestructorBlock &node) override
visit node of type ast::DestructorBlock
Definition: codegen_helper_visitor.cpp:594
nmodl::codegen::CodegenHelperVisitor::table_statement_used
bool table_statement_used
table statement found
Definition: codegen_helper_visitor.hpp:67
nmodl::ast::FunctionTableBlock
TODO.
Definition: function_table_block.hpp:39
nmodl::codegen::CodegenHelperVisitor::psymtab
symtab::SymbolTable * psymtab
symbol table for the program
Definition: codegen_helper_visitor.hpp:70
nmodl::codegen::CodegenHelperVisitor::visit_electrode_current
void visit_electrode_current(const ast::ElectrodeCurrent &node) override
visit node of type ast::ElectrodeCurrent
Definition: codegen_helper_visitor.cpp:573
nmodl::ast::ConductanceHint
Represents CONDUCTANCE statement in NMODL.
Definition: conductance_hint.hpp:46
nmodl::codegen::CodegenHelperVisitor::SymbolVectorType
std::vector< std::shared_ptr< symtab::Symbol > > SymbolVectorType
Definition: codegen_helper_visitor.hpp:49
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
nmodl::codegen::CodegenHelperVisitor::visit_program
void visit_program(const ast::Program &node) override
visit node of type ast::Program
Definition: codegen_helper_visitor.cpp:802
nmodl::codegen::CodegenHelperVisitor::visit_function_block
void visit_function_block(const ast::FunctionBlock &node) override
visit node of type ast::FunctionBlock
Definition: codegen_helper_visitor.cpp:649
nmodl::codegen::CodegenHelperVisitor::CodegenHelperVisitor
CodegenHelperVisitor(bool enable_cvode=false)
Definition: codegen_helper_visitor.hpp:84
nmodl::codegen::CodegenHelperVisitor::SymbolType
std::shared_ptr< symtab::Symbol > SymbolType
Definition: codegen_helper_visitor.hpp:48
nmodl::codegen::CodegenHelperVisitor::visit_discrete_block
void visit_discrete_block(const ast::DiscreteBlock &node) override
visit node of type ast::DiscreteBlock
Definition: codegen_helper_visitor.cpp:834
nmodl::ast::CvodeBlock
Represents a block used for variable timestep integration (CVODE) of DERIVATIVE blocks.
Definition: cvode_block.hpp:38
symbol_table.hpp
Implement classes for representing symbol table at block and file scope.
nmodl::codegen::CodegenHelperVisitor::visit_function_call
void visit_function_call(const ast::FunctionCall &node) override
visit node of type ast::FunctionCall
Definition: codegen_helper_visitor.cpp:683
nmodl::ast::TableStatement
Represents TABLE statement in NMODL.
Definition: table_statement.hpp:39
nmodl::ast::Suffix
Represents SUFFIX statement in NMODL.
Definition: suffix.hpp:38
nmodl::codegen::CodegenHelperVisitor::visit_factor_def
void visit_factor_def(const ast::FactorDef &node) override
visit node of type ast::FactorDef
Definition: codegen_helper_visitor.cpp:757
nmodl::codegen::CodegenInfo
Represent information collected from AST for code generation.
Definition: codegen_info.hpp:335
nmodl::codegen::CodegenHelperVisitor::visit_for_netcon
void visit_for_netcon(const ast::ForNetcon &node) override
visit node of type ast::ForNetcon
Definition: codegen_helper_visitor.cpp:791
nmodl::codegen::CodegenHelperVisitor::visit_binary_expression
void visit_binary_expression(const ast::BinaryExpression &node) override
visit node of type ast::BinaryExpression
Definition: codegen_helper_visitor.cpp:762
nmodl::ast::EigenNewtonSolverBlock
Represent newton solver solution block based on Eigen.
Definition: eigen_newton_solver_block.hpp:38
nmodl::codegen::CodegenHelperVisitor::visit_statement_block
void visit_statement_block(const ast::StatementBlock &node) override
Visit statement block and find prime symbols appear in derivative block.
Definition: codegen_helper_visitor.cpp:726
nmodl::ast::InitialBlock
Represents a INITIAL block in the NMODL.
Definition: initial_block.hpp:49
nmodl::ast::DiscreteBlock
TODO.
Definition: discrete_block.hpp:38
nmodl::ast::WatchStatement
Represent WATCH statement in NMODL.
Definition: watch_statement.hpp:39
nmodl::ast::BreakpointBlock
Represents a BREAKPOINT block in NMODL.
Definition: breakpoint_block.hpp:53
nmodl::ast::FunctionCall
TODO.
Definition: function_call.hpp:38
nmodl::codegen::CodegenHelperVisitor::visit_cvode_block
void visit_cvode_block(const ast::CvodeBlock &node) override
visit node of type ast::CvodeBlock
Definition: codegen_helper_visitor.cpp:633
nmodl::codegen::CodegenHelperVisitor::visit_table_statement
void visit_table_statement(const ast::TableStatement &node) override
visit node of type ast::TableStatement
Definition: codegen_helper_visitor.cpp:796
nmodl::ast::DestructorBlock
Represents a DESTRUCTOR block in the NMODL.
Definition: destructor_block.hpp:53
nmodl::codegen::CodegenHelperVisitor::under_breakpoint_block
bool under_breakpoint_block
if visiting breakpoint block
Definition: codegen_helper_visitor.hpp:64
nmodl::ast::ConstructorBlock
Represents a CONSTRUCTOR block in the NMODL.
Definition: constructor_block.hpp:51
nmodl::codegen::CodegenHelperVisitor::visit_non_linear_block
void visit_non_linear_block(const ast::NonLinearBlock &node) override
visit node of type ast::NonLinearBlock
Definition: codegen_helper_visitor.cpp:830
nmodl::ast::LongitudinalDiffusionBlock
Extracts information required for LONGITUDINAL_DIFFUSION for each KINETIC block.
Definition: longitudinal_diffusion_block.hpp:38
nmodl::codegen::CodegenHelperVisitor::visit_after_block
void visit_after_block(const ast::AfterBlock &node) override
visit node of type ast::AfterBlock
Definition: codegen_helper_visitor.cpp:863
nmodl::codegen::CodegenHelperVisitor::find_range_variables
void find_range_variables()
Find range variables i.e.
Definition: codegen_helper_visitor.cpp:423
nmodl::codegen::CodegenHelperVisitor::visit_watch
void visit_watch(const ast::Watch &node) override
visit node of type ast::Watch
Definition: codegen_helper_visitor.cpp:780
nmodl::codegen::CodegenHelperVisitor::sort_with_mod2c_symbol_order
static void sort_with_mod2c_symbol_order(std::vector< SymbolType > &symbols)
How symbols are stored in NEURON? See notes written in markdown file.
Definition: codegen_helper_visitor.cpp:68
nmodl::codegen::CodegenHelperVisitor::visit_watch_statement
void visit_watch_statement(const ast::WatchStatement &node) override
visit node of type ast::WatchStatement
Definition: codegen_helper_visitor.cpp:785
nmodl::codegen::CodegenHelperVisitor::visit_procedure_block
void visit_procedure_block(const ast::ProcedureBlock &node) override
visit node of type ast::ProcedureBlock
Definition: codegen_helper_visitor.cpp:639
nmodl::codegen::CodegenHelperVisitor::visit_before_block
void visit_before_block(const ast::BeforeBlock &node) override
visit node of type ast::BeforeBlock
Definition: codegen_helper_visitor.cpp:859
nmodl::ast::DerivativeBlock
Represents DERIVATIVE block in the NMODL.
Definition: derivative_block.hpp:49
codegen_info.hpp
Various types to store code generation specific information.
nmodl::symtab::SymbolTable
Represent symbol table for a NMODL block.
Definition: symbol_table.hpp:57
nmodl::codegen::CodegenHelperVisitor::analyze
codegen::CodegenInfo analyze(const ast::Program &node)
run visitor and return information for code generation
Definition: codegen_helper_visitor.cpp:821
nmodl::ast::EigenLinearSolverBlock
Represent linear solver solution block based on Eigen.
Definition: eigen_linear_solver_block.hpp:38
nmodl::ast::UpdateDt
Statement to indicate a change in timestep in a given block.
Definition: update_dt.hpp:38
nmodl::codegen::CodegenHelperVisitor::visit_net_receive_block
void visit_net_receive_block(const ast::NetReceiveBlock &node) override
visit node of type ast::NetReceiveBlock
Definition: codegen_helper_visitor.cpp:600
nmodl::codegen::CodegenHelperVisitor::assign_lhs
std::shared_ptr< ast::Expression > assign_lhs
lhs of assignment in derivative block
Definition: codegen_helper_visitor.hpp:73
nmodl::codegen::CodegenHelperVisitor::find_table_variables
void find_table_variables()
Definition: codegen_helper_visitor.cpp:540
nmodl::ast::NrnStateBlock
Represents the coreneuron nrn_state callback function.
Definition: nrn_state_block.hpp:39
nmodl::ast::StatementBlock
Represents block encapsulating list of statements.
Definition: statement_block.hpp:53
nmodl::ast::ForNetcon
TODO.
Definition: for_netcon.hpp:39
nmodl::codegen::CodegenHelperVisitor::visit_thread_safe
void visit_thread_safe(const ast::ThreadSafe &) override
visit node of type ast::ThreadSafe
Definition: codegen_helper_visitor.cpp:775
nmodl::codegen::CodegenHelperVisitor::visit_longitudinal_diffusion_block
void visit_longitudinal_diffusion_block(const ast::LongitudinalDiffusionBlock &node) override
visit node of type ast::LongitudinalDiffusionBlock
Definition: codegen_helper_visitor.cpp:887
nmodl::codegen::CodegenHelperVisitor::visit_linear_block
void visit_linear_block(const ast::LinearBlock &node) override
visit node of type ast::LinearBlock
Definition: codegen_helper_visitor.cpp:826
nmodl::ast::LinearBlock
Represents LINEAR block in the NMODL.
Definition: linear_block.hpp:53
nmodl::ast::DerivimplicitCallback
Represent a callback to NEURON's derivimplicit solver.
Definition: derivimplicit_callback.hpp:38
nmodl::ast::ProcedureBlock
TODO.
Definition: procedure_block.hpp:39
nmodl::codegen::CodegenHelperVisitor::find_non_range_variables
void find_non_range_variables()
Find non-range variables i.e.
Definition: codegen_helper_visitor.cpp:237
nmodl::codegen::CodegenHelperVisitor::visit_derivimplicit_callback
void visit_derivimplicit_callback(const ast::DerivimplicitCallback &node) override
visit node of type ast::DerivimplicitCallback
Definition: codegen_helper_visitor.cpp:615
nmodl::codegen::CodegenHelperVisitor::find_ion_variables
void find_ion_variables(const ast::Program &node)
Find all ions used in mod file.
Definition: codegen_helper_visitor.cpp:89
nmodl::ast::NonLinearBlock
Represents NONLINEAR block in the NMODL.
Definition: non_linear_block.hpp:50
nmodl::codegen::CodegenHelperVisitor::visit_derivative_block
void visit_derivative_block(const ast::DerivativeBlock &node) override
visit node of type ast::DerivativeBlock
Definition: codegen_helper_visitor.cpp:609
nmodl::codegen::CodegenHelperVisitor::visit_function_table_block
void visit_function_table_block(const ast::FunctionTableBlock &node) override
visit node of type ast::FunctionTableBlock
Definition: codegen_helper_visitor.cpp:659
nmodl::codegen::CodegenHelperVisitor
Helper visitor to gather AST information to help code generation.
Definition: codegen_helper_visitor.hpp:47
nmodl::codegen::CodegenHelperVisitor::visit_bbcore_pointer
void visit_bbcore_pointer(const ast::BbcorePointer &node) override
visit node of type ast::BbcorePointer
Definition: codegen_helper_visitor.cpp:771
nmodl::codegen::CodegenHelperVisitor::visit_verbatim
void visit_verbatim(const ast::Verbatim &node) override
visit verbatim block and find all symbols used
Definition: codegen_helper_visitor.cpp:843
nmodl::ast::BbcorePointer
Represents BBCOREPOINTER statement in NMODL.
Definition: bbcore_pointer.hpp:47
nmodl::codegen::CodegenHelperVisitor::under_net_receive_block
bool under_net_receive_block
if visiting net receive block
Definition: codegen_helper_visitor.hpp:58
nmodl::codegen::CodegenHelperVisitor::enable_cvode
bool enable_cvode
Config variable for enabling/disabling CVODE, see emit_cvode.
Definition: codegen_helper_visitor.hpp:55
nmodl::ast::Program
Represents top level AST node for whole NMODL input.
Definition: program.hpp:39
nmodl::ast::AfterBlock
Represents a AFTER block in NMODL.
Definition: after_block.hpp:51
nmodl::ast::ThreadSafe
Represents THREADSAFE statement in NMODL.
Definition: thread_safe.hpp:38
nmodl::ast::ElectrodeCurrent
Represents ELECTRODE_CURRENT variables statement in NMODL.
Definition: electrode_current.hpp:39
nmodl::codegen::CodegenHelperVisitor::visit_initial_block
void visit_initial_block(const ast::InitialBlock &node) override
visit node of type ast::InitialBlock
Definition: codegen_helper_visitor.cpp:578
nmodl::codegen::CodegenHelperVisitor::visit_nrn_state_block
void visit_nrn_state_block(const ast::NrnStateBlock &node) override
visit node of type ast::NrnStateBlock
Definition: codegen_helper_visitor.cpp:628
nmodl::ast::BinaryExpression
Represents binary expression in the NMODL.
Definition: binary_expression.hpp:52
nmodl::codegen::CodegenHelperVisitor::info
codegen::CodegenInfo info
holds all codegen related information
Definition: codegen_helper_visitor.hpp:52
nmodl::codegen::CodegenHelperVisitor::visit_constructor_block
void visit_constructor_block(const ast::ConstructorBlock &node) override
visit node of type ast::ConstructorBlock
Definition: codegen_helper_visitor.cpp:588
nmodl::codegen::CodegenHelperVisitor::visit_suffix
void visit_suffix(const ast::Suffix &node) override
visit node of type ast::Suffix
Definition: codegen_helper_visitor.cpp:561
ast_visitor.hpp
Concrete visitor for all AST classes.