From 4232cab222fe66634e49ad5d8beb4bf47d7c19a9 Mon Sep 17 00:00:00 2001 From: wthun Date: Thu, 22 Aug 2024 14:41:20 +0200 Subject: [PATCH 1/9] increased maximum number of ions per compartment by using std::bitset for bitvector comparisons --- src/nrnoc/eion.cpp | 49 +++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/nrnoc/eion.cpp b/src/nrnoc/eion.cpp index 7933fabe29..5721943836 100644 --- a/src/nrnoc/eion.cpp +++ b/src/nrnoc/eion.cpp @@ -14,6 +14,10 @@ #include #include +#include +#include +#include + #undef hoc_retpushx extern double chkarg(int, double low, double high); @@ -64,7 +68,7 @@ double nrn_ion_charge(Symbol* sym) { void ion_register(void) { /* hoc level registration of ion name. Return -1 if name already - in use and not an ion; and the mechanism subtype otherwise. + in use and not an ion; and the mechanism subtype otherwise. */ char* name; Symbol* s; @@ -401,7 +405,11 @@ The argument `i` specifies which concentration is being written to. It's 0 for exterior; and 1 for interior. */ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) { - static long *chk_conc_, *ion_bit_, size_; + const int max_length = 10000; // parametrize? + static std::unique_ptr>> chk_conc_; + static std::unique_ptr>> ion_bit_; + static long size_; + Prop* p; int flag, j, k; if (i == 1) { @@ -409,41 +417,46 @@ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) { } else { flag = 0400; } - /* an embarassing hack */ - /* up to 32 possible ions */ - /* continuously compute a bitmap that allows determination - of which models WRITE which ion concentrations */ - if (n_memb_func > size_) { + + // create a vctor of std::bitsets to track ions being written + if (n_memb_func > size_) { // No need to reallocate now? if (!chk_conc_) { - chk_conc_ = (long*) ecalloc(2 * n_memb_func, sizeof(long)); - ion_bit_ = (long*) ecalloc(n_memb_func, sizeof(long)); + chk_conc_ = std::make_unique>>(); + chk_conc_->reserve(2 * n_memb_func); + + ion_bit_ = std::make_unique>>(); + ion_bit_->reserve(n_memb_func); } else { - chk_conc_ = (long*) erealloc(chk_conc_, 2 * n_memb_func * sizeof(long)); - ion_bit_ = (long*) erealloc(ion_bit_, n_memb_func * sizeof(long)); + chk_conc_ = std::make_unique>>(); + chk_conc_->reserve(2 * n_memb_func); + + ion_bit_ = std::make_unique>>(); + ion_bit_->reserve(n_memb_func); for (j = size_; j < n_memb_func; ++j) { - chk_conc_[2 * j] = 0; - chk_conc_[2 * j + 1] = 0; - ion_bit_[j] = 0; + (*chk_conc_)[2 * j] &= 0; + (*chk_conc_)[2 * j + 1] &= 0; + (*ion_bit_)[j] &= 0; } } size_ = n_memb_func; } for (k = 0, j = 0; j < n_memb_func; ++j) { if (nrn_is_ion(j)) { - ion_bit_[j] = (1 << k); + (*ion_bit_)[j] = (1 << k); ++k; - assert(k < sizeof(long) * 8); + assert(k < max_length); } } - chk_conc_[2 * p_ok->_type + i] |= ion_bit_[pion->_type]; + (*chk_conc_)[2 * p_ok->_type + i] |= (*ion_bit_)[pion->_type]; if (pion->dparam[iontype_index_dparam].get() & flag) { /* now comes the hard part. Is the possibility in fact actual.*/ for (p = pion->next; p; p = p->next) { if (p == p_ok) { continue; } - if (chk_conc_[2 * p->_type + i] & ion_bit_[pion->_type]) { + auto rst = (*chk_conc_)[2 * p->_type + i] & (*ion_bit_)[pion->_type]; + if (rst.count() > 0) { char buf[300]; Sprintf(buf, "%.*s%c is being written at the same location by %s and %s", From 5179cc4f34f63c7a965e892530a861a85eab8fd6 Mon Sep 17 00:00:00 2001 From: wthun Date: Fri, 23 Aug 2024 09:41:11 +0200 Subject: [PATCH 2/9] changed vector.reserve to vector.resize to initialize std::bitset elements --- src/nrnoc/eion.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nrnoc/eion.cpp b/src/nrnoc/eion.cpp index 5721943836..3010f0d5ea 100644 --- a/src/nrnoc/eion.cpp +++ b/src/nrnoc/eion.cpp @@ -422,16 +422,16 @@ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) { if (n_memb_func > size_) { // No need to reallocate now? if (!chk_conc_) { chk_conc_ = std::make_unique>>(); - chk_conc_->reserve(2 * n_memb_func); + chk_conc_->resize(2 * n_memb_func); // std::bitset defaults to 0 ion_bit_ = std::make_unique>>(); - ion_bit_->reserve(n_memb_func); + ion_bit_->resize(n_memb_func); } else { chk_conc_ = std::make_unique>>(); - chk_conc_->reserve(2 * n_memb_func); + chk_conc_->resize(2 * n_memb_func); ion_bit_ = std::make_unique>>(); - ion_bit_->reserve(n_memb_func); + ion_bit_->resize(n_memb_func); for (j = size_; j < n_memb_func; ++j) { (*chk_conc_)[2 * j] &= 0; (*chk_conc_)[2 * j + 1] &= 0; From 61162e49ef41bdebab7c13b24fd23001328f37de Mon Sep 17 00:00:00 2001 From: wthun Date: Fri, 23 Aug 2024 09:53:52 +0200 Subject: [PATCH 3/9] cleanup --- src/nrnoc/eion.cpp | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/nrnoc/eion.cpp b/src/nrnoc/eion.cpp index 3010f0d5ea..302615984d 100644 --- a/src/nrnoc/eion.cpp +++ b/src/nrnoc/eion.cpp @@ -406,10 +406,10 @@ exterior; and 1 for interior. */ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) { const int max_length = 10000; // parametrize? - static std::unique_ptr>> chk_conc_; - static std::unique_ptr>> ion_bit_; static long size_; + static std::vector> chk_conc_, ion_bit_; + Prop* p; int flag, j, k; if (i == 1) { @@ -418,44 +418,37 @@ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) { flag = 0400; } - // create a vctor of std::bitsets to track ions being written - if (n_memb_func > size_) { // No need to reallocate now? - if (!chk_conc_) { - chk_conc_ = std::make_unique>>(); - chk_conc_->resize(2 * n_memb_func); // std::bitset defaults to 0 + /* Create a vector holding std::bitset to track which ions + are being written to the membrane */ + if (n_memb_func > size_) { - ion_bit_ = std::make_unique>>(); - ion_bit_->resize(n_memb_func); - } else { - chk_conc_ = std::make_unique>>(); - chk_conc_->resize(2 * n_memb_func); - - ion_bit_ = std::make_unique>>(); - ion_bit_->resize(n_memb_func); - for (j = size_; j < n_memb_func; ++j) { - (*chk_conc_)[2 * j] &= 0; - (*chk_conc_)[2 * j + 1] &= 0; - (*ion_bit_)[j] &= 0; - } + chk_conc_.resize(2 * n_memb_func); + ion_bit_.resize(n_memb_func); + + for (j = size_; j < n_memb_func; ++j) { + chk_conc_[2 * j].reset(); + chk_conc_[2 * j + 1].reset(); + ion_bit_[j].reset(); } + size_ = n_memb_func; } for (k = 0, j = 0; j < n_memb_func; ++j) { if (nrn_is_ion(j)) { - (*ion_bit_)[j] = (1 << k); + ion_bit_[j] = (1 << k); ++k; assert(k < max_length); } } - (*chk_conc_)[2 * p_ok->_type + i] |= (*ion_bit_)[pion->_type]; + chk_conc_[2 * p_ok->_type + i] |= ion_bit_[pion->_type]; if (pion->dparam[iontype_index_dparam].get() & flag) { /* now comes the hard part. Is the possibility in fact actual.*/ for (p = pion->next; p; p = p->next) { if (p == p_ok) { continue; } - auto rst = (*chk_conc_)[2 * p->_type + i] & (*ion_bit_)[pion->_type]; + auto rst = chk_conc_[2 * p->_type + i] & ion_bit_[pion->_type]; if (rst.count() > 0) { char buf[300]; Sprintf(buf, From fc274772dc1b61111ee06aa2ad25d385209eee80 Mon Sep 17 00:00:00 2001 From: wthun <43437733+wthun@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:10:46 +0200 Subject: [PATCH 4/9] rename max_length to max_ion Co-authored-by: Luc Grosheintz --- src/nrnoc/eion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nrnoc/eion.cpp b/src/nrnoc/eion.cpp index 7a8db092bc..d6f31d8da5 100644 --- a/src/nrnoc/eion.cpp +++ b/src/nrnoc/eion.cpp @@ -401,7 +401,7 @@ The argument `i` specifies which concentration is being written to. It's 0 for exterior; and 1 for interior. */ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) { - const int max_length = 10000; // parametrize? + const int max_ions = 64; static long size_; static std::vector> chk_conc_, ion_bit_; From e36452cc24cf61a69b1db17dd04138b456ca8acb Mon Sep 17 00:00:00 2001 From: wthun <43437733+wthun@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:10:57 +0200 Subject: [PATCH 5/9] Update src/nrnoc/eion.cpp Co-authored-by: Luc Grosheintz --- src/nrnoc/eion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nrnoc/eion.cpp b/src/nrnoc/eion.cpp index d6f31d8da5..d148c2e35a 100644 --- a/src/nrnoc/eion.cpp +++ b/src/nrnoc/eion.cpp @@ -404,7 +404,7 @@ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) { const int max_ions = 64; static long size_; - static std::vector> chk_conc_, ion_bit_; + static std::vector> chk_conc_, ion_bit_; Prop* p; int flag, j, k; From 3b5e359fea00ac2b5bbbd52ceed3dc0c9105b9ee Mon Sep 17 00:00:00 2001 From: wthun <43437733+wthun@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:11:08 +0200 Subject: [PATCH 6/9] Update src/nrnoc/eion.cpp Co-authored-by: Luc Grosheintz --- src/nrnoc/eion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nrnoc/eion.cpp b/src/nrnoc/eion.cpp index d148c2e35a..30195e112a 100644 --- a/src/nrnoc/eion.cpp +++ b/src/nrnoc/eion.cpp @@ -445,7 +445,7 @@ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) { continue; } auto rst = chk_conc_[2 * p->_type + i] & ion_bit_[pion->_type]; - if (rst.count() > 0) { + if (rst.any()) { char buf[300]; Sprintf(buf, "%.*s%c is being written at the same location by %s and %s", From dc47da518b1d8b7f81e3ca832d5d9f518a952f14 Mon Sep 17 00:00:00 2001 From: wthun <43437733+wthun@users.noreply.github.com> Date: Fri, 20 Sep 2024 13:11:29 +0200 Subject: [PATCH 7/9] Update src/nrnoc/eion.cpp Co-authored-by: Luc Grosheintz --- src/nrnoc/eion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nrnoc/eion.cpp b/src/nrnoc/eion.cpp index 30195e112a..224d5f9e21 100644 --- a/src/nrnoc/eion.cpp +++ b/src/nrnoc/eion.cpp @@ -433,7 +433,7 @@ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) { if (nrn_is_ion(j)) { ion_bit_[j] = (1 << k); ++k; - assert(k < max_length); + assert(k < max_ions); } } From 570a9aea4d14cbaff7f097da54004a635c081801 Mon Sep 17 00:00:00 2001 From: wthun Date: Fri, 20 Sep 2024 14:10:24 +0200 Subject: [PATCH 8/9] cmake-format --- src/nrnoc/eion.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/nrnoc/eion.cpp b/src/nrnoc/eion.cpp index 224d5f9e21..5a0a921969 100644 --- a/src/nrnoc/eion.cpp +++ b/src/nrnoc/eion.cpp @@ -414,13 +414,12 @@ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) { flag = 0400; } - /* Create a vector holding std::bitset to track which ions + /* Create a vector holding std::bitset to track which ions are being written to the membrane */ if (n_memb_func > size_) { - chk_conc_.resize(2 * n_memb_func); ion_bit_.resize(n_memb_func); - + for (j = size_; j < n_memb_func; ++j) { chk_conc_[2 * j].reset(); chk_conc_[2 * j + 1].reset(); From dc11e937becb4f1d0fc17907c8c2d5141548e2ee Mon Sep 17 00:00:00 2001 From: wthun Date: Fri, 20 Sep 2024 14:20:49 +0200 Subject: [PATCH 9/9] increased max_ion to 256 --- src/nrnoc/eion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nrnoc/eion.cpp b/src/nrnoc/eion.cpp index 5a0a921969..4c841f4c2c 100644 --- a/src/nrnoc/eion.cpp +++ b/src/nrnoc/eion.cpp @@ -401,7 +401,7 @@ The argument `i` specifies which concentration is being written to. It's 0 for exterior; and 1 for interior. */ void nrn_check_conc_write(Prop* p_ok, Prop* pion, int i) { - const int max_ions = 64; + const int max_ions = 256; static long size_; static std::vector> chk_conc_, ion_bit_;