User Guide
codegen_info.cpp
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 
9 
10 #include "ast/all.hpp"
15 
16 
17 namespace nmodl {
18 namespace codegen {
19 
20 using visitor::VarUsageVisitor;
21 
23  const std::shared_ptr<ast::Name>& volume_index_name,
24  std::shared_ptr<ast::Expression> volume_expr,
25  const std::shared_ptr<ast::Name>& rate_index_name,
26  std::shared_ptr<ast::Expression> rate_expr)
27  : volume_index_name(volume_index_name ? volume_index_name->get_node_name() : std::string{})
28  , volume_expr(std::move(volume_expr))
29  , rate_index_name(rate_index_name ? rate_index_name->get_node_name() : std::string{})
30  , rate_expr(std::move(rate_expr)) {}
31 
32 std::shared_ptr<ast::Expression> LongitudinalDiffusionInfo::volume(
33  const std::string& index_name) const {
34  return substitute_index(index_name, volume_index_name, volume_expr);
35 }
36 std::shared_ptr<ast::Expression> LongitudinalDiffusionInfo::diffusion_rate(
37  const std::string& index_name) const {
38  return substitute_index(index_name, rate_index_name, rate_expr);
39 }
40 
41 double LongitudinalDiffusionInfo::dfcdc(const std::string& /* index_name */) const {
42  // Needed as part of the Jacobian to stabalize
43  // the implicit time-integration. However,
44  // currently, it's set to `0.0` for simplicity.
45  return 0.0;
46 }
47 
48 std::shared_ptr<ast::Expression> LongitudinalDiffusionInfo::substitute_index(
49  const std::string& index_name,
50  const std::string& old_index_name,
51  const std::shared_ptr<ast::Expression>& old_expr) const {
52  if (old_index_name == "") {
53  // The expression doesn't contain an index that needs substituting.
54  return old_expr;
55  }
56  auto new_expr = old_expr->clone();
57 
58  auto v = visitor::RenameVisitor(old_index_name, index_name);
59  new_expr->accept(v);
60 
61  return std::shared_ptr<ast::Expression>(dynamic_cast<ast::Expression*>(new_expr));
62 }
63 
64 /// if any ion has write variable
65 bool CodegenInfo::ion_has_write_variable() const noexcept {
66  return std::any_of(ions.begin(), ions.end(), [](auto const& ion) {
67  return !ion.writes.empty();
68  });
69 }
70 
71 
72 /// if given variable is ion write variable
73 bool CodegenInfo::is_ion_write_variable(const std::string& name) const noexcept {
74  return std::any_of(ions.begin(), ions.end(), [&name](auto const& ion) {
75  return std::any_of(ion.writes.begin(), ion.writes.end(), [&name](auto const& var) {
76  return var == name;
77  });
78  });
79 }
80 
81 
82 /// if given variable is ion read variable
83 bool CodegenInfo::is_ion_read_variable(const std::string& name) const noexcept {
84  return std::any_of(ions.begin(), ions.end(), [&name](auto const& ion) {
85  return std::any_of(ion.reads.begin(), ion.reads.end(), [&name](auto const& var) {
86  return var == name;
87  });
88  });
89 }
90 
91 
92 /// if either read or write variable
93 bool CodegenInfo::is_ion_variable(const std::string& name) const noexcept {
94  return is_ion_read_variable(name) || is_ion_write_variable(name);
95 }
96 
97 
98 /// if a current (ionic or non-specific)
99 bool CodegenInfo::is_current(const std::string& name) const noexcept {
100  return std::any_of(currents.begin(), currents.end(), [&name](auto const& var) {
101  return var == name;
102  });
103 }
104 
105 /// true is a given variable name if a ionic current
106 /// (i.e. currents excluding non-specific current)
107 bool CodegenInfo::is_ionic_current(const std::string& name) const noexcept {
108  return std::any_of(ions.begin(), ions.end(), [&name](auto const& ion) {
109  return ion.is_ionic_current(name);
110  });
111 }
112 
113 /// true if given variable name is a ionic concentration
114 bool CodegenInfo::is_ionic_conc(const std::string& name) const noexcept {
115  return std::any_of(ions.begin(), ions.end(), [&name](auto const& ion) {
116  return ion.is_ionic_conc(name);
117  });
118 }
119 
120 bool CodegenInfo::function_uses_table(const std::string& name) const noexcept {
121  return std::any_of(functions_with_table.begin(),
122  functions_with_table.end(),
123  [&name](auto const& function) { return name == function->get_node_name(); });
124 }
125 
126 /**
127  * Check if NrnState node in the AST has EigenSolverBlock node
128  *
129  * @return True if EigenSolverBlock exist in the node
130  */
131 bool CodegenInfo::nrn_state_has_eigen_solver_block() const {
132  if (nrn_state_block == nullptr) {
133  return false;
134  }
135  return !collect_nodes(*nrn_state_block, {ast::AstNodeType::EIGEN_NEWTON_SOLVER_BLOCK}).empty();
136 }
137 
138 /**
139  * Check if WatchStatement uses voltage variable v
140  *
141  * Watch statement has condition expression which could use voltage
142  * variable `v`. To avoid memory access into voltage array we check
143  * if `v` is used and then print necessary code.
144  *
145  * @return true if voltage variable b is used otherwise false
146  */
147 bool CodegenInfo::is_voltage_used_by_watch_statements() const {
148  return std::any_of(watch_statements.begin(), watch_statements.end(), [](auto const& statement) {
149  return VarUsageVisitor{}.variable_used(*statement, "v");
150  });
151 }
152 
153 } // namespace codegen
154 } // namespace nmodl
nmodl::codegen::LongitudinalDiffusionInfo::volume
std::shared_ptr< ast::Expression > volume(const std::string &index_name) const
Volume of this species.
Definition: codegen_info.cpp:32
nmodl::codegen::LongitudinalDiffusionInfo::dfcdc
double dfcdc(const std::string &) const
The value of what NEURON calls dfcdc.
Definition: codegen_info.cpp:41
nmodl::codegen::LongitudinalDiffusionInfo::rate_index_name
std::string rate_index_name
Definition: codegen_info.hpp:321
nmodl::codegen::CodegenInfo::ion_has_write_variable
bool ion_has_write_variable() const noexcept
if any ion has write variable
Definition: codegen_info.cpp:65
nmodl::codegen::LongitudinalDiffusionInfo::rate_expr
std::shared_ptr< ast::Expression > rate_expr
Definition: codegen_info.hpp:322
nmodl::codegen::CodegenInfo::ions
std::vector< Ion > ions
ions used in the mod file
Definition: codegen_info.hpp:501
nmodl::codegen::LongitudinalDiffusionInfo::volume_expr
std::shared_ptr< ast::Expression > volume_expr
Definition: codegen_info.hpp:319
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
var_usage_visitor.hpp
Check if variable is used in given block.
nmodl::codegen::LongitudinalDiffusionInfo::substitute_index
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
Definition: codegen_info.cpp:48
visitor_utils.hpp
Utility functions for visitors implementation.
nmodl::visitor::RenameVisitor
Blindly rename given variable to new name
Definition: rename_visitor.hpp:43
nmodl::codegen::CodegenInfo::is_ion_write_variable
bool is_ion_write_variable(const std::string &name) const noexcept
if given variable is ion write variable
Definition: codegen_info.cpp:73
codegen_info.hpp
Various types to store code generation specific information.
longitudinal_diffusion_block.hpp
Auto generated AST classes declaration.
nmodl::collect_nodes
std::vector< std::shared_ptr< const ast::Ast > > collect_nodes(const ast::Ast &node, const std::vector< ast::AstNodeType > &types)
traverse node recursively and collect nodes of given types
Definition: visitor_utils.cpp:206
nmodl::codegen::LongitudinalDiffusionInfo::diffusion_rate
std::shared_ptr< ast::Expression > diffusion_rate(const std::string &index_name) const
Difusion rate of this species.
Definition: codegen_info.cpp:36
nmodl::codegen::LongitudinalDiffusionInfo::volume_index_name
std::string volume_index_name
Definition: codegen_info.hpp:318
nmodl::ast::Expression
Base class for all expressions in the NMODL.
Definition: expression.hpp:43
rename_visitor.hpp
Blindly rename given variable to new name
all.hpp
Auto generated AST classes declaration.
nmodl::codegen::LongitudinalDiffusionInfo::LongitudinalDiffusionInfo
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)
Definition: codegen_info.cpp:22