User Guide
perf_visitor.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 <utility>
11 
12 #include "ast/all.hpp"
13 #include "printer/json_printer.hpp"
14 
15 
16 namespace nmodl {
17 namespace visitor {
18 
19 using printer::JSONPrinter;
20 using symtab::Symbol;
23 using utils::PerfStat;
24 
25 PerfVisitor::PerfVisitor(const std::string& filename)
26  : printer(new JSONPrinter(filename)) {}
27 
28 void PerfVisitor::compact_json(bool flag) {
29  printer->compact_json(flag);
30 }
31 
32 
33 /// count math operations from all binary expressions
35  bool assign_op = false;
36 
37  if (start_measurement) {
38  auto value = node.get_op().get_value();
39  switch (value) {
40  case ast::BOP_ADDITION:
42  break;
43 
46  break;
47 
50  break;
51 
52  case ast::BOP_DIVISION:
54  break;
55 
56  case ast::BOP_POWER:
58  break;
59 
60  case ast::BOP_AND:
62  break;
63 
64  case ast::BOP_OR:
66  break;
67 
68  case ast::BOP_GREATER:
70  break;
71 
74  break;
75 
76  case ast::BOP_LESS:
78  break;
79 
82  break;
83 
84  case ast::BOP_ASSIGN:
86  assign_op = true;
87  break;
88 
89  case ast::BOP_NOT_EQUAL:
91  break;
92 
95  break;
96 
97  default:
98  throw std::logic_error("Binary operator not handled in perf visitor");
99  }
100  }
101 
102  /// if visiting assignment expression, symbols from lhs
103  /// are written and hence need flag to track
104  if (assign_op) {
106  }
107 
108  node.get_lhs()->accept(*this);
109 
110  /// lhs is done (rhs is read only)
111  visiting_lhs_expression = false;
112 
113  node.get_rhs()->accept(*this);
114 }
115 
116 /// add performance stats to json printer
118  const auto& keys = nmodl::utils::PerfStat::keys();
119  const auto& values = perf.values();
120  assert(keys.size() == values.size());
121 
122  for (size_t i = 0; i < keys.size(); i++) {
123  printer->add_node(values[i], keys[i]);
124  }
125 }
126 
127 /** Helper function used by all ast nodes : visit all children
128  * recursively and performance stats get added on stack. Once
129  * all children visited, we get total performance by summing
130  * perfstat of all children.
131  */
133  start_measurement = true;
134 
135  node.visit_children(*this);
136 
137  PerfStat perf;
138  while (!children_blocks_perf.empty()) {
139  perf = perf + children_blocks_perf.top();
140  children_blocks_perf.pop();
141  }
142 
143  auto symtab = node.get_symbol_table();
144  if (symtab == nullptr) {
145  throw std::runtime_error("Perfvisitor : symbol table not setup for " +
146  node.get_node_type_name());
147  }
148 
149  auto name = symtab->name();
150  if (node.is_derivative_block()) {
151  name = node.get_node_type_name();
152  }
153 
154  if (printer) {
155  printer->push_block(name);
156  }
157 
158  perf.title = "Performance Statistics of " + name;
159  perf.print(stream);
160 
161  if (printer) {
162  add_perf_to_printer(perf);
163  printer->pop_block();
164  }
165 
166  start_measurement = false;
167 
168  /// clear var usage map
169  for (auto& var_set: var_usage) {
170  var_set.second.clear();
171  }
172 }
173 
174 /// count function calls and "most useful" or "commonly used" math functions
176  under_function_call = true;
177 
178  if (start_measurement) {
179  auto name = node.get_node_name();
180  if (name == "exp") {
182  } else if (name == "log") {
184  } else if (name == "pow") {
186  }
187  node.visit_children(*this);
188 
189  auto symbol = current_symtab->lookup_in_scope(name);
190  auto method_property = NmodlType::procedure_block | NmodlType::function_block;
191  if (symbol != nullptr && symbol->has_any_property(method_property)) {
193  } else {
195  }
196  }
197 
198  under_function_call = false;
199 }
200 
201 /// every variable used is of type name, update counters
204  node.visit_children(*this);
205 }
206 
207 /// prime name derived from identifier and hence need to be handled here
210  node.visit_children(*this);
211 }
212 
214  if (start_measurement) {
216  node.visit_children(*this);
217  }
218 }
219 
221  if (start_measurement) {
223  node.visit_children(*this);
224  }
225 }
226 
228  /// number of instance variables: range or assigned variables
229  /// one caveat is that the global variables appearing in
230  /// assigned block are not treated as range
232 
233  NmodlType property = NmodlType::range_var | NmodlType::assigned_definition |
234  NmodlType::state_var;
235  auto variables = current_symtab->get_variables_with_properties(property);
236 
237  for (auto& variable: variables) {
238  if (!variable->has_any_property(NmodlType::global_var)) {
240  if (variable->has_any_property(NmodlType::param_assign)) {
242  }
243  if (variable->has_any_status(Status::localized)) {
245  }
246  }
247  }
248 
249  /// state variables have state_var property
250  property = NmodlType::state_var;
251  variables = current_symtab->get_variables_with_properties(property);
252  num_state_variables = static_cast<int>(variables.size());
253 
254  /// pointer variables have pointer/bbcorepointer
255  property = NmodlType::pointer_var | NmodlType::bbcore_pointer_var;
256  variables = current_symtab->get_variables_with_properties(property);
257  num_pointer_variables = static_cast<int>(variables.size());
258 
259  /// RANDOM variables have NmodlType::random_var
260  property = NmodlType::random_var;
261  variables = current_symtab->get_variables_with_properties(property);
262  num_random_variables = static_cast<int>(variables.size());
263 
264 
265  /// number of global variables : parameters and pointers could appear also
266  /// as range variables and hence need to filter out. But if anything declared
267  /// as global is always global.
268  property = NmodlType::global_var | NmodlType::param_assign | NmodlType::bbcore_pointer_var |
269  NmodlType::pointer_var;
270  variables = current_symtab->get_variables_with_properties(property);
272  for (auto& variable: variables) {
273  auto is_global = variable->has_any_property(NmodlType::global_var);
274  property = NmodlType::range_var | NmodlType::assigned_definition;
275  if (!variable->has_any_property(property) || is_global) {
277  if (variable->has_any_property(NmodlType::param_assign)) {
279  }
280  if (variable->has_any_status(Status::localized)) {
282  }
283  }
284  }
285 }
286 
288  stream << std::endl;
289 
290  stream << "#VARIABLES :: ";
291  stream << " INSTANCE : " << num_instance_variables << " ";
292  stream << "[ CONSTANT " << num_constant_instance_variables << ", ";
293  stream << "LOCALIZED " << num_localized_instance_variables << " ]";
294 
295  stream << " GLOBAL VARIABLES : " << num_global_variables << " ";
296  stream << "[ CONSTANT " << num_constant_global_variables << ", ";
297  stream << "LOCALIZED " << num_localized_global_variables << " ]";
298 
299  stream << " STATE : " << num_state_variables;
300  stream << " POINTER : " << num_pointer_variables << std::endl;
301  stream << " RANDOM : " << num_random_variables << std::endl;
302 
303  if (printer) {
304  printer->push_block("MemoryInfo");
305 
306  printer->push_block("Instance");
307  printer->add_node(std::to_string(num_instance_variables), "total");
310  printer->pop_block();
311 
312  printer->push_block("Global");
313  printer->add_node(std::to_string(num_global_variables), "total");
314  printer->add_node(std::to_string(num_global_variables), "const");
315  printer->add_node(std::to_string(num_localized_global_variables), "localized");
316  printer->pop_block();
317 
318  printer->push_block("State");
319  printer->add_node(std::to_string(num_state_variables), "total");
320  printer->pop_block();
321 
322  printer->push_block("Pointer");
323  printer->add_node(std::to_string(num_pointer_variables), "total");
324  printer->pop_block();
325 
326  printer->push_block("RANDOM");
327  printer->add_node(std::to_string(num_random_variables), "total");
328  printer->pop_block();
329 
330  printer->pop_block();
331  }
332 }
333 
335  if (printer) {
336  printer->push_block("BlockPerf");
337  }
338 
339  node.visit_children(*this);
340  std::string title = "Total Performance Statistics";
341  total_perf.title = title;
343 
344  if (printer) {
345  printer->push_block("total");
347  printer->pop_block();
348  printer->pop_block();
349  }
350 
352  count_variables();
354 }
355 
356 /// skip initial block under net_receive block
359  measure_performance(node);
360  }
361 }
362 
364  measure_performance(node);
365 }
366 
368  measure_performance(node);
369 }
370 
372  measure_performance(node);
373 }
374 
376  measure_performance(node);
377 }
378 
380  measure_performance(node);
381 }
382 
384  measure_performance(node);
385 }
386 
388  measure_performance(node);
389 }
390 
392  measure_performance(node);
393 }
394 
396  measure_performance(node);
397 }
398 
401  measure_performance(node);
402  under_net_receive_block = false;
403 }
404 
406  measure_performance(node);
407 }
408 
410  measure_performance(node);
411 }
412 
414  measure_performance(node);
415 }
416 
418  measure_performance(node);
419 }
420 
422  measure_performance(node);
423 }
424 
426  measure_performance(node);
427 }
428 
429 /** Blocks like function can have multiple statement blocks and
430  * blocks like net receive has nested initial blocks. Hence need
431  * to maintain separate stack.
432  */
434  /// starting new block, store current state
436 
438 
439  if (current_symtab == nullptr) {
440  throw std::runtime_error("Perfvisitor : symbol table not setup for " +
441  node.get_node_type_name());
442  }
443 
444  /// new block perf starts from zero
446 
447  node.visit_children(*this);
448 
449  /// add performance of all visited children
451 
453 
454  // go back to parent block's state
456  blocks_perf.pop();
457 }
458 
459 /// solve is not a statement but could have associated block
460 /// and hence could/should not be skipped completely
461 /// we can't ignore the block because it could have associated
462 /// statement block (in theory)
464  under_solve_block = true;
465  node.visit_children(*this);
466  under_solve_block = false;
467 }
468 
470  if (start_measurement) {
471  auto value = node.get_op().get_value();
472  switch (value) {
473  case ast::UOP_NEGATION:
475  break;
476 
477  case ast::UOP_NOT:
479  break;
480 
481  default:
482  throw std::logic_error("Unary operator not handled in perf visitor");
483  }
484  }
485  node.visit_children(*this);
486 }
487 
488 /** Certain statements / symbols needs extra check while measuring
489  * read/write operations. For example, for expression "exp(a+b)",
490  * "exp" is an external math function and we should not increment read
491  * count for "exp" symbol. Same for solve statement where name will
492  * be derivative block name and neuron solver method.
493  */
494 bool PerfVisitor::symbol_to_skip(const std::shared_ptr<Symbol>& symbol) const {
495  bool skip = false;
496 
497  auto is_method = symbol->has_any_property(NmodlType::extern_method | NmodlType::function_block);
499  skip = true;
500  }
501 
502  is_method = symbol->has_any_property(NmodlType::derivative_block | NmodlType::extern_method);
503  if (is_method && under_solve_block) {
504  skip = true;
505  }
506 
507  return skip;
508 }
509 
510 bool PerfVisitor::is_local_variable(const std::shared_ptr<Symbol>& symbol) {
511  bool is_local = false;
512  /// in the function when we write to function variable then consider it as local variable
513  auto properties = NmodlType::local_var | NmodlType::argument | NmodlType::function_block;
514  if (symbol->has_any_property(properties)) {
515  is_local = true;
516  }
517  return is_local;
518 }
519 
520 bool PerfVisitor::is_constant_variable(const std::shared_ptr<Symbol>& symbol) {
521  bool is_constant = false;
522  auto properties = NmodlType::param_assign;
523  if (symbol->has_any_property(properties)) {
524  is_constant = true;
525  }
526  return is_constant;
527 }
528 
529 
530 /** Find symbol in closest scope (up to parent) and update
531  * read/write count. Also update ops count in current block.
532  */
533 void PerfVisitor::update_memory_ops(const std::string& name) {
534  if (!start_measurement || current_symtab == nullptr) {
535  return;
536  }
537 
538  auto symbol = current_symtab->lookup_in_scope(name);
539  if (symbol == nullptr || symbol_to_skip(symbol)) {
540  return;
541  }
542 
543  if (is_local_variable(symbol)) {
545  symbol->write();
547  } else {
548  symbol->read();
550  }
551  return;
552  }
553 
554  /// lhs symbols get written
556  symbol->write();
557  if (is_constant_variable(symbol)) {
559  if (var_usage[const_memw_key].find(name) == var_usage[const_memw_key].end()) {
561  var_usage[const_memw_key].insert(name);
562  }
563  } else {
565  if (var_usage[global_memw_key].find(name) == var_usage[global_memw_key].end()) {
567  var_usage[global_memw_key].insert(name);
568  }
569  }
570  return;
571  }
572 
573  /// rhs symbols get read
574  symbol->read();
575  if (is_constant_variable(symbol)) {
577  if (var_usage[const_memr_key].find(name) == var_usage[const_memr_key].end()) {
579  var_usage[const_memr_key].insert(name);
580  }
581  } else {
583  if (var_usage[global_memr_key].find(name) == var_usage[global_memr_key].end()) {
585  var_usage[global_memr_key].insert(name);
586  }
587  }
588 }
589 
590 } // namespace visitor
591 } // namespace nmodl
nmodl::ast::BOP_GREATER_EQUAL
@ BOP_GREATER_EQUAL
>=
Definition: ast_common.hpp:57
nmodl::ast::FunctionCall::get_node_name
std::string get_node_name() const override
Return name of the node.
Definition: ast.cpp:7061
nmodl::ast::IfStatement::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:9551
nmodl::utils::PerfStat::n_pow
int n_pow
Definition: perf_stat.hpp:55
nmodl::visitor::PerfVisitor::visit_before_block
void visit_before_block(const ast::BeforeBlock &node) override
visit node of type ast::BeforeBlock
Definition: perf_visitor.cpp:409
nmodl::ast::BeforeBlock
Represents a BEFORE block in NMODL.
Definition: before_block.hpp:38
nmodl::visitor::PerfVisitor::under_function_call
bool under_function_call
whether function call is being visited
Definition: perf_visitor.hpp:84
nmodl::ast::SolveBlock
TODO.
Definition: solve_block.hpp:38
nmodl::ast::BABlock
Represents a block to be executed before or after another block.
Definition: ba_block.hpp:40
nmodl::visitor::PerfVisitor::var_usage
std::map< std::string, std::set< std::string > > var_usage
map of variables to count unique read-writes
Definition: perf_visitor.hpp:132
nmodl::visitor::PerfVisitor::visit_unary_expression
void visit_unary_expression(const ast::UnaryExpression &node) override
visit node of type ast::UnaryExpression
Definition: perf_visitor.cpp:469
nmodl::ast::Name::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:795
nmodl::utils::PerfStat::n_sub
int n_sub
Definition: perf_stat.hpp:45
nmodl::utils::PerfStat::n_ext_func_call
int n_ext_func_call
could be external math funcs
Definition: perf_stat.hpp:58
nmodl::ast::BOP_LESS
@ BOP_LESS
<
Definition: ast_common.hpp:56
perf_visitor.hpp
Visitor for measuring performance related information
nmodl::ast::Ast
Base class for all Abstract Syntax Tree node types.
Definition: ast.hpp:69
nmodl::visitor::PerfVisitor::visit_prime_name
void visit_prime_name(const ast::PrimeName &node) override
prime name derived from identifier and hence need to be handled here
Definition: perf_visitor.cpp:208
nmodl::visitor::PerfVisitor::num_state_variables
int num_state_variables
count of state variables
Definition: perf_visitor.hpp:117
nmodl::ast::BOP_POWER
@ BOP_POWER
^
Definition: ast_common.hpp:52
nmodl::ast::FunctionBlock
TODO.
Definition: function_block.hpp:39
nmodl::utils::PerfStat::values
std::vector< std::string > values() const
Definition: perf_stat.cpp:82
nmodl::utils::PerfStat::n_assign
int n_assign
write ops
Definition: perf_stat.hpp:41
nmodl::visitor::PerfVisitor::children_blocks_perf
std::stack< utils::PerfStat > children_blocks_perf
performance of current all childrens
Definition: perf_visitor.hpp:74
nmodl::utils::PerfStat::n_not
int n_not
unary ops
Definition: perf_stat.hpp:76
nmodl::visitor::PerfVisitor::global_memr_key
std::string global_memr_key
Definition: perf_visitor.hpp:128
nmodl::ast::NetReceiveBlock
TODO.
Definition: net_receive_block.hpp:39
nmodl::utils::PerfStat::n_neg
int n_neg
Definition: perf_stat.hpp:77
nmodl::ast::FunctionTableBlock
TODO.
Definition: function_table_block.hpp:39
nmodl::ast::StatementBlock::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:3158
nmodl::visitor::PerfVisitor::is_local_variable
static bool is_local_variable(const std::shared_ptr< symtab::Symbol > &symbol)
Definition: perf_visitor.cpp:510
nmodl::visitor::PerfVisitor::visit_name
void visit_name(const ast::Name &node) override
every variable used is of type name, update counters
Definition: perf_visitor.cpp:202
nmodl::visitor::PerfVisitor::global_memw_key
std::string global_memw_key
Definition: perf_visitor.hpp:129
nmodl::utils::PerfStat::n_elif
int n_elif
Definition: perf_stat.hpp:81
nmodl::utils::PerfStat::n_le
int n_le
Definition: perf_stat.hpp:71
nmodl::utils::PerfStat::n_unique_global_read
int n_unique_global_read
Definition: perf_stat.hpp:86
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
nmodl::visitor::PerfVisitor::visit_after_block
void visit_after_block(const ast::AfterBlock &node) override
visit node of type ast::AfterBlock
Definition: perf_visitor.cpp:413
nmodl::ast::UOP_NEGATION
@ UOP_NEGATION
Definition: ast_common.hpp:74
nmodl::utils::PerfStat::n_constant_write
int n_constant_write
Definition: perf_stat.hpp:96
nmodl::visitor::PerfVisitor::num_constant_instance_variables
int num_constant_instance_variables
subset of instance variables which are constant
Definition: perf_visitor.hpp:102
nmodl::visitor::PerfVisitor::visit_net_receive_block
void visit_net_receive_block(const ast::NetReceiveBlock &node) override
visit node of type ast::NetReceiveBlock
Definition: perf_visitor.cpp:399
nmodl::utils::PerfStat::keys
static std::vector< std::string > keys()
Definition: perf_stat.cpp:76
nmodl::utils::PerfStat::n_if
int n_if
conditional ops
Definition: perf_stat.hpp:80
nmodl::symtab::SymbolTable::get_variables_with_properties
std::vector< std::shared_ptr< Symbol > > get_variables_with_properties(syminfo::NmodlType properties, bool all=false) const
get variables with properties
Definition: symbol_table.cpp:88
nmodl::visitor::PerfVisitor::update_memory_ops
void update_memory_ops(const std::string &name)
Find symbol in closest scope (up to parent) and update read/write count.
Definition: perf_visitor.cpp:533
nmodl::visitor::PerfVisitor::const_memr_key
std::string const_memr_key
keys used in map to track var usage
Definition: perf_visitor.hpp:126
nmodl::visitor::PerfVisitor::visit_binary_expression
void visit_binary_expression(const ast::BinaryExpression &node) override
count math operations from all binary expressions
Definition: perf_visitor.cpp:34
nmodl::utils::PerfStat::n_ee
int n_ee
Definition: perf_stat.hpp:73
nmodl::symtab::syminfo::Status
Status
state during various compiler passes
Definition: symbol_properties.hpp:54
nmodl::visitor::PerfVisitor::visit_non_linear_block
void visit_non_linear_block(const ast::NonLinearBlock &node) override
visit node of type ast::NonLinearBlock
Definition: perf_visitor.cpp:379
nmodl::ast::ElseIfStatement
TODO.
Definition: else_if_statement.hpp:38
nmodl::visitor::PerfVisitor::visit_statement_block
void visit_statement_block(const ast::StatementBlock &node) override
Blocks like function can have multiple statement blocks and blocks like net receive has nested initia...
Definition: perf_visitor.cpp:433
nmodl::visitor::PerfVisitor::current_symtab
symtab::SymbolTable * current_symtab
symbol table of current block being visited
Definition: perf_visitor.hpp:61
nmodl::ast::BOP_ASSIGN
@ BOP_ASSIGN
=
Definition: ast_common.hpp:59
nmodl::ast::BOP_SUBTRACTION
@ BOP_SUBTRACTION
Definition: ast_common.hpp:49
nmodl::ast::UOP_NOT
@ UOP_NOT
Definition: ast_common.hpp:74
nmodl::visitor::PerfVisitor::visit_function_call
void visit_function_call(const ast::FunctionCall &node) override
count function calls and "most useful" or "commonly used" math functions
Definition: perf_visitor.cpp:175
nmodl::visitor::PerfVisitor::num_instance_variables
int num_instance_variables
count of per channel instance variables
Definition: perf_visitor.hpp:99
nmodl::visitor::PerfVisitor::count_variables
void count_variables()
Definition: perf_visitor.cpp:227
nmodl::visitor::PerfVisitor::visit_procedure_block
void visit_procedure_block(const ast::ProcedureBlock &node) override
visit node of type ast::ProcedureBlock
Definition: perf_visitor.cpp:395
json_printer.hpp
Helper class for printing AST in JSON form.
nmodl::ast::BinaryExpression::get_rhs
std::shared_ptr< Expression > get_rhs() const noexcept
Getter for member variable BinaryExpression::rhs.
Definition: binary_expression.hpp:179
nmodl::utils::PerfStat::n_global_read
int n_global_read
expensive : typically access to dynamically allocated memory
Definition: perf_stat.hpp:84
nmodl::ast::PrimeName::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:887
nmodl::ast::BOP_EXACT_EQUAL
@ BOP_EXACT_EQUAL
==
Definition: ast_common.hpp:61
nmodl::ast::ElseIfStatement::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:9740
nmodl::ast::InitialBlock
Represents a INITIAL block in the NMODL.
Definition: initial_block.hpp:49
nmodl::visitor::PerfVisitor::PerfVisitor
PerfVisitor()=default
nmodl::utils::PerfStat::n_unique_constant_write
int n_unique_constant_write
Definition: perf_stat.hpp:98
nmodl::visitor::PerfVisitor::visit_destructor_block
void visit_destructor_block(const ast::DestructorBlock &node) override
visit node of type ast::DestructorBlock
Definition: perf_visitor.cpp:367
nmodl::visitor::PerfVisitor::visiting_lhs_expression
bool visiting_lhs_expression
true while visiting lhs of binary expression (to count write operations)
Definition: perf_visitor.hpp:81
nmodl::ast::DiscreteBlock
TODO.
Definition: discrete_block.hpp:38
nmodl::visitor::PerfVisitor::compact_json
void compact_json(bool flag)
Definition: perf_visitor.cpp:28
nmodl::visitor::PerfVisitor::printer
std::unique_ptr< printer::JSONPrinter > printer
to print to json file
Definition: perf_visitor.hpp:93
nmodl::ast::BOP_OR
@ BOP_OR
||
Definition: ast_common.hpp:54
nmodl::printer::JSONPrinter
Helper class for printing AST in JSON form.
Definition: json_printer.hpp:46
nmodl::ast::UnaryOperator::get_value
UnaryOp get_value() const noexcept
Getter for member variable UnaryOperator::value.
Definition: unary_operator.hpp:143
nmodl::ast::BreakpointBlock
Represents a BREAKPOINT block in NMODL.
Definition: breakpoint_block.hpp:53
nmodl::ast::Ast::get_node_type_name
virtual std::string get_node_type_name() const =0
Return type (ast::AstNodeType) of ast node as std::string.
nmodl::visitor::PerfVisitor::visit_program
void visit_program(const ast::Program &node) override
visit node of type ast::Program
Definition: perf_visitor.cpp:334
nmodl::ast::Ast::get_symbol_table
virtual symtab::SymbolTable * get_symbol_table() const
Return associated symbol table for the AST node.
Definition: ast.cpp:38
nmodl::is_method
bool is_method(const std::string &name)
Check if given name is an integration method in NMODL.
Definition: token_mapping.cpp:274
nmodl::ast::BOP_ADDITION
@ BOP_ADDITION
+
Definition: ast_common.hpp:48
nmodl::utils::PerfStat::n_ge
int n_ge
Definition: perf_stat.hpp:70
nmodl::utils::PerfStat::n_lt
int n_lt
Definition: perf_stat.hpp:69
nmodl::ast::FunctionCall
TODO.
Definition: function_call.hpp:38
nmodl::ast::DestructorBlock
Represents a DESTRUCTOR block in the NMODL.
Definition: destructor_block.hpp:53
nmodl::utils::PerfStat::n_ne
int n_ne
Definition: perf_stat.hpp:72
nmodl::ast::UnaryExpression::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:6725
nmodl::visitor::PerfVisitor::start_measurement
bool start_measurement
whether to measure performance for current block
Definition: perf_visitor.hpp:77
nmodl::ast::ConstructorBlock
Represents a CONSTRUCTOR block in the NMODL.
Definition: constructor_block.hpp:51
nmodl::ast::StatementBlock::get_symbol_table
symtab::SymbolTable * get_symbol_table() const override
Return associated symbol table for the current ast node.
Definition: statement_block.hpp:164
nmodl::ast::BOP_DIVISION
@ BOP_DIVISION
\/
Definition: ast_common.hpp:51
nmodl::utils::PerfStat::n_log
int n_log
Definition: perf_stat.hpp:54
nmodl::ast::BOP_MULTIPLICATION
@ BOP_MULTIPLICATION
*
Definition: ast_common.hpp:50
nmodl::visitor::PerfVisitor::visit_solve_block
void visit_solve_block(const ast::SolveBlock &node) override
solve is not a statement but could have associated block and hence could/should not be skipped comple...
Definition: perf_visitor.cpp:463
nmodl::utils::PerfStat::print
void print(std::stringstream &stream) const
Definition: perf_stat.cpp:66
nmodl::utils::PerfStat::n_local_read
int n_local_read
cheap : typically local variables in mod file means registers
Definition: perf_stat.hpp:90
nmodl::symtab::syminfo::to_string
std::string to_string(const T &obj)
Definition: symbol_properties.hpp:279
nmodl::ast::Program::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:12902
nmodl::ast::UnaryExpression
TODO.
Definition: unary_expression.hpp:39
nmodl::visitor::PerfVisitor::is_constant_variable
static bool is_constant_variable(const std::shared_ptr< symtab::Symbol > &symbol)
Definition: perf_visitor.cpp:520
nmodl::utils::PerfStat::n_constant_read
int n_constant_read
could be optimized : access to variables that could be read-only in this case write counts are typica...
Definition: perf_stat.hpp:95
nmodl::utils::PerfStat::n_or
int n_or
Definition: perf_stat.hpp:65
nmodl::ast::SolveBlock::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:4488
nmodl::ast::UnaryExpression::get_op
const UnaryOperator & get_op() const noexcept
Getter for member variable UnaryExpression::op.
Definition: unary_expression.hpp:146
nmodl::visitor::PerfVisitor::under_net_receive_block
bool under_net_receive_block
whether net receive block is being visited
Definition: perf_visitor.hpp:90
nmodl::ast::BinaryExpression::get_op
const BinaryOperator & get_op() const noexcept
Getter for member variable BinaryExpression::op.
Definition: binary_expression.hpp:170
nmodl::visitor::PerfVisitor::num_localized_global_variables
int num_localized_global_variables
subset of global variables which are localized
Definition: perf_visitor.hpp:114
nmodl::ast::PrimeName
Represents a prime variable (for ODE)
Definition: prime_name.hpp:48
nmodl::ast::DerivativeBlock
Represents DERIVATIVE block in the NMODL.
Definition: derivative_block.hpp:49
nmodl::utils::PerfStat::n_gt
int n_gt
comparisons ops
Definition: perf_stat.hpp:68
nmodl::ast::IfStatement
TODO.
Definition: if_statement.hpp:39
nmodl::visitor::PerfVisitor::visit_for_netcon
void visit_for_netcon(const ast::ForNetcon &node) override
visit node of type ast::ForNetcon
Definition: perf_visitor.cpp:421
nmodl::ast::KineticBlock
TODO.
Definition: kinetic_block.hpp:39
nmodl::utils::PerfStat::n_local_write
int n_local_write
Definition: perf_stat.hpp:91
nmodl::visitor::PerfVisitor::visit_discrete_block
void visit_discrete_block(const ast::DiscreteBlock &node) override
visit node of type ast::DiscreteBlock
Definition: perf_visitor.cpp:383
nmodl::utils::PerfStat::n_global_write
int n_global_write
Definition: perf_stat.hpp:85
nmodl::visitor::PerfVisitor::visit_constructor_block
void visit_constructor_block(const ast::ConstructorBlock &node) override
visit node of type ast::ConstructorBlock
Definition: perf_visitor.cpp:363
nmodl::ast::BOP_LESS_EQUAL
@ BOP_LESS_EQUAL
<=
Definition: ast_common.hpp:58
nmodl::visitor::PerfVisitor::visit_if_statement
void visit_if_statement(const ast::IfStatement &node) override
visit node of type ast::IfStatement
Definition: perf_visitor.cpp:213
nmodl::ast::StatementBlock
Represents block encapsulating list of statements.
Definition: statement_block.hpp:53
nmodl::visitor::PerfVisitor::measure_performance
void measure_performance(const ast::Ast &node)
Helper function used by all ast nodes : visit all children recursively and performance stats get adde...
Definition: perf_visitor.cpp:132
nmodl::symtab::syminfo::NmodlType
NmodlType
NMODL variable properties.
Definition: symbol_properties.hpp:116
nmodl::ast::ForNetcon
TODO.
Definition: for_netcon.hpp:39
nmodl::visitor::PerfVisitor::visit_else_if_statement
void visit_else_if_statement(const ast::ElseIfStatement &node) override
visit node of type ast::ElseIfStatement
Definition: perf_visitor.cpp:220
nmodl::visitor::PerfVisitor::num_pointer_variables
int num_pointer_variables
count of pointer / bbcorepointer variables
Definition: perf_visitor.hpp:120
nmodl::ast::BOP_AND
@ BOP_AND
&&
Definition: ast_common.hpp:53
nmodl::visitor::PerfVisitor::blocks_perf
std::stack< utils::PerfStat > blocks_perf
performance stats of all blocks being visited in recursive chain
Definition: perf_visitor.hpp:65
nmodl::ast::LinearBlock
Represents LINEAR block in the NMODL.
Definition: linear_block.hpp:53
nmodl::visitor::PerfVisitor::num_global_variables
int num_global_variables
count of global variables
Definition: perf_visitor.hpp:108
nmodl::visitor::PerfVisitor::num_localized_instance_variables
int num_localized_instance_variables
subset of instance variables which are localized
Definition: perf_visitor.hpp:105
nmodl::ast::ProcedureBlock
TODO.
Definition: procedure_block.hpp:39
nmodl::ast::PrimeName::get_node_name
std::string get_node_name() const override
Return name of the node.
Definition: ast.cpp:880
nmodl::ast::FunctionCall::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:7068
nmodl::ast::Name::get_node_name
std::string get_node_name() const override
Return name of the node.
Definition: ast.cpp:791
nmodl::ast::BinaryOperator::get_value
BinaryOp get_value() const noexcept
Getter for member variable BinaryOperator::value.
Definition: binary_operator.hpp:143
nmodl::ast::NonLinearBlock
Represents NONLINEAR block in the NMODL.
Definition: non_linear_block.hpp:50
nmodl::visitor::PerfVisitor::under_solve_block
bool under_solve_block
whether solve block is being visited
Definition: perf_visitor.hpp:87
nmodl::utils::PerfStat::n_div
int n_div
expensive ops
Definition: perf_stat.hpp:49
nmodl::utils::PerfStat::n_and
int n_and
bitwise ops
Definition: perf_stat.hpp:64
nmodl::visitor::PerfVisitor::stream
std::stringstream stream
if not json, all goes to string
Definition: perf_visitor.hpp:96
nmodl::utils::PerfStat::n_int_func_call
int n_int_func_call
mod functions (before/after inlining)
Definition: perf_stat.hpp:61
nmodl::visitor::PerfVisitor::current_block_perf
utils::PerfStat current_block_perf
performance of current block
Definition: perf_visitor.hpp:71
nmodl::visitor::PerfVisitor::visit_ba_block
void visit_ba_block(const ast::BABlock &node) override
visit node of type ast::BABlock
Definition: perf_visitor.cpp:417
nmodl::ast::Program::get_symbol_table
symtab::SymbolTable * get_symbol_table() const override
Return associated symbol table for the current ast node.
Definition: program.hpp:153
nmodl::visitor::PerfVisitor::visit_linear_block
void visit_linear_block(const ast::LinearBlock &node) override
visit node of type ast::LinearBlock
Definition: perf_visitor.cpp:375
nmodl::visitor::PerfVisitor::symbol_to_skip
bool symbol_to_skip(const std::shared_ptr< symtab::Symbol > &symbol) const
Certain statements / symbols needs extra check while measuring read/write operations.
Definition: perf_visitor.cpp:494
nmodl::visitor::PerfVisitor::visit_breakpoint_block
void visit_breakpoint_block(const ast::BreakpointBlock &node) override
visit node of type ast::BreakpointBlock
Definition: perf_visitor.cpp:405
nmodl::ast::BinaryExpression::get_lhs
std::shared_ptr< Expression > get_lhs() const noexcept
Getter for member variable BinaryExpression::lhs.
Definition: binary_expression.hpp:161
nmodl::visitor::PerfVisitor::total_perf
utils::PerfStat total_perf
total performance of mod file
Definition: perf_visitor.hpp:68
nmodl::ast::StatementBlock::get_node_type_name
std::string get_node_type_name() const noexcept override
Return type (ast::AstNodeType) of ast node as std::string.
Definition: statement_block.hpp:122
nmodl::utils::PerfStat
Helper class to collect performance statistics.
Definition: perf_stat.hpp:36
nmodl::ast::Name
Represents a name.
Definition: name.hpp:44
nmodl::ast::BOP_NOT_EQUAL
@ BOP_NOT_EQUAL
!=
Definition: ast_common.hpp:60
nmodl::ast::Program
Represents top level AST node for whole NMODL input.
Definition: program.hpp:39
nmodl::visitor::PerfVisitor::visit_function_table_block
void visit_function_table_block(const ast::FunctionTableBlock &node) override
visit node of type ast::FunctionTableBlock
Definition: perf_visitor.cpp:387
nmodl::visitor::PerfVisitor::num_constant_global_variables
int num_constant_global_variables
subset of global variables which are constant
Definition: perf_visitor.hpp:111
nmodl::visitor::PerfVisitor::const_memw_key
std::string const_memw_key
Definition: perf_visitor.hpp:127
nmodl::ast::AfterBlock
Represents a AFTER block in NMODL.
Definition: after_block.hpp:51
nmodl::utils::PerfStat::n_mul
int n_mul
Definition: perf_stat.hpp:46
nmodl::visitor::PerfVisitor::num_random_variables
int num_random_variables
count of RANDOM variables
Definition: perf_visitor.hpp:123
nmodl::visitor::PerfVisitor::visit_kinetic_block
void visit_kinetic_block(const ast::KineticBlock &node) override
visit node of type ast::KineticBlock
Definition: perf_visitor.cpp:425
nmodl::utils::PerfStat::n_unique_global_write
int n_unique_global_write
Definition: perf_stat.hpp:87
nmodl::visitor::PerfVisitor::print_memory_usage
void print_memory_usage()
Definition: perf_visitor.cpp:287
nmodl::ast::Ast::visit_children
virtual void visit_children(visitor::Visitor &v)=0
Visit children i.e.
nmodl::visitor::PerfVisitor::add_perf_to_printer
void add_perf_to_printer(const utils::PerfStat &perf) const
add performance stats to json printer
Definition: perf_visitor.cpp:117
nmodl::ast::BinaryExpression
Represents binary expression in the NMODL.
Definition: binary_expression.hpp:52
nmodl::visitor::PerfVisitor::visit_initial_block
void visit_initial_block(const ast::InitialBlock &node) override
skip initial block under net_receive block
Definition: perf_visitor.cpp:357
nmodl::utils::PerfStat::title
std::string title
name for pretty-printing
Definition: perf_stat.hpp:38
nmodl::ast::Ast::is_derivative_block
virtual bool is_derivative_block() const noexcept
Check if the ast node is an instance of ast::DerivativeBlock.
Definition: ast.cpp:132
nmodl::utils::PerfStat::n_exp
int n_exp
expensive functions : commonly used functions in mod files
Definition: perf_stat.hpp:53
nmodl::visitor::PerfVisitor::visit_function_block
void visit_function_block(const ast::FunctionBlock &node) override
visit node of type ast::FunctionBlock
Definition: perf_visitor.cpp:391
all.hpp
Auto generated AST classes declaration.
nmodl::utils::PerfStat::n_unique_constant_read
int n_unique_constant_read
Definition: perf_stat.hpp:97
nmodl::symtab::SymbolTable::lookup_in_scope
std::shared_ptr< Symbol > lookup_in_scope(const std::string &name) const
check if symbol with given name exist in the current table (including all parents)
Definition: symbol_table.cpp:164
nmodl::ast::BOP_GREATER
@ BOP_GREATER
Definition: ast_common.hpp:55
nmodl::visitor::PerfVisitor::visit_derivative_block
void visit_derivative_block(const ast::DerivativeBlock &node) override
visit node of type ast::DerivativeBlock
Definition: perf_visitor.cpp:371
nmodl::utils::PerfStat::n_add
int n_add
basic ops (<= 1 cycle)
Definition: perf_stat.hpp:44