Code generation fixes for array variables in TABLE statement#924
Conversation
* table statements can have array variables. Until now only
scalar variables were supported in code generation.
* we can check symbol table to find out if the variable is
an array and it's length.
* similar to mod2c implementation, generate code for array
variable assignments:
https://github.com/BlueBrain/mod2c/blob/469c74dc7d96bbc5a06a42696422154b4cd2ce28/src/mod2c_core/parsact.c#L942
* with this, `glia__dbbs_mod_collection__Cav2_3__0.mod` from #888
compiles
|
@alkino: for array variables, this is how one could use symbol table to determine how array variables needs to be printed. MOD2C does similar thing using symbol table. |
|
Logfiles from GitLab pipeline #72860 (:white_check_mark:) have been uploaded here! Status and direct links: |
Codecov Report
@@ Coverage Diff @@
## master #924 +/- ##
==========================================
- Coverage 61.46% 61.46% -0.01%
==========================================
Files 194 194
Lines 28457 28481 +24
==========================================
+ Hits 17492 17506 +14
- Misses 10965 10975 +10
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
|
We should try with range and not range variable |
You mean for testing? (i.e. using GLOBAL variable in TABLE) |
|
@alkino: I tested with NEURON {
SUFFIX glia__dbbs_mod_collection__Cav2_3__0
THREADSAFE
USEION ca READ eca WRITE ica
RANGE gcabar, m, h, g, gmax
RANGE inf, tau
GLOBAL xx
}
UNITS {
(mA) = (milliamp)
(mV) = (millivolt)
}
PARAMETER { : parameters that can be entered when function is called in cell-setup
v (mV)
celsius
gcabar = 0 (mho/cm2) : initialized conductance
xx = 1
}
....
PROCEDURE mhn(v (mV)) {
TABLE inf, tau, xx DEPEND celsius FROM -100 TO 100 WITH 200
FROM i=0 TO 1 {
tau[i] = vartau(v,i)
inf[i] = varss(v,i) + xx
}
}And generated code is reasonable / same as mod2c: /** all global variables */
struct glia__dbbs_mod_collection__Cav2_3__0_Store {
int ca_type{};
double m0{};
double h0{};
int reset{};
int mech_type{};
double xx{1};
int slist1[2]{7, 8};
int dlist1[2]{9, 10};
double usetable{1};
double tmin_mhn{};
double mfac_mhn{};
double t_inf[201]{};
double t_tau[201]{};
double t_xx[201]{};
};
/** all mechanism instance variables and global variables */
struct glia__dbbs_mod_collection__Cav2_3__0_Instance {
...
glia__dbbs_mod_collection__Cav2_3__0_Store* global{&glia__dbbs_mod_collection__Cav2_3__0_global};
};
...
inline int mhn_glia__dbbs_mod_collection__Cav2_3__0(int id, int pnodecount, glia__dbbs_mod_collection__Cav2_3__0_Instance* inst, double* data, const Datum* indexes, ThreadDatum* thread, NrnThread* nt, double v, double arg_v){
if (inst->global->usetable == 0) {
f_mhn_glia__dbbs_mod_collection__Cav2_3__0(id, pnodecount, inst, data, indexes, thread, nt, v, arg_v);
return 0;
}
double xi = inst->global->mfac_mhn * (arg_v - inst->global->tmin_mhn);
if (isnan(xi)) {
(inst->inf+id*2)[0] = xi;
(inst->inf+id*2)[1] = xi;
(inst->tau+id*2)[0] = xi;
(inst->tau+id*2)[1] = xi;
inst->global->xx = xi;
return 0;
}
if (xi <= 0. || xi >= 200.) {
int index = (xi <= 0.) ? 0 : 200;
(inst->inf+id*2)[0] = inst->global->t_inf[index];
(inst->inf+id*2)[1] = inst->global->t_inf[index];
(inst->tau+id*2)[0] = inst->global->t_tau[index];
(inst->tau+id*2)[1] = inst->global->t_tau[index];
inst->global->xx = inst->global->t_xx[index];
return 0;
}
int i = int(xi);
double theta = xi - double(i);
(inst->inf+id*2)[0] = inst->global->t_inf[i] + theta*(inst->global->t_inf[i+1]-inst->global->t_inf[i]);
(inst->inf+id*2)[1] = inst->global->t_inf[i] + theta*(inst->global->t_inf[i+1]-inst->global->t_inf[i]);
(inst->tau+id*2)[0] = inst->global->t_tau[i] + theta*(inst->global->t_tau[i+1]-inst->global->t_tau[i]);
(inst->tau+id*2)[1] = inst->global->t_tau[i] + theta*(inst->global->t_tau[i+1]-inst->global->t_tau[i]);
inst->global->xx = inst->global->t_xx[i] + theta*(inst->global->t_xx[i+1]-inst->global->t_xx[i]);
return 0;
}we don't have a good (integration) test but we will handle this once we get all issues from #888 covered (and some work with @iomaganaris about testing/code coverage aspects). |
Maybe not a bad idea to add a small example like the above to the unit tests of codegen c visitor in https://github.com/BlueBrain/nmodl/blob/master/test/unit/codegen/codegen_c_visitor.cpp? |
|
Logfiles from GitLab pipeline #73346 (:white_check_mark:) have been uploaded here! Status and direct links: |
|
Logfiles from GitLab pipeline #73369 (:white_check_mark:) have been uploaded here! Status and direct links: |
@iomaganaris : done in ec56905 |
…in/nmodl#924) * Table statements can have array variables. Until now only scalar variables were supported in code generation. * We can check symbol table to find out if the variable is an array and it's length. * Similar to mod2c implementation, generate code for array variable assignments: https://github.com/BlueBrain/mod2c/blob/469c74dc7d96bbc5a06a42696422154b4cd2ce28/src/mod2c_core/parsact.c#L942 * with this, `glia__dbbs_mod_collection__Cav2_3__0.mod` from BlueBrain/nmodl#888 compiles * Add test and fix the bug for array variables allocation and access NMODL Repo SHA: BlueBrain/nmodl@6a59caa
scalar variables were supported in code generation.
an array and it's length.
variable assignments:
https://github.com/BlueBrain/mod2c/blob/469c74dc7d96bbc5a06a42696422154b4cd2ce28/src/mod2c_core/parsact.c#L942
glia__dbbs_mod_collection__Cav2_3__0.modfrom Testing & Fixing issues with DBBS-Lab's MOD file collection #888compiles