NEURON
codegen_info.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 Various types to store code generation specific information
13  */
14 
15 #include "utils/fmt.h"
16 
17 #include <optional>
18 #include <string>
19 #include <unordered_map>
20 #include <unordered_set>
21 #include <utility>
22 
23 #include "ast/ast.hpp"
25 #include "symtab/symbol_table.hpp"
26 
27 
28 namespace nmodl {
29 namespace codegen {
30 
31 /**
32  * \addtogroup codegen_details
33  * \{
34  */
35 
36 /**
37  * \class Conductance
38  * \brief Represent conductance statements used in mod file
39  */
40 struct Conductance {
41  /// name of the ion
42  std::string ion;
43 
44  /// ion variable like intra/extra concentration
45  std::string variable;
46 };
47 
48 
49 /**
50  * \class Ion
51  * \brief Represent ions used in mod file
52  */
53 struct Ion {
54  /// name of the ion
55  std::string name;
56 
57  /// ion variables that are being read
58  std::vector<std::string> reads;
59 
60  /// ion variables that are being implicitly read
61  std::vector<std::string> implicit_reads;
62 
63  /// ion variables that are being written
64  std::vector<std::string> writes;
65 
66  /// ion valence
67  std::optional<double> valence;
68 
69  /// if style semantic needed
70  bool need_style = false;
71 
72  Ion() = delete;
73 
74  explicit Ion(std::string name)
75  : name(std::move(name)) {}
76 
77  bool is_read(const std::string& name) const {
78  return std::find(reads.cbegin(), reads.cend(), name) != reads.cend() ||
79  std::find(implicit_reads.cbegin(), implicit_reads.cend(), name) !=
80  implicit_reads.cend();
81  }
82 
83  bool is_conc_read() const {
85  }
86 
87  bool is_interior_conc_read() const {
88  return is_read(fmt::format("{}i", name));
89  }
90 
91  bool is_exterior_conc_read() const {
92  return is_read(fmt::format("{}o", name));
93  }
94 
95  bool is_written(const std::string& name) const {
96  return std::find(writes.cbegin(), writes.cend(), name) != writes.cend();
97  }
98 
99  bool is_conc_written() const {
101  }
102 
104  return is_written(fmt::format("{}i", name));
105  }
106 
108  return is_written(fmt::format("{}o", name));
109  }
110 
111  bool is_rev_read() const {
112  return is_read(fmt::format("e{}", name));
113  }
114 
115  bool is_rev_written() const {
116  return is_written(fmt::format("e{}", name));
117  }
118 
119  /**
120  * Check if variable name is a ionic current
121  *
122  * This is equivalent of IONCUR flag in mod2c.
123  * If it is read variable then also get NRNCURIN flag.
124  * If it is write variables then also get NRNCUROUT flag.
125  */
126  bool is_ionic_current(const std::string& text) const {
127  return text == ionic_current_name();
128  }
129 
130  /**
131  * Check if variable name is internal cell concentration
132  *
133  * This is equivalent of IONIN flag in mod2c.
134  */
135  bool is_intra_cell_conc(const std::string& text) const {
136  return text == intra_conc_name();
137  }
138 
139  /**
140  * Check if variable name is external cell concentration
141  *
142  * This is equivalent of IONOUT flag in mod2c.
143  */
144  bool is_extra_cell_conc(const std::string& text) const {
145  return text == extra_conc_name();
146  }
147 
148  /**
149  * Check if variable name is reveral potential
150  *
151  * Matches `ena` and `na_erev`.
152  */
153  bool is_rev_potential(const std::string& text) const {
154  return text == rev_potential_name() ||
156  }
157 
158  /// check if it is either internal or external concentration
159  bool is_ionic_conc(const std::string& text) const {
161  }
162 
163  /// Is the variable name `text` related to this ion?
164  ///
165  /// Example: For sodium this is true for any of `"ena"`, `"ina"`, `"nai"`
166  /// and `"nao"`; but not `ion_ina`, etc.
167  bool is_ionic_variable(const std::string& text) const {
169  }
170 
171  /// Is the variable name `text` the style of this ion?
172  ///
173  /// Example: For sodium this is true for `"style_na"`.
174  bool is_style(const std::string& text) const {
175  return text == fmt::format("style_{}", name);
176  }
177 
178  bool is_current_derivative(const std::string& text) const {
179  return text == ("di" + name + "dv");
180  }
181 
182  std::string intra_conc_name() const {
183  return name + "i";
184  }
185 
186  std::string intra_conc_pointer_name() const {
188  }
189 
190  std::string extra_conc_name() const {
191  return name + "o";
192  }
193 
194  std::string extra_conc_pointer_name() const {
196  }
197 
198  std::string rev_potential_name() const {
199  return "e" + name;
200  }
201 
202  std::string rev_potential_pointer_name() const {
203  return naming::ION_VARNAME_PREFIX + name + "_erev";
204  }
205 
206  std::string ionic_current_name() const {
207  return "i" + name;
208  }
209 
210  std::string ionic_current_pointer_name() const {
212  }
213 
214  std::string current_derivative_name() const {
215  return "di" + name + "dv";
216  }
217 
218  std::string current_derivative_pointer_name() const {
220  }
221 
222  /// for a given ion, return different variable names/properties
223  /// like internal/external concentration, reversal potential,
224  /// ionic current etc.
225  static std::vector<std::string> get_possible_variables(const std::string& ion_name) {
226  auto ion = Ion(ion_name);
227  return {ion.ionic_current_name(),
228  ion.intra_conc_name(),
229  ion.extra_conc_name(),
230  ion.rev_potential_name()};
231  }
232 
233  /// Variable index in the ion mechanism.
234  ///
235  /// For sodium (na), the `var_name` must be one of `ina`, `ena`, `nai`,
236  /// `nao` or `dinadv`. Replace `na` with the analogous for other ions.
237  ///
238  /// In NRN the order is:
239  /// 0: ena
240  /// 1: nai
241  /// 2: nao
242  /// 3: ina
243  /// 4: dinadv
244  int variable_index(const std::string& var_name) const {
245  if (is_rev_potential(var_name)) {
246  return 0;
247  }
248  if (is_intra_cell_conc(var_name)) {
249  return 1;
250  }
251  if (is_extra_cell_conc(var_name)) {
252  return 2;
253  }
254  if (is_ionic_current(var_name)) {
255  return 3;
256  }
257  if (is_current_derivative(var_name)) {
258  return 4;
259  }
260 
261  throw std::runtime_error(fmt::format("Invalid `var_name == {}`.", var_name));
262  }
263 };
264 
265 
266 /**
267  * \class IndexSemantics
268  * \brief Represent semantic information for index variable
269  */
271  /// start position in the int array
272  int index;
273 
274  /// name/type of the variable (i.e. semantics)
275  std::string name;
276 
277  /// number of elements (typically one)
278  int size;
279 
280  IndexSemantics() = delete;
281  IndexSemantics(int index, std::string name, int size)
282  : index(index)
283  , name(std::move(name))
284  , size(size) {}
285 };
286 
287 /**
288  * \brief Information required to print LONGITUDINAL_DIFFUSION callbacks.
289  */
291  public:
292  LongitudinalDiffusionInfo(const std::shared_ptr<ast::Name>& index_name,
293  std::shared_ptr<ast::Expression> volume_expr,
294  const std::shared_ptr<ast::Name>& rate_index_name,
295  std::shared_ptr<ast::Expression> rate_expr);
296  /// Volume of this species.
297  ///
298  /// If the volume expression is an indexed expression, the index in the
299  /// expression is substituted with `index_name`.
300  std::shared_ptr<ast::Expression> volume(const std::string& index_name) const;
301 
302  /// Difusion rate of this species.
303  ///
304  /// If the diffusion expression is an indexed expression, the index in the
305  /// expression is substituted with `index_name`.
306  std::shared_ptr<ast::Expression> diffusion_rate(const std::string& index_name) const;
307 
308  /// The value of what NEURON calls `dfcdc`.
309  double dfcdc(const std::string& /* index_name */) const;
310 
311  protected:
312  std::shared_ptr<ast::Expression> substitute_index(
313  const std::string& index_name,
314  const std::string& old_index_name,
315  const std::shared_ptr<ast::Expression>& old_expr) const;
316 
317  private:
318  std::string volume_index_name;
319  std::shared_ptr<ast::Expression> volume_expr;
320 
321  std::string rate_index_name;
322  std::shared_ptr<ast::Expression> rate_expr;
323 };
324 
325 
326 /**
327  * \class CodegenInfo
328  * \brief Represent information collected from AST for code generation
329  *
330  * Code generation passes require different information from AST. This
331  * information is gathered in this single class.
332  *
333  * \todo Need to store all Define i.e. macro definitions?
334  */
335 struct CodegenInfo {
336  /// name of mod file
337  std::string mod_file;
338 
339  /// name of the suffix
340  std::string mod_suffix;
341 
342  /// point process range and functions don't have suffix
343  std::string rsuffix;
344 
345  /// true if mod file is vectorizable (which should be always true for coreneuron)
346  /// But there are some blocks like LINEAR are not thread safe in neuron or mod2c
347  /// context. In this case vectorize is used to determine number of float variable
348  /// in the data array (e.g. v). For such non thread methods or blocks vectorize is
349  /// false.
350  bool vectorize = true;
351 
352  /// if mod file is thread safe (always true for coreneuron)
353  bool thread_safe = true;
354 
355  /// A mod file can be declared to be thread safe using the keyword THREADSAFE.
356  /// This boolean is true if and only if the mod file was declared thread safe
357  /// by the user. For example thread variables require the mod file to be declared
358  /// thread safe.
359  bool declared_thread_safe = false;
360 
361  /// if mod file is point process
362  bool point_process = false;
363 
364  /// if mod file is artificial cell
365  bool artificial_cell = false;
366 
367  /// if electrode current specified
368  bool electrode_current = false;
369 
370  /// if thread thread call back routines need to register
372 
373  /// if bbcore pointer is used
374  bool bbcore_pointer_used = false;
375 
376  /// if write concentration call required in initial block
377  bool write_concentration = false;
378 
379  /// if net_send function is used
380  bool net_send_used = false;
381 
382  /// if net_event function is used
383  bool net_event_used = false;
384 
385  /// if diam is used
386  bool diam_used = false;
387 
388  /// if area is used
389  bool area_used = false;
390 
391  /// if for_netcon is used
392  bool for_netcon_used = false;
393 
394  /// number of watch expressions
395  int watch_count = 0;
396 
397  /// number of table statements
398  int table_count = 0;
399 
400  /**
401  * thread_data_index indicates number of threads being allocated.
402  * For example, if there is derivimplicit method used, then two thread
403  * structures are created. When we print global variables then
404  * thread_data_index is used to indicate whats next thread id to use.
405  */
407 
408  /**
409  * Top local variables are those local variables that appear in global scope.
410  * Thread structure is created for top local variables and doesn't thread id
411  * 0. For example, if derivimplicit method is used then thread id 0 is assigned
412  * to those structures first. And then next thread id is assigned for top local
413  * variables. The idea of thread is assignement is to have same order for variables
414  * between neuron and coreneuron.
415  */
416 
417  /// thread id for top local variables
419 
420  /// total length of all top local variables
422 
423  /// thread id for thread promoted variables
425 
426  /// sum of length of thread promoted variables
428 
429  /// thread id for derivimplicit variables
431 
432  /// slist/dlist id for derivimplicit block
434 
435  /// number of solve blocks in mod file
437 
438  /// number of primes (all state variables not necessary to be prime)
439  int num_primes = 0;
440 
441  /// sum of length of all prime variables
442  int primes_size = 0;
443 
444  /// number of equations (i.e. statements) in derivative block
445  /// typically equal to number of primes
446  int num_equations = 0;
447 
448  /// number of semantic variables
450 
451  /// True if we have to emit CVODE code
452  /// TODO: Figure out when this needs to be true
453  bool emit_cvode = false;
454 
455  /// derivative block
457 
458  /// nrn_state block
460 
461  /// the CVODE block
462  const ast::CvodeBlock* cvode_block = nullptr;
463 
464  /// net receive block for point process
466 
467  /// number of arguments to net_receive block
469 
470  /// initial block within net receive block
472 
473  /// initial block
474  const ast::InitialBlock* initial_node = nullptr;
475 
476  /// constructor block
478 
479  /// destructor block only for point process
481 
482  /// all procedures defined in the mod file
483  std::vector<const ast::ProcedureBlock*> procedures;
484 
485  /// derivimplicit callbacks need to be emited
486  std::vector<const ast::DerivimplicitCallback*> derivimplicit_callbacks;
487 
488  /// all functions defined in the mod file
489  std::vector<const ast::FunctionBlock*> functions;
490 
491  /// all functions tables defined in the mod file
492  std::vector<const ast::FunctionTableBlock*> function_tables;
493 
494  /// all factors defined in the mod file
495  std::vector<const ast::FactorDef*> factor_definitions;
496 
497  /// for each state, the information needed to print the callbacks.
498  std::map<std::string, LongitudinalDiffusionInfo> longitudinal_diffusion_info;
499 
500  /// ions used in the mod file
501  std::vector<Ion> ions;
502 
503  using SymbolType = std::shared_ptr<symtab::Symbol>;
504 
505  /// range variables which are parameter as well
506  std::vector<SymbolType> range_parameter_vars;
507 
508  /// range variables which are assigned variables as well
509  std::vector<SymbolType> range_assigned_vars;
510 
511  /// remaining assigned variables
512  std::vector<SymbolType> assigned_vars;
513 
514  /// all state variables
515  std::vector<SymbolType> state_vars;
516 
517  /// state variables excluding such useion read/write variables
518  /// that are not ionic currents. In neuron/mod2c these are stored
519  /// in the list "rangestate".
520  std::vector<SymbolType> range_state_vars;
521 
522  /// local variables in the global scope
523  std::vector<SymbolType> top_local_variables;
524 
525  /// pointer or bbcore pointer variables
526  std::vector<SymbolType> pointer_variables;
527 
528  /// RANDOM variables
529  std::vector<SymbolType> random_variables;
530 
531  /// index/offset for first pointer variable if exist
533 
534  /// index/offset for first RANDOM variable if exist
536 
537  /// tqitem index in integer variables
538  /// note that if tqitem doesn't exist then the default value should be 0
539  int tqitem_index = 0;
540 
541  /// updated dt to use with steadystate solver (in initial block)
542  /// empty string means no change in dt
543  std::string changed_dt;
544 
545  /// global variables
546  std::vector<SymbolType> global_variables;
547 
548  /// constant variables
549  std::vector<SymbolType> constant_variables;
550 
551  /// thread variables (e.g. global variables promoted to thread)
552  std::vector<SymbolType> thread_variables;
553 
554  /// external variables
555  std::vector<SymbolType> external_variables;
556 
557  /// new one used in print_ion_types
558  std::vector<SymbolType> use_ion_variables;
559 
560  /// this is the order in which they appear in derivative block
561  /// this is required while printing them in initlist function
562  std::vector<SymbolType> prime_variables_by_order;
563 
564  /// table variables
565  std::vector<SymbolType> table_statement_variables;
566  std::vector<SymbolType> table_assigned_variables;
567 
568  /// [Core]NEURON global variables used (e.g. celsius) and their types
569  std::vector<std::pair<SymbolType, std::string>> neuron_global_variables;
570 
571  /// function or procedures with table statement
572  std::vector<const ast::Block*> functions_with_table;
573 
574  /// represent conductance statements used in mod file
575  std::vector<Conductance> conductances;
576 
577  /// index variable semantic information
578  std::vector<IndexSemantics> semantics;
579 
580  /// non specific and ionic currents
581  std::vector<std::string> currents;
582 
583  /// all top level global blocks
584  std::vector<ast::Node*> top_blocks;
585 
586  /// all top level verbatim blocks
587  std::vector<ast::Node*> top_verbatim_blocks;
588 
589  /// all watch statements
590  std::vector<const ast::WatchStatement*> watch_statements;
591 
592  /// all before after blocks
593  std::vector<const ast::Block*> before_after_blocks;
594 
595  /// all variables/symbols used in the verbatim block
596  std::unordered_set<std::string> variables_in_verbatim;
597 
598  /// unique functor names for all the \c EigenNewtonSolverBlock s
599  std::unordered_map<const ast::EigenNewtonSolverBlock*, std::string> functor_names;
600 
601  /// true if eigen newton solver is used
603 
604  /// true if eigen linear solver is used
606 
607  /// if any ion has write variable
608  bool ion_has_write_variable() const noexcept;
609 
610  /// if given variable is ion write variable
611  bool is_ion_write_variable(const std::string& name) const noexcept;
612 
613  /// if given variable is ion read variable
614  bool is_ion_read_variable(const std::string& name) const noexcept;
615 
616  /// if either read or write variable
617  bool is_ion_variable(const std::string& name) const noexcept;
618 
619  /// if given variable is a current
620  bool is_current(const std::string& name) const noexcept;
621 
622  /// if given variable is a ionic current
623  bool is_ionic_current(const std::string& name) const noexcept;
624 
625  /// if given variable is a ionic concentration
626  bool is_ionic_conc(const std::string& name) const noexcept;
627 
628  /// if watch statements are used
629  bool is_watch_used() const noexcept {
630  return watch_count > 0;
631  }
632 
633  bool emit_table_thread() const noexcept {
634  return (table_count > 0 && vectorize == true);
635  }
636 
637  /// if legacy derivimplicit solver from coreneuron to be used
638  inline bool derivimplicit_used() const {
639  return !derivimplicit_callbacks.empty();
640  }
641 
642  bool function_uses_table(const std::string& name) const noexcept;
643 
644  /// true if EigenNewtonSolver is used in nrn_state block
646 
647  /// true if WatchStatement uses voltage v variable
649 
650  /// if we need a call back to wrote_conc in neuron/coreneuron
651  bool require_wrote_conc = false;
652 };
653 
654 /** \} */ // end of codegen_backends
655 
656 } // namespace codegen
657 } // namespace nmodl
Auto generated AST classes declaration.
Represents a BREAKPOINT block in NMODL.
Represents a CONSTRUCTOR block in the NMODL.
Represents a block used for variable timestep integration (CVODE) of DERIVATIVE blocks.
Definition: cvode_block.hpp:38
Represents a DESTRUCTOR block in the NMODL.
Represents a INITIAL block in the NMODL.
Represents the coreneuron nrn_state callback function.
Information required to print LONGITUDINAL_DIFFUSION callbacks.
std::shared_ptr< ast::Expression > volume(const std::string &index_name) const
Volume of this species.
std::shared_ptr< ast::Expression > substitute_index(const std::string &index_name, const std::string &old_index_name, const std::shared_ptr< ast::Expression > &old_expr) const
std::shared_ptr< ast::Expression > volume_expr
double dfcdc(const std::string &) const
The value of what NEURON calls dfcdc.
LongitudinalDiffusionInfo(const std::shared_ptr< ast::Name > &index_name, std::shared_ptr< ast::Expression > volume_expr, const std::shared_ptr< ast::Name > &rate_index_name, std::shared_ptr< ast::Expression > rate_expr)
std::shared_ptr< ast::Expression > diffusion_rate(const std::string &index_name) const
Difusion rate of this species.
std::shared_ptr< ast::Expression > rate_expr
static bool ends_with(const std::string &haystack, const std::string &needle)
Check if haystack ends with needle.
const char * name
Definition: init.cpp:16
void move(Item *q1, Item *q2, Item *q3)
Definition: list.cpp:200
static constexpr char ION_VARNAME_PREFIX[]
prefix for ion variable
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
#define text
Definition: plot.cpp:60
int find(const int, const int, const int, const int, const int)
Represent information collected from AST for code generation.
int thread_var_data_size
sum of length of thread promoted variables
int semantic_variable_count
number of semantic variables
bool is_voltage_used_by_watch_statements() const
true if WatchStatement uses voltage v variable
std::vector< SymbolType > range_assigned_vars
range variables which are assigned variables as well
std::vector< std::pair< SymbolType, std::string > > neuron_global_variables
[Core]NEURON global variables used (e.g. celsius) and their types
bool bbcore_pointer_used
if bbcore pointer is used
bool write_concentration
if write concentration call required in initial block
std::vector< const ast::FactorDef * > factor_definitions
all factors defined in the mod file
std::vector< SymbolType > assigned_vars
remaining assigned variables
const ast::CvodeBlock * cvode_block
the CVODE block
std::vector< SymbolType > range_state_vars
state variables excluding such useion read/write variables that are not ionic currents.
bool is_ion_write_variable(const std::string &name) const noexcept
if given variable is ion write variable
bool is_ion_variable(const std::string &name) const noexcept
if either read or write variable
int num_equations
number of equations (i.e.
bool artificial_cell
if mod file is artificial cell
std::vector< const ast::FunctionTableBlock * > function_tables
all functions tables defined in the mod file
std::vector< SymbolType > pointer_variables
pointer or bbcore pointer variables
bool function_uses_table(const std::string &name) const noexcept
bool point_process
if mod file is point process
bool electrode_current
if electrode current specified
std::vector< ast::Node * > top_blocks
all top level global blocks
int tqitem_index
tqitem index in integer variables note that if tqitem doesn't exist then the default value should be ...
bool diam_used
if diam is used
std::unordered_map< const ast::EigenNewtonSolverBlock *, std::string > functor_names
unique functor names for all the EigenNewtonSolverBlock s
std::vector< IndexSemantics > semantics
index variable semantic information
std::vector< SymbolType > global_variables
global variables
int first_random_var_index
index/offset for first RANDOM variable if exist
int thread_data_index
thread_data_index indicates number of threads being allocated.
bool vectorize
true if mod file is vectorizable (which should be always true for coreneuron) But there are some bloc...
bool net_event_used
if net_event function is used
const ast::BreakpointBlock * breakpoint_node
derivative block
bool require_wrote_conc
if we need a call back to wrote_conc in neuron/coreneuron
bool net_send_used
if net_send function is used
std::vector< const ast::WatchStatement * > watch_statements
all watch statements
bool declared_thread_safe
A mod file can be declared to be thread safe using the keyword THREADSAFE.
bool thread_callback_register
if thread thread call back routines need to register
bool ion_has_write_variable() const noexcept
if any ion has write variable
std::vector< SymbolType > use_ion_variables
new one used in print_ion_types
bool nrn_state_has_eigen_solver_block() const
true if EigenNewtonSolver is used in nrn_state block
int num_primes
number of primes (all state variables not necessary to be prime)
const ast::DestructorBlock * destructor_node
destructor block only for point process
std::vector< SymbolType > external_variables
external variables
std::vector< const ast::ProcedureBlock * > procedures
all procedures defined in the mod file
const ast::NrnStateBlock * nrn_state_block
nrn_state block
bool is_current(const std::string &name) const noexcept
if given variable is a current
const ast::InitialBlock * net_receive_initial_node
initial block within net receive block
std::vector< SymbolType > thread_variables
thread variables (e.g. global variables promoted to thread)
bool eigen_newton_solver_exist
true if eigen newton solver is used
std::string mod_file
name of mod file
std::vector< SymbolType > constant_variables
constant variables
std::vector< ast::Node * > top_verbatim_blocks
all top level verbatim blocks
bool thread_safe
if mod file is thread safe (always true for coreneuron)
int num_net_receive_parameters
number of arguments to net_receive block
std::vector< const ast::DerivimplicitCallback * > derivimplicit_callbacks
derivimplicit callbacks need to be emited
bool is_ion_read_variable(const std::string &name) const noexcept
if given variable is ion read variable
bool is_ionic_current(const std::string &name) const noexcept
if given variable is a ionic current
std::vector< const ast::Block * > before_after_blocks
all before after blocks
std::vector< std::string > currents
non specific and ionic currents
bool derivimplicit_used() const
if legacy derivimplicit solver from coreneuron to be used
int table_count
number of table statements
std::vector< SymbolType > table_statement_variables
table variables
std::vector< const ast::Block * > functions_with_table
function or procedures with table statement
std::vector< Ion > ions
ions used in the mod file
std::string rsuffix
point process range and functions don't have suffix
std::vector< SymbolType > random_variables
RANDOM variables.
std::vector< SymbolType > top_local_variables
local variables in the global scope
const ast::NetReceiveBlock * net_receive_node
net receive block for point process
std::shared_ptr< symtab::Symbol > SymbolType
std::vector< SymbolType > range_parameter_vars
range variables which are parameter as well
std::vector< const ast::FunctionBlock * > functions
all functions defined in the mod file
bool is_watch_used() const noexcept
if watch statements are used
int top_local_thread_id
Top local variables are those local variables that appear in global scope.
int first_pointer_var_index
index/offset for first pointer variable if exist
int derivimplicit_var_thread_id
thread id for derivimplicit variables
bool eigen_linear_solver_exist
true if eigen linear solver is used
int thread_var_thread_id
thread id for thread promoted variables
int primes_size
sum of length of all prime variables
std::map< std::string, LongitudinalDiffusionInfo > longitudinal_diffusion_info
for each state, the information needed to print the callbacks.
bool emit_cvode
True if we have to emit CVODE code TODO: Figure out when this needs to be true.
int watch_count
number of watch expressions
std::vector< Conductance > conductances
represent conductance statements used in mod file
std::vector< SymbolType > prime_variables_by_order
this is the order in which they appear in derivative block this is required while printing them in in...
bool area_used
if area is used
std::string mod_suffix
name of the suffix
std::string changed_dt
updated dt to use with steadystate solver (in initial block) empty string means no change in dt
int num_solve_blocks
number of solve blocks in mod file
int derivimplicit_list_num
slist/dlist id for derivimplicit block
bool emit_table_thread() const noexcept
bool for_netcon_used
if for_netcon is used
const ast::ConstructorBlock * constructor_node
constructor block
bool is_ionic_conc(const std::string &name) const noexcept
if given variable is a ionic concentration
std::vector< SymbolType > state_vars
all state variables
std::unordered_set< std::string > variables_in_verbatim
all variables/symbols used in the verbatim block
std::vector< SymbolType > table_assigned_variables
const ast::InitialBlock * initial_node
initial block
int top_local_thread_size
total length of all top local variables
Represent conductance statements used in mod file.
std::string variable
ion variable like intra/extra concentration
std::string ion
name of the ion
Represent semantic information for index variable.
int size
number of elements (typically one)
std::string name
name/type of the variable (i.e. semantics)
IndexSemantics(int index, std::string name, int size)
int index
start position in the int array
Represent ions used in mod file.
bool is_conc_written() const
bool is_current_derivative(const std::string &text) const
bool is_interior_conc_read() const
bool is_exterior_conc_written() const
std::string rev_potential_pointer_name() const
std::string name
name of the ion
bool is_read(const std::string &name) const
std::string intra_conc_name() const
std::string extra_conc_name() const
static std::vector< std::string > get_possible_variables(const std::string &ion_name)
for a given ion, return different variable names/properties like internal/external concentration,...
bool need_style
if style semantic needed
Ion(std::string name)
std::vector< std::string > implicit_reads
ion variables that are being implicitly read
std::string extra_conc_pointer_name() const
bool is_ionic_variable(const std::string &text) const
Is the variable name text related to this ion?
bool is_style(const std::string &text) const
Is the variable name text the style of this ion?
bool is_ionic_current(const std::string &text) const
Check if variable name is a ionic current.
bool is_rev_read() const
bool is_intra_cell_conc(const std::string &text) const
Check if variable name is internal cell concentration.
bool is_exterior_conc_read() const
std::string ionic_current_pointer_name() const
std::string current_derivative_pointer_name() const
std::optional< double > valence
ion valence
bool is_ionic_conc(const std::string &text) const
check if it is either internal or external concentration
bool is_extra_cell_conc(const std::string &text) const
Check if variable name is external cell concentration.
std::string current_derivative_name() const
std::vector< std::string > reads
ion variables that are being read
bool is_rev_potential(const std::string &text) const
Check if variable name is reveral potential.
std::string intra_conc_pointer_name() const
bool is_conc_read() const
bool is_rev_written() const
std::vector< std::string > writes
ion variables that are being written
bool is_interior_conc_written() const
int variable_index(const std::string &var_name) const
Variable index in the ion mechanism.
std::string rev_potential_name() const
std::string ionic_current_name() const
bool is_written(const std::string &name) const
Implement classes for representing symbol table at block and file scope.