diff --git a/cmake/NeuronFileLists.cmake b/cmake/NeuronFileLists.cmake index ca4fbcdbfa..f4d6e11e95 100644 --- a/cmake/NeuronFileLists.cmake +++ b/cmake/NeuronFileLists.cmake @@ -21,6 +21,7 @@ set(HEADER_FILES_TO_INSTALL nrnoc/md1redef.h nrnoc/md2redef.h nrnoc/membdef.h + nrnoc/ion_semantics.h nrnoc/membfunc.h nrnoc/multicore.h nrnoc/multisplit.h diff --git a/src/coreneuron/io/nrn_checkpoint.cpp b/src/coreneuron/io/nrn_checkpoint.cpp index ed91d7de81..c7c7743ed9 100644 --- a/src/coreneuron/io/nrn_checkpoint.cpp +++ b/src/coreneuron/io/nrn_checkpoint.cpp @@ -11,6 +11,7 @@ #include #include +#include "nrnoc/ion_semantics.h" #include "coreneuron/sim/multicore.hpp" #include "coreneuron/nrniv/nrniv_decl.h" #include "coreneuron/io/nrn_filehandler.hpp" @@ -296,8 +297,9 @@ void CheckPoints::write_phase2(NrnThread& nt) const { // out into the following function. d[ix] = nrn_original_aos_index(ptype, d[ix], nt, ml_pinv); } - } else if (s >= 0 && s < 1000) { // ion - d[ix] = nrn_original_aos_index(s, d[ix], nt, ml_pinv); + } else if (nrn_semantics_is_ion(s)) { // ion + auto type = nrn_semantics_ion_type(s); + d[ix] = nrn_original_aos_index(type, d[ix], nt, ml_pinv); } #if CHKPNTDEBUG if (s != -8) { // WATCH values change diff --git a/src/coreneuron/io/phase2.cpp b/src/coreneuron/io/phase2.cpp index 19fb12e8a3..3c712f1f5b 100644 --- a/src/coreneuron/io/phase2.cpp +++ b/src/coreneuron/io/phase2.cpp @@ -6,6 +6,7 @@ # ============================================================================= */ +#include "nrnoc/ion_semantics.h" #include "coreneuron/io/phase2.hpp" #include "coreneuron/coreneuron.hpp" #include "coreneuron/sim/multicore.hpp" @@ -699,8 +700,8 @@ void Phase2::pdata_relocation(const NrnThread& nt, const std::vector& **/ break; default: - if (s >= 0 && s < 1000) { // ion - int etype = s; + if (nrn_semantics_is_ion(s)) { // ion + int etype = nrn_semantics_ion_type(s); /* if ion is SoA, must recalculate pdata values */ /* if ion is AoS, have to deal with offset */ Memb_list* eml = nt._ml_list[etype]; diff --git a/src/coreneuron/mechanism/register_mech.cpp b/src/coreneuron/mechanism/register_mech.cpp index 260d420411..2ef95e976f 100644 --- a/src/coreneuron/mechanism/register_mech.cpp +++ b/src/coreneuron/mechanism/register_mech.cpp @@ -9,6 +9,7 @@ #include #include "coreneuron/nrnconf.h" +#include "nrnoc/ion_semantics.h" #include "coreneuron/sim/multicore.hpp" #include "coreneuron/membrane_definitions.h" #include "coreneuron/mechanism/eion.hpp" @@ -212,7 +213,7 @@ void hoc_register_dparam_semantics(int type, int ix, const char* name) { xx_ion and #xx_ion which will get a semantics value of -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, - type, and type+1000 respectively + 2*type, and 2*type+1 respectively */ auto& memb_func = corenrn.get_memb_funcs(); if (strcmp(name, "area") == 0) { @@ -240,7 +241,7 @@ void hoc_register_dparam_semantics(int type, int ix, const char* name) { } else { int i = name[0] == '#' ? 1 : 0; int etype = nrn_get_mechtype(name + i); - memb_func[type].dparam_semantics[ix] = etype + i * 1000; + memb_func[type].dparam_semantics[ix] = nrn_semantics_from_ion(etype, i); /* note that if style is needed (i==1), then we are writing a concentration */ if (i) { ion_write_depend(type, etype); @@ -300,8 +301,8 @@ int nrn_mech_depend(int type, int* dependencies) { int idep = 0; if (ds) for (int i = 0; i < dpsize; ++i) { - if (ds[i] > 0 && ds[i] < 1000) { - int deptype = ds[i]; + if (nrn_semantics_is_ion(ds[i])) { + int deptype = nrn_semantics_ion_type(ds[i]); int idepnew = depend_append(idep, dependencies, deptype, type); if ((idepnew > idep) && !corenrn.get_ion_write_dependency().empty() && !corenrn.get_ion_write_dependency()[deptype].empty()) { diff --git a/src/coreneuron/permute/node_permute.cpp b/src/coreneuron/permute/node_permute.cpp index a19230b4fc..eb33da0991 100644 --- a/src/coreneuron/permute/node_permute.cpp +++ b/src/coreneuron/permute/node_permute.cpp @@ -94,6 +94,7 @@ so pdata_m(k, isz) = inew + data_t #include "coreneuron/nrniv/nrniv_decl.h" #include "coreneuron/utils/nrn_assert.h" #include "coreneuron/coreneuron.hpp" +#include "nrnoc/ion_semantics.h" #else #include "nrnoc/multicore.h" #include "oc/nrnassrt.h" @@ -333,8 +334,8 @@ static void update_pdata_values(Memb_list* ml, int type, NrnThread& nt) { nrn_assert(0); } } - } else if (s >= 0 && s < 1000) { // ion - int etype = s; + } else if (nrn_semantics_is_ion(s)) { // ion + int etype = nrn_semantics_ion_type(s); int elayout = corenrn.get_mech_data_layout()[etype]; Memb_list* eml = nt._ml_list[etype]; int edata0 = eml->data - nt._data; diff --git a/src/neuron/cache/mechanism_range.hpp b/src/neuron/cache/mechanism_range.hpp index 4a332ebb06..8cca0ce44d 100644 --- a/src/neuron/cache/mechanism_range.hpp +++ b/src/neuron/cache/mechanism_range.hpp @@ -22,7 +22,7 @@ void indices_to_cache(short type, Callable callable) { auto const sem = dparam_semantics[field]; // See https://github.com/neuronsimulator/nrn/issues/2312 for discussion of possible // extensions to caching. - if ((sem > 0 && sem < 1000) || sem == -1 /* area */ || sem == -9 /* diam */) { + if (nrn_semantics_is_ion(sem) || sem == -1 /* area */ || sem == -9 /* diam */) { std::invoke(callable, field); } } diff --git a/src/nrniv/nrncore_write/callbacks/nrncore_callbacks.cpp b/src/nrniv/nrncore_write/callbacks/nrncore_callbacks.cpp index 158ae0c028..a91b69ec14 100644 --- a/src/nrniv/nrncore_write/callbacks/nrncore_callbacks.cpp +++ b/src/nrniv/nrncore_write/callbacks/nrncore_callbacks.cpp @@ -670,10 +670,10 @@ int* datum2int(int type, } } else if (etype == -9) { pdata[jj] = eindex; - } else if (etype > 0 && etype < 1000) { // ion pointer + } else if (nrn_semantics_is_ion(etype)) { // ion pointer pdata[jj] = eindex; - } else if (etype > 1000 && etype < 2000) { // ionstyle can be explicit instead of - // pointer to int* + } else if (nrn_semantics_is_ionstyle(etype)) { + // ionstyle can be explicit instead of pointer to int* pdata[jj] = eindex; } else if (etype == -2) { // an ion and this is the iontype pdata[jj] = eindex; diff --git a/src/nrniv/nrncore_write/data/cell_group.cpp b/src/nrniv/nrncore_write/data/cell_group.cpp index e034359387..8ee75d4191 100644 --- a/src/nrniv/nrncore_write/data/cell_group.cpp +++ b/src/nrniv/nrncore_write/data/cell_group.cpp @@ -343,15 +343,15 @@ void CellGroup::datumindex_fill(int ith, CellGroup& cg, DatumIndices& di, Memb_l } assert(etype != 0); // pointer into one of the tml types? - } else if (dmap[j] > 0 && dmap[j] < 1000) { // double* into eion type data - etype = dmap[j]; + } else if (nrn_semantics_is_ion(dmap[j])) { // double* into eion type data + etype = nrn_semantics_ion_type(dmap[j]); Memb_list* eml = cg.type2ml[etype]; assert(eml); auto* const pval = dparam[j].get(); auto const legacy_index = eml->legacy_index(pval); assert(legacy_index >= 0); eindex = legacy_index; - } else if (dmap[j] > 1000) { // int* into ion dparam[xxx][0] + } else if (nrn_semantics_is_ionstyle(dmap[j])) { // int* into ion dparam[xxx][0] // store the actual ionstyle etype = dmap[j]; eindex = *dparam[j].get(); diff --git a/src/nrniv/nrncore_write/data/cell_group.h b/src/nrniv/nrncore_write/data/cell_group.h index 374c2a2510..e86b1500cb 100644 --- a/src/nrniv/nrncore_write/data/cell_group.h +++ b/src/nrniv/nrncore_write/data/cell_group.h @@ -32,8 +32,8 @@ class CellGroup { // following three are parallel arrays std::vector output_ps; // n_presyn of these, real are first, tml order for acell. std::vector output_gid; // n_presyn of these, -(type + 1000*index) if no gid - std::vector output_vindex; // n_presyn of these. >=0 if associated with voltage, -(type + - // 1000*index) for acell. + std::vector output_vindex; // n_presyn of these. >=0 if associated with voltage, + // -(type + 1000*index) for acell. int n_netcon; // all that have targets associated with this threads Point_process. std::vector netcons; int* netcon_srcgid; // -(type + 1000*index) refers to acell with no gid diff --git a/src/nrnoc/init.cpp b/src/nrnoc/init.cpp index 267eac5c55..0ce3980ec8 100644 --- a/src/nrnoc/init.cpp +++ b/src/nrnoc/init.cpp @@ -765,7 +765,7 @@ namespace { */ // name to int map for the negative types -// xx_ion and #xx_ion will get values of type and type+1000 respectively +// xx_ion and #xx_ion will get values of type*2 and type*2+1 respectively static std::unordered_map name_to_negint = {{"area", -1}, {"iontype", -2}, {"cvodeieq", -3}, @@ -785,7 +785,7 @@ int dparam_semantics_to_int(std::string_view name) { bool const i{name[0] == '#'}; Symbol* s = hoc_lookup(std::string{name.substr(i)}.c_str()); if (s && s->type == MECHANISM) { - return s->subtype + i * 1000; + return s->subtype * 2 + i; } throw std::runtime_error("unknown dparam semantics: " + std::string{name}); } diff --git a/src/nrnoc/ion_semantics.h b/src/nrnoc/ion_semantics.h new file mode 100644 index 0000000000..2a3dfc8253 --- /dev/null +++ b/src/nrnoc/ion_semantics.h @@ -0,0 +1,14 @@ +#pragma once + +inline int nrn_semantics_from_ion(int type, int i) { + return 2 * type + i; +} +inline bool nrn_semantics_is_ion(int i) { + return i >= 0 && (i & 1) == 0; +} +inline bool nrn_semantics_is_ionstyle(int i) { + return i >= 0 && (i & 1) == 1; +} +inline int nrn_semantics_ion_type(int i) { + return i / 2; +} diff --git a/src/nrnoc/membfunc.h b/src/nrnoc/membfunc.h index ad80ed9d7e..18647c19b7 100644 --- a/src/nrnoc/membfunc.h +++ b/src/nrnoc/membfunc.h @@ -5,6 +5,7 @@ extern void hoc_register_prop_size(int type, int psize, int dpsize); #include "nrnoc_ml.h" #include "oc_ansi.h" // neuron::model_sorted_token #include "options.h" // EXTRACELLULAR +#include "ion_semantics.h" #include #include