8 #include <catch2/catch_test_macros.hpp>
9 #include <catch2/matchers/catch_matchers_string.hpp>
16 using namespace nmodl;
17 using namespace visitor;
27 SCENARIO(
"Symbol table generation with Perf stat visitor",
"[visitor][performance]") {
28 GIVEN(
"A mod file and associated ast") {
29 std::string nmodl_text = R
"(
32 USEION na READ ena WRITE ina
33 RANGE gNaTs2_tbar, A_AMPA_step : range + anything = range (2)
34 GLOBAL Rstate : global + anything = global
35 POINTER rng : pointer = global
36 BBCOREPOINTER coreRng : pointer + assigned = range
40 gNaTs2_tbar = 0.00001 (S/cm2) : range + parameter = range already
41 tau_r = 0.2 (ms) : parameter = global
42 tau_d_AMPA = 1.0 : parameter = global
43 tsyn_fac = 11.1 : parameter + assigned = range
47 v (mV) : only assigned = range
48 ena (mV) : only assigned = range
49 tsyn_fac : parameter + assigned = range already
50 A_AMPA_step : range + assigned = range already
51 AmState : only assigned = range
52 Rstate : global + assigned == global already
53 coreRng : pointer + assigned = range already
62 CONDUCTANCE gNaTs2_t USEION na
63 SOLVE states METHOD cnexp
67 gNaTs2_t = gNaTs2_tbar*m*m*m*h
69 ina = gNaTs2_t*(v-ena)
76 gNaTs2_tbar = gNaTs2_tbar*gNaTs2_tbar + 11.0
82 hBetaf = (-0.015 * (-v -60))/(1-(exp((-v -60)/6)))
89 WHEN(
"Symbol table generator pass runs") {
91 v.visit_program(*ast);
92 auto symtab = ast->get_model_symbol_table();
94 THEN(
"Can lookup for defined variables") {
95 auto symbol = symtab->lookup(
"m");
96 REQUIRE(symbol->has_any_property(NmodlType::assigned_definition));
97 REQUIRE_FALSE(symbol->has_any_property(NmodlType::local_var));
99 symbol = symtab->lookup(
"gNaTs2_tbar");
100 REQUIRE(symbol->has_any_property(NmodlType::param_assign));
101 REQUIRE(symbol->has_any_property(NmodlType::range_var));
103 symbol = symtab->lookup(
"ena");
104 REQUIRE(symbol->has_any_property(NmodlType::read_ion_var));
106 THEN(
"Can lookup for defined functions") {
107 auto symbol = symtab->lookup(
"hBetaf");
108 REQUIRE(symbol->has_any_property(NmodlType::function_block));
110 THEN(
"Non existent variable lookup returns nullptr") {
111 REQUIRE(symtab->lookup(
"xyz") ==
nullptr);
114 WHEN(
"Perf visitor pass runs after symtab visitor") {
116 v.visit_program(*ast);
118 auto result = v.get_total_perfstat();
119 auto num_instance_var = v.get_instance_variable_count();
120 auto num_global_var = v.get_global_variable_count();
121 auto num_state_var = v.get_state_variable_count();
122 auto num_const_instance_var = v.get_const_instance_variable_count();
123 auto num_const_global_var = v.get_const_global_variable_count();
125 THEN(
"Performance counters are updated") {
126 REQUIRE(result.n_add == 2);
127 REQUIRE(result.n_sub == 4);
128 REQUIRE(result.n_mul == 7);
129 REQUIRE(result.n_div == 3);
130 REQUIRE(result.n_exp == 1);
131 REQUIRE(result.n_global_read == 7);
132 REQUIRE(result.n_unique_global_read == 4);
133 REQUIRE(result.n_global_write == 3);
134 REQUIRE(result.n_unique_global_write == 2);
135 REQUIRE(result.n_constant_read == 4);
136 REQUIRE(result.n_unique_constant_read == 1);
137 REQUIRE(result.n_constant_write == 2);
138 REQUIRE(result.n_unique_constant_write == 1);
139 REQUIRE(result.n_local_read == 3);
140 REQUIRE(result.n_local_write == 2);
141 REQUIRE(result.n_ext_func_call == 1);
142 REQUIRE(result.n_int_func_call == 1);
143 REQUIRE(result.n_neg == 3);
144 REQUIRE(num_instance_var == 9);
145 REQUIRE(num_global_var == 4);
146 REQUIRE(num_state_var == 2);
147 REQUIRE(num_const_instance_var == 2);
148 REQUIRE(num_const_global_var == 2);
153 WHEN(
"Perf visitor pass runs before symtab visitor") {
155 THEN(
"exception is thrown") {
156 REQUIRE_THROWS_WITH(v.visit_program(*ast),
157 Catch::Matchers::ContainsSubstring(
"table not setup"));