NEURON
codegen_neuron_cpp_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  * \dir
12  * \brief Code generation backend implementations for NEURON
13  *
14  * \file
15  * \brief \copybrief nmodl::codegen::CodegenNeuronCppVisitor
16  */
17 
18 #include <algorithm>
19 #include <cmath>
20 #include <ctime>
21 #include <numeric>
22 #include <ostream>
23 #include <string>
24 #include <string_view>
25 #include <utility>
26 
27 #include "ast/function_block.hpp"
28 #include "ast/procedure_block.hpp"
30 #include "codegen/codegen_info.hpp"
32 #include "printer/code_printer.hpp"
33 #include "symtab/symbol_table.hpp"
34 #include "utils/logger.hpp"
35 #include "visitors/ast_visitor.hpp"
36 
37 
38 /// encapsulates code generation backend implementations
39 namespace nmodl {
40 
41 namespace codegen {
42 
43 
44 using printer::CodePrinter;
45 
46 
47 /**
48  * @brief Enum to switch between HOC and Python wrappers for functions and
49  * procedures defined in mechanisms
50  *
51  */
53 
54 
55 /**
56  * \defgroup codegen_backends Codegen Backends
57  * \ingroup codegen
58  * \brief Code generation backends for NEURON
59  * \{
60  */
61 
63  const std::shared_ptr<symtab::Symbol> symbol;
64 
65  /** There `index` global variables ahead of this one. If one counts array
66  * global variables as one variable.
67  */
68  size_t index;
69 
70  /** The global variables ahead of this one require `offset` doubles to
71  * store.
72  */
73  size_t offset;
74 };
75 
76 inline std::string get_name(const ThreadVariableInfo& var) {
77  return var.symbol->get_name();
78 }
79 
80 
81 /**
82  * \class CodegenNeuronCppVisitor
83  * \brief %Visitor for printing C++ code compatible with legacy api of NEURON
84  *
85  * \todo
86  * - Handle define statement (i.e. macros)
87  * - If there is a return statement in the verbatim block
88  * of inlined function then it will be error. Need better
89  * error checking. For example, see netstim.mod where we
90  * have removed return from verbatim block.
91  */
93  public:
95 
96  protected:
97  /****************************************************************************************/
98  /* Member variables */
99  /****************************************************************************************/
100 
101  /**
102  * GLOBAL variables in THREADSAFE MOD files that are not read-only are
103  * converted to thread variables. This is the list of all such variables.
104  */
105  std::vector<ThreadVariableInfo> codegen_thread_variables;
106 
107 
108  /****************************************************************************************/
109  /* Generic information getters */
110  /****************************************************************************************/
111 
112 
113  /**
114  * Name of the simulator the code was generated for
115  */
116  std::string simulator_name() override;
117 
118 
119  /**
120  * Name of the code generation backend
121  */
122  std::string backend_name() const override;
123 
124  /**
125  * Name of the threaded table checking function
126  */
127  std::string table_thread_function_name() const;
128 
129  bool needs_v_unused() const override;
130 
131  /****************************************************************************************/
132  /* Common helper routines accross codegen functions */
133  /****************************************************************************************/
134 
135 
136  /**
137  * Determine the position in the data array for a given float variable
138  * \param name The name of a float variable
139  * \return The position index in the data array
140  */
141  int position_of_float_var(const std::string& name) const override;
142 
143 
144  /**
145  * Determine the position in the data array for a given int variable
146  * \param name The name of an int variable
147  * \return The position index in the data array
148  */
149  int position_of_int_var(const std::string& name) const override;
150 
151 
152  /****************************************************************************************/
153  /* Backend specific routines */
154  /****************************************************************************************/
155 
156  /**
157  * Check if ion variable copies should be avoided
158  */
159  bool optimize_ion_variable_copies() const override;
160 
161  /****************************************************************************************/
162  /* Printing routines for code generation */
163  /****************************************************************************************/
164 
165  /**
166  * Print NET_RECEIVE{ INITIAL{ ... }} block.
167  */
168  void print_net_init();
169 
170  /**
171  * Print call to \c net\_send
172  * \param node The AST node representing the function call
173  */
174  void print_net_send_call(const ast::FunctionCall& node) override;
175 
176 
177  /**
178  * Print call to net\_move
179  * \param node The AST node representing the function call
180  */
181  void print_net_move_call(const ast::FunctionCall& node) override;
182 
183 
184  /**
185  * Print call to net\_event
186  * \param node The AST node representing the function call
187  */
188  void print_net_event_call(const ast::FunctionCall& node) override;
189 
190  void print_function_table_call(const ast::FunctionCall& node) override;
191 
192  /**
193  * Print `net_receive` call-back.
194  */
195  void print_net_receive();
198 
199  /**
200  * Print code to register the call-back for the NET_RECEIVE block.
201  */
203 
204  /**
205  * Print POINT_PROCESS related functions
206  * Wrap external NEURON functions related to POINT_PROCESS mechanisms
207  *
208  */
210 
211  /**
212  * Print NEURON functions related to setting global variables of the mechanism
213  *
214  */
216 
217 
218  /**
219  * Print function and procedures prototype declaration
220  */
221  void print_function_prototypes() override;
222 
223 
224  /**
225  * Print function and procedures prototype definitions.
226  *
227  * This includes the HOC/Python wrappers.
228  */
230 
231 
232  /**
233  * Print all `check_*` function declarations
234  */
236 
237 
239  const std::string& name,
240  const std::unordered_set<CppObjectSpecifier>& specifiers = {
241  CppObjectSpecifier::Inline}) override;
242 
243 
244  /**
245  * Common helper function to help printing function or procedure blocks
246  * \param node the AST node representing the function or procedure in NMODL
247  */
248  void print_function_procedure_helper(const ast::Block& node) override;
249 
250 
251  /** Print the wrapper for calling FUNCION/PROCEDURES from HOC/Py.
252  *
253  * Usually the function is made up of the following parts:
254  * * Print setup code `inst`, etc.
255  * * Print code to call the function and return.
256  */
257  void print_hoc_py_wrapper(const ast::Block* function_or_procedure_block,
258  InterpreterWrapper wrapper_type);
259 
260  /** Print the setup code for HOC/Py wrapper.
261  */
262  void print_hoc_py_wrapper_setup(const ast::Block* function_or_procedure_block,
263  InterpreterWrapper wrapper_type);
264 
265 
266  /** Print the code that calls the impl from the HOC/Py wrapper.
267  */
268  void print_hoc_py_wrapper_call_impl(const ast::Block* function_or_procedure_block,
269  InterpreterWrapper wrapper_type);
270 
271  /** Return the wrapper signature.
272  *
273  * Everything without the `{` or `;`. Roughly, as an example:
274  * <return_type> <function_name>(<internal_args>, <args>)
275  *
276  * were `<internal_args> is the list of arguments required by the
277  * codegen to be passed along, while <args> are the arguments of
278  * of the function as they appear in the MOD file.
279  */
280  std::string hoc_py_wrapper_signature(const ast::Block* function_or_procedure_block,
281  InterpreterWrapper wrapper_type);
282 
284 
285  /**
286  * Prints the callbacks required for LONGITUDINAL_DIFFUSION.
287  */
289 
290  /**
291  * Parameters for what NEURON calls `ldifusfunc1_t`.
292  */
294 
295  /**
296  * Parameters for what NEURON calls `ldifusfunc3_t`.
297  */
299 
300 
301  /****************************************************************************************/
302  /* Code-specific helper routines */
303  /****************************************************************************************/
304 
305  void add_variable_tqitem(std::vector<IndexVariableInfo>& variables) override;
306  void add_variable_point_process(std::vector<IndexVariableInfo>& variables) override;
307 
308  /**
309  * Arguments for functions that are defined and used internally.
310  * \return the method arguments
311  */
312  std::string internal_method_arguments() override;
313 
314 
315  /**
316  * Parameters for internally defined functions
317  * \return the method parameters
318  */
320 
321 
322  /**
323  * Arguments for external functions called from generated code
324  * \return A string representing the arguments passed to an external function
325  */
326  const std::string external_method_arguments() noexcept override;
327 
328 
329  /**
330  * Parameters for functions in generated code that are called back from external code
331  *
332  * Functions registered in NEURON during initialization for callback must adhere to a prescribed
333  * calling convention. This method generates the string representing the function parameters for
334  * these externally called functions.
335  * \param table
336  * \return A string representing the parameters of the function
337  */
338  const ParamVector external_method_parameters(bool table = false) noexcept override;
339 
340 
341  /** The parameters for the four macros `_internalthreadargs*_`. */
343 
344 
345  /** The parameters for the four macros `_threadargs*_`. */
347 
348 
349  /**
350  * Arguments for "_threadargs_" macro in neuron implementation
351  */
352  std::string nrn_thread_arguments() const override;
353 
354 
355  /**
356  * Arguments for "_threadargs_" macro in neuron implementation
357  */
358  std::string nrn_thread_internal_arguments() override;
359 
361  const ast::FunctionTableBlock& /* node */) override;
362 
363 
364  /** Print compatibility macros required for VERBATIM blocks.
365  *
366  * Returns the names of all macros introduced.
367  */
368  std::vector<std::string> print_verbatim_setup(const ast::Verbatim& node,
369  const std::string& verbatim);
370 
371 
372  /** Print `#undef`s to erase all compatibility macros.
373  */
374  void print_verbatim_cleanup(const std::vector<std::string>& macros_defined);
375 
376 
377  /**
378  * Arguments for register_mech or point_register_mech function
379  */
380  std::string register_mechanism_arguments() const override;
381 
382 
383  void append_conc_write_statements(std::vector<ShadowUseStatement>& statements,
384  const Ion& ion,
385  const std::string& concentration) override;
386 
387  /**
388  * All functions and procedures need a \c _hoc_<func_or_proc_name> to be available to the HOC
389  * interpreter
390  */
391  std::string hoc_function_name(const std::string& function_or_procedure_name) const;
392 
393 
394  /**
395  * Get the signature of the \c _hoc_<func_or_proc_name> function
396  */
397  std::string hoc_function_signature(const std::string& function_or_procedure_name) const;
398 
399 
400  /**
401  * In non POINT_PROCESS mechanisms all functions and procedures need a \c
402  * _py_<func_or_proc_name> to be available to the HOC interpreter
403  */
404  std::string py_function_name(const std::string& function_or_procedure_name) const;
405 
406  /**
407  * Get the signature of the \c _npy_<func_or_proc_name> function
408  */
409  std::string py_function_signature(const std::string& function_or_procedure_name) const;
410 
411 
412  /****************************************************************************************/
413  /* Code-specific printing routines for code generations */
414  /****************************************************************************************/
415 
416 
417  std::string namespace_name() override;
418 
419 
420  /****************************************************************************************/
421  /* Routines for returning variable name */
422  /****************************************************************************************/
423 
424 
425  /**
426  * Determine the name of a \c float variable given its symbol
427  *
428  * This function typically returns the accessor expression in backend code for the given symbol.
429  * Since the model variables are stored in data arrays and accessed by offset, this function
430  * will return the C++ string representing the array access at the correct offset
431  *
432  * \param symbol The symbol of a variable for which we want to obtain its name
433  * \param use_instance Should the variable be accessed via instance or data array
434  * \return The backend code string representing the access to the given variable
435  * symbol
436  */
437  std::string float_variable_name(const SymbolType& symbol, bool use_instance) const override;
438 
439 
440  /**
441  * Determine the name of an \c int variable given its symbol
442  *
443  * This function typically returns the accessor expression in backend code for the given symbol.
444  * Since the model variables are stored in data arrays and accessed by offset, this function
445  * will return the C++ string representing the array access at the correct offset
446  *
447  * \param symbol The symbol of a variable for which we want to obtain its name
448  * \param name The name of the index variable
449  * \param use_instance Should the variable be accessed via instance or data array
450  * \return The backend code string representing the access to the given variable
451  * symbol
452  */
453  std::string int_variable_name(const IndexVariableInfo& symbol,
454  const std::string& name,
455  bool use_instance) const override;
456 
457 
458  /**
459  * Determine the variable name for a global variable given its symbol
460  * \param symbol The symbol of a variable for which we want to obtain its name
461  * \param use_instance Should the variable be accessed via the (host-only)
462  * global variable or the instance-specific copy (also available on GPU).
463  * \return The C++ string representing the access to the global variable
464  */
465  std::string global_variable_name(const SymbolType& symbol,
466  bool use_instance = true) const override;
467 
468 
469  /**
470  * Determine the C++ string to print for thread variables.
471  *
472  * \param var_info Identifies the thread variable, typically an instance of
473  * `codegen_thread_variables`.
474  * \param use_instance Should the variable be accessed via instance or data array
475  */
476  std::string thread_variable_name(const ThreadVariableInfo& var_info,
477  bool use_instance = true) const;
478 
479 
480  /**
481  * Determine the C++ string to replace variable names with.
482  *
483  * Given a variable name such as `ion_cai` or `v`, return the C++ code
484  * required to get the value.
485  *
486  * \param name Variable name that is being printed
487  * \param use_instance Should the variable be accessed via instance or data array
488  * \return The C++ string representing the variable.
489  * thread structure
490  */
491  std::string get_variable_name(const std::string& name, bool use_instance = true) const override;
492 
493  /**
494  * Determine the C++ string to replace pointer names with.
495  *
496  * Given a variable name such as `_p_ptr` or `_p_rng`, return the C++ code
497  * required to get a pointer to `ptr` (or `rng`).
498  *
499  * \param name Variable name that is being printed
500  * \return The C++ string representing the variable.
501  * thread structure
502  */
503  std::string get_pointer_name(const std::string& name) const;
504 
505 
506  /****************************************************************************************/
507  /* Main printing routines for code generation */
508  /****************************************************************************************/
509 
510 
511  /**
512  * Print standard C/C++ includes
513  */
514  void print_standard_includes() override;
515 
516 
517  /**
518  * Print includes from NEURON
519  */
520  void print_neuron_includes();
521 
522 
523  void print_sdlists_init(bool print_initializers) override;
524 
525 
526  /**
527  * Print the structure that wraps all global variables used in the NMODL
528  *
529  * \param print_initializers Whether to include default values in the struct
530  * definition (true: int foo{42}; false: int foo;)
531  */
532  void print_mechanism_global_var_structure(bool print_initializers) override;
533 
534 
535  /**
536  * Print byte arrays that register scalar and vector variables for hoc interface
537  *
538  */
539  void print_global_variables_for_hoc() override;
540 
541  /**
542  * Print functions for EXTERNAL use.
543  *
544  */
546 
547  /** Print global struct with default value of RANGE PARAMETERs.
548  */
550 
551  /**
552  * Print the mechanism registration function
553  *
554  */
555  void print_mechanism_register() override;
556 
557  /** Function body for anything not SUFFIX nothing. */
559 
560  /** Function body for SUFFIX nothing. */
562 
563  /**
564  * Print thread variable (de-)initialization functions.
565  */
567 
568  /**
569  * Print common code for global functions like nrn_init, nrn_cur and nrn_state
570  * \param type The target backend code block type
571  */
573  const std::string& function_name = "") override;
574 
575  /**
576  * Prints setup code for entrypoints from NEURON.
577  *
578  * The entrypoints typically receive a `sorted_token` and a bunch of other things, which then
579  * need to be converted into the default arguments for functions called (recursively) from the
580  * entrypoint.
581  *
582  * This variation prints the fast entrypoint, where NEURON is fully initialized and setup.
583  */
585 
586 
587  /**
588  * Prints setup code for entrypoints NEURON.
589  *
590  * See `print_entrypoint_setup_code_from_memb_list`. This variation should be used when one only
591  * has access to a `Prop`, but not the full `Memb_list`.
592  */
594 
595 
596  /**
597  * Print the \c nrn\_init function definition
598  * \param skip_init_check \c true to generate code executing the initialization conditionally
599  */
600  void print_nrn_init(bool skip_init_check = true);
601 
602  /** Print the initial block. */
603  void print_initial_block(const ast::InitialBlock* node);
604 
605  /**
606  * Print nrn_constructor function definition
607  *
608  */
609  void print_nrn_constructor() override;
611 
612  /**
613  * Print nrn_destructor function definition
614  *
615  */
616  void print_nrn_destructor() override;
618 
619 
620  /**
621  * Print nrn_alloc function definition
622  *
623  */
624  void print_nrn_alloc() override;
625 
626 
627  /**
628  * Print nrn_jacob function definition
629  *
630  */
631  void print_nrn_jacob();
632 
633 
634  /****************************************************************************************/
635  /* Print nrn_state routine */
636  /****************************************************************************************/
637 
638 
639  /**
640  * Print nrn_state / state update function definition
641  */
642  void print_nrn_state() override;
643 
644 
645  /****************************************************************************************/
646  /* Print nrn_cur related routines */
647  /****************************************************************************************/
648 
649  std::string nrn_current_arguments();
651 
652  /**
653  * Print the \c nrn_current kernel
654  *
655  * \note nrn_cur_kernel will have two calls to nrn_current if no conductance keywords specified
656  * \param node the AST node representing the NMODL breakpoint block
657  */
658  void print_nrn_current(const ast::BreakpointBlock& node) override;
659 
660 
661  /**
662  * Print the \c nrn\_cur kernel with NMODL \c conductance keyword provisions
663  *
664  * If the NMODL \c conductance keyword is used in the \c breakpoint block, then
665  * CodegenCoreneuronCppVisitor::print_nrn_cur_kernel will use this printer
666  *
667  * \param node the AST node representing the NMODL breakpoint block
668  */
669  void print_nrn_cur_conductance_kernel(const ast::BreakpointBlock& node) override;
670 
671 
672  /**
673  * Print the \c nrn\_cur kernel without NMODL \c conductance keyword provisions
674  *
675  * If the NMODL \c conductance keyword is \b not used in the \c breakpoint block, then
676  * CodegenCoreneuronCppVisitor::print_nrn_cur_kernel will use this printer
677  */
678  void print_nrn_cur_non_conductance_kernel() override;
679 
680 
681  /**
682  * Print main body of nrn_cur function
683  * \param node the AST node representing the NMODL breakpoint block
684  */
685  void print_nrn_cur_kernel(const ast::BreakpointBlock& node) override;
686 
687 
688  /**
689  * Print fast membrane current calculation code
690  */
691  void print_fast_imem_calculation() override;
692 
693 
694  /**
695  * Print nrn_cur / current update function definition
696  */
697  void print_nrn_cur() override;
698 
699 
700  /****************************************************************************************/
701  /* Main code printing entry points */
702  /****************************************************************************************/
703 
704 
705  /**
706  * Print all includes
707  *
708  */
709  void print_headers_include() override;
710 
711 
712  /**
713  * Print all NEURON macros
714  *
715  */
717 
718 
719  /**
720  * Print extern declarations for neuron global variables.
721  *
722  * Examples include `celsius`.
723  */
725 
726 
727  /**
728  * Print NEURON global variable macros
729  *
730  */
731  void print_global_macros();
732 
733 
734  /**
735  * Print mechanism variables' related macros
736  *
737  */
739 
740 
741  /**
742  * Print all classes
743  * \param print_initializers Whether to include default values.
744  */
745  void print_data_structures(bool print_initializers) override;
746 
747  /** Print `make_*_instance`.
748  */
749  void print_make_instance() const;
750 
751  /** Print `make_*_node_data`.
752  */
753  void print_make_node_data() const;
754 
755  /**
756  * Set v_unused (voltage) for NRN_PRCELLSTATE feature
757  */
758  void print_v_unused() const override;
759 
760 
761  /**
762  * Set g_unused (conductance) for NRN_PRCELLSTATE feature
763  */
764  void print_g_unused() const override;
765 
766 
767  /**
768  * Print all compute functions for every backend
769  *
770  */
771  void print_compute_functions() override;
772 
773 
774  /**
775  * Print entry point to code generation
776  *
777  */
778  void print_codegen_routines() override;
779 
780  /** Anything not SUFFIX nothing. */
782 
783  /** SUFFIX nothing is special. */
785 
786 
787  void print_ion_variable() override;
788 
789 
790  /**
791  * Get the parameters for functions that setup (initialize) CVODE
792  *
793  */
795 
796 
797  /**
798  * Get the parameters for functions that update state at given timestep in CVODE
799  *
800  */
802 
803 
804  /**
805  * Print all callbacks for CVODE
806  *
807  */
809 
810  /**
811  * Print the CVODE function returning the number of ODEs to solve
812  */
813  void print_cvode_count();
814 
815  /**
816  * Print the CVODE function for setup of tolerances
817  */
818  void print_cvode_tolerances();
819 
820  /**
821  * Print the CVODE update function \c name contained in \c block
822  */
823  void print_cvode_update(const std::string& name, const ast::StatementBlock& block);
824 
825  /**
826  * Print the CVODE setup function \c setup_name that calls the CVODE update function
827  * \c update_name
828  */
829  void print_cvode_setup(const std::string& setup_name, const std::string& update_name);
830 
831 
832  /****************************************************************************************/
833  /* Overloaded visitor routines */
834  /****************************************************************************************/
835 
836  std::string process_verbatim_text(const std::string& verbatim);
837  void visit_verbatim(const ast::Verbatim& node) override;
838  void visit_watch_statement(const ast::WatchStatement& node) override;
839  void visit_for_netcon(const ast::ForNetcon& node) override;
841  void visit_lon_diffuse(const ast::LonDiffuse& node) override;
842  void visit_protect_statement(const ast::ProtectStatement& node) override;
843 
844  public:
845  /****************************************************************************************/
846  /* Public printing routines for code generation for use in unit tests */
847  /****************************************************************************************/
848  ParamVector functor_params() override;
849 
850  /**
851  * Print the structure that wraps all range and int variables required for the NMODL
852  *
853  * \param print_initializers Whether or not default values for variables
854  * be included in the struct declaration.
855  */
856  void print_mechanism_range_var_structure(bool print_initializers) override;
857 
858  /**
859  * Print the structure that wraps all node variables required for the NMODL.
860  *
861  * \param print_initializers Whether or not default values for variables
862  * be included in the struct declaration.
863  */
864  void print_node_data_structure(bool print_initializers);
865 
866  /**
867  * Print the data structure used to access thread variables.
868  */
869  void print_thread_variables_structure(bool print_initializers);
870 };
871 
872 
873 /** \} */ // end of codegen_backends
874 
875 } // namespace codegen
876 } // namespace nmodl
Concrete visitor for all AST classes.
Base class for all block scoped nodes.
Definition: block.hpp:41
Represents a BREAKPOINT block in NMODL.
Represents a INITIAL block in the NMODL.
Represent LONGITUDINAL_DIFFUSION statement in NMODL.
Definition: lon_diffuse.hpp:39
Extracts information required for LONGITUDINAL_DIFFUSION for each KINETIC block.
Represents block encapsulating list of statements.
Represents a C code block.
Definition: verbatim.hpp:38
Represent WATCH statement in NMODL.
Visitor for printing C++ code compatible with legacy api of CoreNEURON
std::vector< std::tuple< std::string, std::string, std::string, std::string > > ParamVector
A vector of parameters represented by a 4-tuple of strings:
CodegenCppVisitor(std::string mod_filename, std::ostream &stream, std::string float_type, const bool optimize_ionvar_copies, std::unique_ptr< nmodl::utils::Blame > blame=nullptr)
Constructs the C++ code generator visitor.
Visitor for printing C++ code compatible with legacy api of NEURON
std::string table_thread_function_name() const
Name of the threaded table checking function.
void print_nrn_cur() override
Print nrn_cur / current update function definition.
void print_net_receive()
Print net_receive call-back.
void print_mechanism_global_var_structure(bool print_initializers) override
Print the structure that wraps all global variables used in the NMODL.
void print_nrn_destructor() override
Print nrn_destructor function definition.
std::pair< ParamVector, ParamVector > function_table_parameters(const ast::FunctionTableBlock &) override
Parameters of the function itself "{}" and "table_{}".
void print_nrn_current(const ast::BreakpointBlock &node) override
Print the nrn_current kernel.
void print_hoc_py_wrapper_call_impl(const ast::Block *function_or_procedure_block, InterpreterWrapper wrapper_type)
Print the code that calls the impl from the HOC/Py wrapper.
void print_cvode_tolerances()
Print the CVODE function for setup of tolerances.
void print_node_data_structure(bool print_initializers)
Print the structure that wraps all node variables required for the NMODL.
void print_mechanism_range_var_structure(bool print_initializers) override
Print the structure that wraps all range and int variables required for the NMODL.
std::vector< ThreadVariableInfo > codegen_thread_variables
GLOBAL variables in THREADSAFE MOD files that are not read-only are converted to thread variables.
void print_nrn_state() override
Print nrn_state / state update function definition.
void print_thread_variables_structure(bool print_initializers)
Print the data structure used to access thread variables.
void print_check_table_entrypoint()
Print all check_* function declarations.
std::string global_variable_name(const SymbolType &symbol, bool use_instance=true) const override
Determine the variable name for a global variable given its symbol.
void print_longitudinal_diffusion_callbacks()
Prints the callbacks required for LONGITUDINAL_DIFFUSION.
ParamVector ldifusfunc3_parameters() const
Parameters for what NEURON calls ldifusfunc3_t.
void print_thread_memory_callbacks()
Print thread variable (de-)initialization functions.
std::string get_variable_name(const std::string &name, bool use_instance=true) const override
Determine the C++ string to replace variable names with.
void visit_watch_statement(const ast::WatchStatement &node) override
TODO: Edit for NEURON.
ParamVector cvode_setup_parameters()
Get the parameters for functions that setup (initialize) CVODE.
void print_nrn_cur_kernel(const ast::BreakpointBlock &node) override
Print main body of nrn_cur function.
const ParamVector external_method_parameters(bool table=false) noexcept override
Parameters for functions in generated code that are called back from external code.
std::string register_mechanism_arguments() const override
Arguments for register_mech or point_register_mech function.
void visit_protect_statement(const ast::ProtectStatement &node) override
visit node of type ast::ProtectStatement
void print_nrn_cur_non_conductance_kernel() override
Print the nrn_cur kernel without NMODL conductance keyword provisions.
void print_hoc_py_wrapper(const ast::Block *function_or_procedure_block, InterpreterWrapper wrapper_type)
Print the wrapper for calling FUNCION/PROCEDURES from HOC/Py.
void print_make_node_data() const
Print make_*_node_data.
void visit_for_netcon(const ast::ForNetcon &node) override
visit node of type ast::ForNetcon
void print_global_variables_for_hoc() override
Print byte arrays that register scalar and vector variables for hoc interface.
void print_neuron_includes()
Print includes from NEURON.
void print_entrypoint_setup_code_from_memb_list()
Prints setup code for entrypoints from NEURON.
void print_codegen_routines_nothing()
SUFFIX nothing is special.
ParamVector cvode_update_parameters()
Get the parameters for functions that update state at given timestep in CVODE.
bool optimize_ion_variable_copies() const override
Check if ion variable copies should be avoided.
std::string thread_variable_name(const ThreadVariableInfo &var_info, bool use_instance=true) const
Determine the C++ string to print for thread variables.
void print_global_param_default_values()
Print global struct with default value of RANGE PARAMETERs.
void print_standard_includes() override
Print standard C/C++ includes.
void print_global_function_common_code(BlockType type, const std::string &function_name="") override
Print common code for global functions like nrn_init, nrn_cur and nrn_state.
void print_mechanism_register_regular()
Function body for anything not SUFFIX nothing.
void print_nrn_alloc() override
Print nrn_alloc function definition.
std::string simulator_name() override
Name of the simulator the code was generated for.
void visit_longitudinal_diffusion_block(const ast::LongitudinalDiffusionBlock &node) override
visit node of type ast::LongitudinalDiffusionBlock
void print_cvode_count()
Print the CVODE function returning the number of ODEs to solve.
ParamVector threadargs_parameters()
The parameters for the four macros _threadargs*_.
void print_function_prototypes() override
Print function and procedures prototype declaration.
void print_net_receive_registration()
Print code to register the call-back for the NET_RECEIVE block.
void print_setdata_functions()
Print NEURON functions related to setting global variables of the mechanism.
std::string backend_name() const override
Name of the code generation backend.
void print_function_or_procedure(const ast::Block &node, const std::string &name, const std::unordered_set< CppObjectSpecifier > &specifiers={ CppObjectSpecifier::Inline}) override
Print nmodl function or procedure (common code)
int position_of_int_var(const std::string &name) const override
Determine the position in the data array for a given int variable.
void print_function_definitions()
Print function and procedures prototype definitions.
void print_entrypoint_setup_code_from_prop()
Prints setup code for entrypoints NEURON.
void print_compute_functions() override
Print all compute functions for every backend.
void print_nrn_constructor() override
Print nrn_constructor function definition.
void print_cvode_definitions()
Print all callbacks for CVODE.
void print_mechanism_register_nothing()
Function body for SUFFIX nothing.
void print_sdlists_init(bool print_initializers) override
void print_verbatim_cleanup(const std::vector< std::string > &macros_defined)
Print #undefs to erase all compatibility macros.
ParamVector internal_method_parameters() override
Parameters for internally defined functions.
std::string get_pointer_name(const std::string &name) const
Determine the C++ string to replace pointer names with.
void print_codegen_routines() override
Print entry point to code generation.
void print_global_macros()
Print NEURON global variable macros.
std::string nrn_thread_internal_arguments() override
Arguments for "_threadargs_" macro in neuron implementation.
std::string py_function_signature(const std::string &function_or_procedure_name) const
Get the signature of the npy <func_or_proc_name> function.
void print_headers_include() override
Print all includes.
void print_macro_definitions()
Print all NEURON macros.
void print_v_unused() const override
Set v_unused (voltage) for NRN_PRCELLSTATE feature.
void visit_verbatim(const ast::Verbatim &node) override
visit node of type ast::Verbatim
ParamVector functor_params() override
The parameters of the Newton solver "functor".
std::string namespace_name() override
Name of "our" namespace.
void print_mechanism_variables_macros()
Print mechanism variables' related macros.
void print_make_instance() const
Print make_*_instance.
void add_variable_tqitem(std::vector< IndexVariableInfo > &variables) override
Add the variable tqitem during get_int_variables.
void print_point_process_function_definitions()
Print POINT_PROCESS related functions Wrap external NEURON functions related to POINT_PROCESS mechani...
void print_fast_imem_calculation() override
Print fast membrane current calculation code.
void print_mechanism_register() override
Print the mechanism registration function.
void print_initial_block(const ast::InitialBlock *node)
Print the initial block.
void print_g_unused() const override
Set g_unused (conductance) for NRN_PRCELLSTATE feature.
std::string py_function_name(const std::string &function_or_procedure_name) const
In non POINT_PROCESS mechanisms all functions and procedures need a py <func_or_proc_name> to be avai...
void print_nrn_jacob()
Print nrn_jacob function definition.
void add_variable_point_process(std::vector< IndexVariableInfo > &variables) override
Add the variable point_process during get_int_variables.
void print_neuron_global_variable_declarations()
Print extern declarations for neuron global variables.
void print_cvode_update(const std::string &name, const ast::StatementBlock &block)
Print the CVODE update function name contained in block.
std::string float_variable_name(const SymbolType &symbol, bool use_instance) const override
Determine the name of a float variable given its symbol.
std::string hoc_function_name(const std::string &function_or_procedure_name) const
All functions and procedures need a hoc <func_or_proc_name> to be available to the HOC interpreter.
void print_nrn_init(bool skip_init_check=true)
Print the nrn_init function definition.
std::string int_variable_name(const IndexVariableInfo &symbol, const std::string &name, bool use_instance) const override
Determine the name of an int variable given its symbol.
void print_net_init()
Print NET_RECEIVE{ INITIAL{ ...
void visit_lon_diffuse(const ast::LonDiffuse &node) override
visit node of type ast::LonDiffuse
std::vector< std::string > print_verbatim_setup(const ast::Verbatim &node, const std::string &verbatim)
Print compatibility macros required for VERBATIM blocks.
void print_net_send_call(const ast::FunctionCall &node) override
Print call to net_send.
const std::string external_method_arguments() noexcept override
Arguments for external functions called from generated code.
void print_net_event_call(const ast::FunctionCall &node) override
Print call to net_event.
ParamVector internalthreadargs_parameters()
The parameters for the four macros _internalthreadargs*_.
void print_global_var_external_access()
Print functions for EXTERNAL use.
std::string hoc_py_wrapper_signature(const ast::Block *function_or_procedure_block, InterpreterWrapper wrapper_type)
Return the wrapper signature.
void print_codegen_routines_regular()
Anything not SUFFIX nothing.
void print_nrn_cur_conductance_kernel(const ast::BreakpointBlock &node) override
Print the nrn_cur kernel with NMODL conductance keyword provisions.
void print_hoc_py_wrapper_setup(const ast::Block *function_or_procedure_block, InterpreterWrapper wrapper_type)
Print the setup code for HOC/Py wrapper.
void append_conc_write_statements(std::vector< ShadowUseStatement > &statements, const Ion &ion, const std::string &concentration) override
Generate Function call statement for nrn_wrote_conc.
void print_data_structures(bool print_initializers) override
Print all classes.
std::string process_verbatim_text(const std::string &verbatim)
ParamVector ldifusfunc1_parameters() const
Parameters for what NEURON calls ldifusfunc1_t.
void print_function_table_call(const ast::FunctionCall &node) override
Print special code when calling FUNCTION_TABLEs.
void print_net_move_call(const ast::FunctionCall &node) override
Print call to net_move.
std::string nrn_thread_arguments() const override
Arguments for "_threadargs_" macro in neuron implementation.
std::string internal_method_arguments() override
Arguments for functions that are defined and used internally.
void print_function_procedure_helper(const ast::Block &node) override
Common helper function to help printing function or procedure blocks.
void print_cvode_setup(const std::string &setup_name, const std::string &update_name)
Print the CVODE setup function setup_name that calls the CVODE update function update_name.
std::string hoc_function_signature(const std::string &function_or_procedure_name) const
Get the signature of the hoc <func_or_proc_name> function.
int position_of_float_var(const std::string &name) const override
Determine the position in the data array for a given float variable.
Helper class for printing C/C++ code.
Visitor for printing C++ code compatible with legacy api of CoreNEURON
Various types to store code generation specific information.
Auto generated AST classes declaration.
BlockType
Helper to represent various block types.
std::string get_name(ast::Ast const *sym)
double var(InputIterator begin, InputIterator end)
Definition: ivocvect.h:108
const char * name
Definition: init.cpp:16
InterpreterWrapper
Enum to switch between HOC and Python wrappers for functions and procedures defined in mechanisms.
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
parser::NmodlParser::symbol_type SymbolType
Definition: main_nmodl.cpp:33
static Node * node(Object *)
Definition: netcvode.cpp:291
short type
Definition: cabvars.h:10
Auto generated AST classes declaration.
Helper to represent information about index/int variables.
Represent ions used in mod file.
Represents ion write statement during code generation.
size_t index
There index global variables ahead of this one.
const std::shared_ptr< symtab::Symbol > symbol
size_t offset
The global variables ahead of this one require offset doubles to store.
Definition: units.cpp:71
Implement classes for representing symbol table at block and file scope.