While investigating #678 we noticed that NMODL generates slightly different logic for WATCH statements than MOD2C. This does not affect the results of the testcorenrn_watch test in the NEURON CTest suite, but it may still be an issue that needs to be resolved.
The following diff modifies the code generated by NMODL to match the logic from MOD2C:
--- hhwatch-original.cpp 2021-06-01 09:31:52.879278000 +0200
+++ hhwatch-patched.cpp 2021-06-01 09:27:37.270874000 +0200
@@ -291,49 +292,47 @@
if (v > -55.0) {
if ((inst->watch1[4*pnodecount+id]&1) == 0) {
net_send_buffering(ml->_net_send_buffer, 0, inst->tqitem[2*pnodecount+id], 0, inst->point_process[1*pnodecount+id], nt->_t+0.0, 2.0);
- inst->watch1[4*pnodecount+id] = 3;
- }
- else {
- inst->watch1[4*pnodecount+id] = 2;
}
+ inst->watch1[4*pnodecount+id] = 3;
+ } else {
+ inst->watch1[4*pnodecount+id] = 2;
}
}
if (inst->watch2[5*pnodecount+id]&2) {
if (v > 10.0) {
if ((inst->watch2[5*pnodecount+id]&1) == 0) {
net_send_buffering(ml->_net_send_buffer, 0, inst->tqitem[2*pnodecount+id], 0, inst->point_process[1*pnodecount+id], nt->_t+0.0, 3.0);
- inst->watch2[5*pnodecount+id] = 3;
- }
- else {
- inst->watch2[5*pnodecount+id] = 2;
}
+ inst->watch2[5*pnodecount+id] = 3;
+ } else {
+ inst->watch2[5*pnodecount+id] = 2;
}
}
if (inst->watch3[6*pnodecount+id]&2) {
if (v < -70.0) {
if ((inst->watch3[6*pnodecount+id]&1) == 0) {
net_send_buffering(ml->_net_send_buffer, 0, inst->tqitem[2*pnodecount+id], 0, inst->point_process[1*pnodecount+id], nt->_t+0.0, 4.0);
- inst->watch3[6*pnodecount+id] = 3;
- }
- else {
- inst->watch3[6*pnodecount+id] = 2;
}
+ inst->watch3[6*pnodecount+id] = 3;
+ } else {
+ inst->watch3[6*pnodecount+id] = 2;
}
}
if (inst->watch4[7*pnodecount+id]&2) {
if (v > -55.0) {
if ((inst->watch4[7*pnodecount+id]&1) == 0) {
net_send_buffering(ml->_net_send_buffer, 0, inst->tqitem[2*pnodecount+id], 0, inst->point_process[1*pnodecount+id], nt->_t+0.0, 2.0);
- inst->watch4[7*pnodecount+id] = 3;
- }
- else {
- inst->watch4[7*pnodecount+id] = 2;
}
+ inst->watch4[7*pnodecount+id] = 3;
+ } else {
+ inst->watch4[7*pnodecount+id] = 2;
}
}
}
And, for example, the first block above generated by MOD2C (and re-formatted) is:
if (_watch_array(1)&2) {
if ( v > - 55.0 ) {
if ((_watch_array(1)&1) == 0) {
#if NET_RECEIVE_BUFFERING
_net_send_buffering(_ml->_net_send_buffer, 0, _tqitem, 0, _ppvar[1*_STRIDE], t + 0.0 , 2.0 );
#else
net_send ( _tqitem, -1, (Point_process*) _nt->_vdata[_ppvar[1*_STRIDE]], t + 0.0 , 2.0 ) ;
#endif
}
_watch_array(1) = 3;
}else{
_watch_array(1) = 2;
}
}
And, for completeness, the vanilla code from NMODL is:
if (inst->watch1[4*pnodecount+id]&2) {
if (v > -55.0) {
if ((inst->watch1[4*pnodecount+id]&1) == 0) {
net_send_buffering(ml->_net_send_buffer, 0, inst->tqitem[2*pnodecount+id], 0, inst->point_process[1*pnodecount+id], nt->_t+0.0, 2.0);
inst->watch1[4*pnodecount+id] = 3;
} else {
inst->watch1[4*pnodecount+id] = 2;
}
}
}
While investigating #678 we noticed that NMODL generates slightly different logic for
WATCHstatements than MOD2C. This does not affect the results of thetestcorenrn_watchtest in the NEURON CTest suite, but it may still be an issue that needs to be resolved.The following diff modifies the code generated by NMODL to match the logic from MOD2C:
And, for example, the first block above generated by MOD2C (and re-formatted) is:
And, for completeness, the vanilla code from NMODL is: