Skip to content
This repository was archived by the owner on Mar 25, 2025. It is now read-only.
This repository was archived by the owner on Mar 25, 2025. It is now read-only.

NMODL generates different WATCH statement logic to MOD2C #679

Description

@olupton

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;
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    codegenCode generation backend

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions