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 <cassert>
11 #include <utility>
12 
13 #include "ast/all.hpp"
14 #include "printer/json_printer.hpp"
15 
16 
17 namespace nmodl {
18 namespace visitor {
19 
20 using printer::JSONPrinter;
21 using symtab::Symbol;
24 using utils::PerfStat;
25 
26 PerfVisitor::PerfVisitor(const std::string& filename)
27  : printer(new JSONPrinter(filename)) {}
28 
29 void PerfVisitor::compact_json(bool flag) {
30  printer->compact_json(flag);
31 }
32 
33 
34 /// count math operations from all binary expressions
36  bool assign_op = false;
37 
38  if (start_measurement) {
39  auto value = node.get_op().get_value();
40  switch (value) {
41  case ast::BOP_ADDITION:
43  break;
44 
47  break;
48 
51  break;
52 
53  case ast::BOP_DIVISION:
55  break;
56 
57  case ast::BOP_POWER:
59  break;
60 
61  case ast::BOP_AND:
63  break;
64 
65  case ast::BOP_OR:
67  break;
68 
69  case ast::BOP_GREATER:
71  break;
72 
75  break;
76 
77  case ast::BOP_LESS:
79  break;
80 
83  break;
84 
85  case ast::BOP_ASSIGN:
87  assign_op = true;
88  break;
89 
90  case ast::BOP_NOT_EQUAL:
92  break;
93 
96  break;
97 
98  default:
99  throw std::logic_error("Binary operator not handled in perf visitor");
100  }
101  }
102 
103  /// if visiting assignment expression, symbols from lhs
104  /// are written and hence need flag to track
105  if (assign_op) {
107  }
108 
109  node.get_lhs()->accept(*this);
110 
111  /// lhs is done (rhs is read only)
112  visiting_lhs_expression = false;
113 
114  node.get_rhs()->accept(*this);
115 }
116 
117 /// add performance stats to json printer
119  const auto& keys = nmodl::utils::PerfStat::keys();
120  const auto& values = perf.values();
121  assert(keys.size() == values.size());
122 
123  for (size_t i = 0; i < keys.size(); i++) {
124  printer->add_node(values[i], keys[i]);
125  }
126 }
127 
128 /** Helper function used by all ast nodes : visit all children
129  * recursively and performance stats get added on stack. Once
130  * all children visited, we get total performance by summing
131  * perfstat of all children.
132  */
134  start_measurement = true;
135 
136  node.visit_children(*this);
137 
138  PerfStat perf;
139  while (!children_blocks_perf.empty()) {
140  perf = perf + children_blocks_perf.top();
141  children_blocks_perf.pop();
142  }
143 
144  auto symtab = node.get_symbol_table();
145  if (symtab == nullptr) {
146  throw std::runtime_error("Perfvisitor : symbol table not setup for " +
147  node.get_node_type_name());
148  }
149 
150  auto name = symtab->name();
151  if (node.is_derivative_block()) {
152  name = node.get_node_type_name();
153  }
154 
155  if (printer) {
156  printer->push_block(name);
157  }
158 
159  perf.title = "Performance Statistics of " + name;
160  perf.print(stream);
161 
162  if (printer) {
163  add_perf_to_printer(perf);
164  printer->pop_block();
165  }
166 
167  start_measurement = false;
168 
169  /// clear var usage map
170  for (auto& var_set: var_usage) {
171  var_set.second.clear();
172  }
173 }
174 
175 /// count function calls and "most useful" or "commonly used" math functions
177  under_function_call = true;
178 
179  if (start_measurement) {
180  auto name = node.get_node_name();
181  if (name == "exp") {
183  } else if (name == "log") {
185  } else if (name == "pow") {
187  }
188  node.visit_children(*this);
189 
190  auto symbol = current_symtab->lookup_in_scope(name);
191  auto method_property = NmodlType::procedure_block | NmodlType::function_block;
192  if (symbol != nullptr && symbol->has_any_property(method_property)) {
194  } else {
196  }
197  }
198 
199  under_function_call = false;
200 }
201 
202 /// every variable used is of type name, update counters
205  node.visit_children(*this);
206 }
207 
208 /// prime name derived from identifier and hence need to be handled here
211  node.visit_children(*this);
212 }
213 
215  if (start_measurement) {
217  node.visit_children(*this);
218  }
219 }
220 
222  if (start_measurement) {
224  node.visit_children(*this);
225  }
226 }
227 
229  /// number of instance variables: range or assigned variables
230  /// one caveat is that the global variables appearing in
231  /// assigned block are not treated as range
233 
234  NmodlType property = NmodlType::range_var | NmodlType::assigned_definition |
235  NmodlType::state_var;
236  auto variables = current_symtab->get_variables_with_properties(property);
237 
238  for (auto& variable: variables) {
239  if (!variable->has_any_property(NmodlType::global_var)) {
241  if (variable->has_any_property(NmodlType::param_assign)) {
243  }
244  if (variable->has_any_status(Status::localized)) {
246  }
247  }
248  }
249 
250  /// state variables have state_var property
251  property = NmodlType::state_var;
252  variables = current_symtab->get_variables_with_properties(property);
253  num_state_variables = static_cast<int>(variables.size());
254 
255  /// pointer variables have pointer/bbcorepointer
256  property = NmodlType::pointer_var | NmodlType::bbcore_pointer_var;
257  variables = current_symtab->get_variables_with_properties(property);
258  num_pointer_variables = static_cast<int>(variables.size());
259 
260  /// RANDOM variables have NmodlType::random_var
261  property = NmodlType::random_var;
262  variables = current_symtab->get_variables_with_properties(property);
263  num_random_variables = static_cast<int>(variables.size());
264 
265 
266  /// number of global variables : parameters and pointers could appear also
267  /// as range variables and hence need to filter out. But if anything declared
268  /// as global is always global.
269  property = NmodlType::global_var | NmodlType::param_assign | NmodlType::bbcore_pointer_var |
270  NmodlType::pointer_var;
271  variables = current_symtab->get_variables_with_properties(property);
273  for (auto& variable: variables) {
274  auto is_global = variable->has_any_property(NmodlType::global_var);
275  property = NmodlType::range_var | NmodlType::assigned_definition;
276  if (!variable->has_any_property(property) || is_global) {
278  if (variable->has_any_property(NmodlType::param_assign)) {
280  }
281  if (variable->has_any_status(Status::localized)) {
283  }
284  }
285  }
286 }
287 
289  stream << std::endl;
290 
291  stream << "#VARIABLES :: ";
292  stream << " INSTANCE : " << num_instance_variables << " ";
293  stream << "[ CONSTANT " << num_constant_instance_variables << ", ";
294  stream << "LOCALIZED " << num_localized_instance_variables << " ]";
295 
296  stream << " GLOBAL VARIABLES : " << num_global_variables << " ";
297  stream << "[ CONSTANT " << num_constant_global_variables << ", ";
298  stream << "LOCALIZED " << num_localized_global_variables << " ]";
299 
300  stream << " STATE : " << num_state_variables;
301  stream << " POINTER : " << num_pointer_variables << std::endl;
302  stream << " RANDOM : " << num_random_variables << std::endl;
303 
304  if (printer) {
305  printer->push_block("MemoryInfo");
306 
307  printer->push_block("Instance");
308  printer->add_node(std::to_string(num_instance_variables), "total");
311  printer->pop_block();
312 
313  printer->push_block("Global");
314  printer->add_node(std::to_string(num_global_variables), "total");
315  printer->add_node(std::to_string(num_global_variables), "const");
316  printer->add_node(std::to_string(num_localized_global_variables), "localized");
317  printer->pop_block();
318 
319  printer->push_block("State");
320  printer->add_node(std::to_string(num_state_variables), "total");
321  printer->pop_block();
322 
323  printer->push_block("Pointer");
324  printer->add_node(std::to_string(num_pointer_variables), "total");
325  printer->pop_block();
326 
327  printer->push_block("RANDOM");
328  printer->add_node(std::to_string(num_random_variables), "total");
329  printer->pop_block();
330 
331  printer->pop_block();
332  }
333 }
334 
336  if (printer) {
337  printer->push_block("BlockPerf");
338  }
339 
340  node.visit_children(*this);
341  std::string title = "Total Performance Statistics";
342  total_perf.title = title;
344 
345  if (printer) {
346  printer->push_block("total");
348  printer->pop_block();
349  printer->pop_block();
350  }
351 
353  count_variables();
355 }
356 
357 /// skip initial block under net_receive block
360  measure_performance(node);
361  }
362 }
363 
365  measure_performance(node);
366 }
367 
369  measure_performance(node);
370 }
371 
373  measure_performance(node);
374 }
375 
377  measure_performance(node);
378 }
379 
381  measure_performance(node);
382 }
383 
385  measure_performance(node);
386 }
387 
389  measure_performance(node);
390 }
391 
393  measure_performance(node);
394 }
395 
397  measure_performance(node);
398 }
399 
402  measure_performance(node);
403  under_net_receive_block = false;
404 }
405 
407  measure_performance(node);
408 }
409 
411  measure_performance(node);
412 }
413 
415  measure_performance(node);
416 }
417 
419  measure_performance(node);
420 }
421 
423  measure_performance(node);
424 }
425 
427  measure_performance(node);
428 }
429 
430 /** Blocks like function can have multiple statement blocks and
431  * blocks like net receive has nested initial blocks. Hence need
432  * to maintain separate stack.
433  */
435  /// starting new block, store current state
437 
439 
440  if (current_symtab == nullptr) {
441  throw std::runtime_error("Perfvisitor : symbol table not setup for " +
442  node.get_node_type_name());
443  }
444 
445  /// new block perf starts from zero
447 
448  node.visit_children(*this);
449 
450  /// add performance of all visited children
452 
454 
455  // go back to parent block's state
457  blocks_perf.pop();
458 }
459 
460 /// solve is not a statement but could have associated block
461 /// and hence could/should not be skipped completely
462 /// we can't ignore the block because it could have associated
463 /// statement block (in theory)
465  under_solve_block = true;
466  node.visit_children(*this);
467  under_solve_block = false;
468 }
469 
471  if (start_measurement) {
472  auto value = node.get_op().get_value();
473  switch (value) {
474  case ast::UOP_NEGATION:
476  break;
477 
478  case ast::UOP_NOT:
480  break;
481 
482  default:
483  throw std::logic_error("Unary operator not handled in perf visitor");
484  }
485  }
486  node.visit_children(*this);
487 }
488 
489 /** Certain statements / symbols needs extra check while measuring
490  * read/write operations. For example, for expression "exp(a+b)",
491  * "exp" is an external math function and we should not increment read
492  * count for "exp" symbol. Same for solve statement where name will
493  * be derivative block name and neuron solver method.
494  */
495 bool PerfVisitor::symbol_to_skip(const std::shared_ptr<Symbol>& symbol) const {
496  bool skip = false;
497 
498  auto is_method = symbol->has_any_property(NmodlType::extern_method | NmodlType::function_block);
500  skip = true;
501  }
502 
503  is_method = symbol->has_any_property(NmodlType::derivative_block | NmodlType::extern_method);
504  if (is_method && under_solve_block) {
505  skip = true;
506  }
507 
508  return skip;
509 }
510 
511 bool PerfVisitor::is_local_variable(const std::shared_ptr<Symbol>& symbol) {
512  bool is_local = false;
513  /// in the function when we write to function variable then consider it as local variable
514  auto properties = NmodlType::local_var | NmodlType::argument | NmodlType::function_block;
515  if (symbol->has_any_property(properties)) {
516  is_local = true;
517  }
518  return is_local;
519 }
520 
521 bool PerfVisitor::is_constant_variable(const std::shared_ptr<Symbol>& symbol) {
522  bool is_constant = false;
523  auto properties = NmodlType::param_assign;
524  if (symbol->has_any_property(properties)) {
525  is_constant = true;
526  }
527  return is_constant;
528 }
529 
530 
531 /** Find symbol in closest scope (up to parent) and update
532  * read/write count. Also update ops count in current block.
533  */
534 void PerfVisitor::update_memory_ops(const std::string& name) {
535  if (!start_measurement || current_symtab == nullptr) {
536  return;
537  }
538 
539  auto symbol = current_symtab->lookup_in_scope(name);
540  if (symbol == nullptr || symbol_to_skip(symbol)) {
541  return;
542  }
543 
544  if (is_local_variable(symbol)) {
546  symbol->write();
548  } else {
549  symbol->read();
551  }
552  return;
553  }
554 
555  /// lhs symbols get written
557  symbol->write();
558  if (is_constant_variable(symbol)) {
560  if (var_usage[const_memw_key].find(name) == var_usage[const_memw_key].end()) {
562  var_usage[const_memw_key].insert(name);
563  }
564  } else {
566  if (var_usage[global_memw_key].find(name) == var_usage[global_memw_key].end()) {
568  var_usage[global_memw_key].insert(name);
569  }
570  }
571  return;
572  }
573 
574  /// rhs symbols get read
575  symbol->read();
576  if (is_constant_variable(symbol)) {
578  if (var_usage[const_memr_key].find(name) == var_usage[const_memr_key].end()) {
580  var_usage[const_memr_key].insert(name);
581  }
582  } else {
584  if (var_usage[global_memr_key].find(name) == var_usage[global_memr_key].end()) {
586  var_usage[global_memr_key].insert(name);
587  }
588  }
589 }
590 
591 } // namespace visitor
592 } // 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:7065
nmodl::ast::IfStatement::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:9555
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:410
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:470
nmodl::ast::Name::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:799
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:209
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:3162
nmodl::visitor::PerfVisitor::is_local_variable
static bool is_local_variable(const std::shared_ptr< symtab::Symbol > &symbol)
Definition: perf_visitor.cpp:511
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:203
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:414
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:400
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:534
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:35
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:380
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:434
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:176
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:228
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:396
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:891
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:9744
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:368
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:29
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:335
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:6729
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:464
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:282
nmodl::ast::Program::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:12906
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:521
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:4492
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:422
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:384
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:364
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:214
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:133
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:221
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:884
nmodl::ast::FunctionCall::visit_children
void visit_children(visitor::Visitor &v) override
visit children i.e.
Definition: ast.cpp:7072
nmodl::ast::Name::get_node_name
std::string get_node_name() const override
Return name of the node.
Definition: ast.cpp:795
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:418
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:376
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:495
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:406
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:388
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:426
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:288
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:118
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:358
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:392
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:163
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:372
nmodl::utils::PerfStat::n_add
int n_add
basic ops (<= 1 cycle)
Definition: perf_stat.hpp:44