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

Commit 8d962da

Browse files
iomaganarispramodk
authored andcommitted
Support for fast membrane current calculation (#196)
In order to support i_membrane reports, this PR the functionality of fast membrane calculation from NEURON. - Related to enabling fast_imem calculation from report parser (for neurondamus+reportinglib) - Added i_membrane to neuron direct memory transfer and refactored fast_imem memory allocation - Updated mod2c submodule commit
1 parent 06d63c0 commit 8d962da

File tree

15 files changed

+251
-16
lines changed

15 files changed

+251
-16
lines changed

coreneuron/nrniv/main1.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ THE POSSIBILITY OF SUCH DAMAGE.
3737
#include "coreneuron/engine.h"
3838
#include "coreneuron/utils/randoms/nrnran123.h"
3939
#include "coreneuron/nrnconf.h"
40+
#include "coreneuron/nrnoc/fast_imem.h"
4041
#include "coreneuron/nrnoc/multicore.h"
4142
#include "coreneuron/nrnoc/nrnoc_decl.h"
4243
#include "coreneuron/nrnmpi/nrnmpi.h"
@@ -126,10 +127,13 @@ char* prepare_args(int& argc, char**& argv, int use_mpi, const char* arg) {
126127
return first;
127128
}
128129

129-
int corenrn_embedded_run(int nthread, int have_gaps, int use_mpi, const char* arg) {
130+
int corenrn_embedded_run(int nthread, int have_gaps, int use_mpi, int use_fast_imem, const char* arg) {
130131
corenrn_embedded = 1;
131132
corenrn_embedded_nthread = nthread;
132133
coreneuron::nrn_have_gaps = have_gaps;
134+
if (use_fast_imem) {
135+
coreneuron::nrn_use_fast_imem = true;
136+
}
133137

134138
set_openmp_threads(nthread);
135139
int argc = 0;

coreneuron/nrniv/nrn_setup.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ THE POSSIBILITY OF SUCH DAMAGE.
3434
#include "coreneuron/nrnconf.h"
3535
#include "coreneuron/nrnoc/multicore.h"
3636
#include "coreneuron/nrniv/nrniv_decl.h"
37+
#include "coreneuron/nrnoc/fast_imem.h"
3738
#include "coreneuron/nrnoc/nrnoc_decl.h"
3839
#include "coreneuron/nrniv/vrecitem.h"
3940
#include "coreneuron/nrniv/multisend.h"
@@ -50,6 +51,8 @@ THE POSSIBILITY OF SUCH DAMAGE.
5051
#include "coreneuron/utils/reports/nrnsection_mapping.h"
5152

5253
// callbacks into nrn/src/nrniv/nrnbbcore_write.cpp
54+
#include "coreneuron/nrnoc/fast_imem.h"
55+
#include "coreneuron/nrniv/nrniv_decl.h"
5356
#include "coreneuron/nrniv/nrn2core_direct.h"
5457

5558
int corenrn_embedded;
@@ -795,6 +798,9 @@ void nrn_setup(const char* filesdat,
795798
mk_cell_indices();
796799
#endif
797800

801+
/// Allocate memory for fast_imem calculation
802+
nrn_fast_imem_alloc();
803+
798804
/// Generally, tables depend on a few parameters. And if those parameters change,
799805
/// then the table needs to be recomputed. This is obviously important in NEURON
800806
/// since the user can change those parameters at any time. However, there is no
@@ -912,17 +918,28 @@ int nrn_i_layout(int icnt, int cnt, int isz, int sz, int layout) {
912918
return 0;
913919
}
914920

921+
// This function is related to nrn_dblpntr2nrncore in Neuron to determine which values should
922+
// be transferred from CoreNeuron. Types correspond to the value to be transferred based on
923+
// mech_type enum or non-artificial cell mechanisms.
915924
// take into account alignment, layout, permutation
916-
// only voltage or mechanism data index allowed. (mtype 0 means time)
925+
// only voltage, i_membrane_ or mechanism data index allowed. (mtype 0 means time)
917926
double* stdindex2ptr(int mtype, int index, NrnThread& nt) {
918-
if (mtype == -5) { // voltage
927+
if (mtype == voltage) { // voltage
919928
int v0 = nt._actual_v - nt._data;
920929
int ix = index; // relative to _actual_v
921930
nrn_assert((ix >= 0) && (ix < nt.end));
922931
if (nt._permute) {
923932
node_permute(&ix, 1, nt._permute);
924933
}
925934
return nt._data + (v0 + ix); // relative to nt._data
935+
} else if (mtype == i_membrane_) { // membrane current from fast_imem calculation
936+
int i_mem = nt.nrn_fast_imem->nrn_sav_rhs - nt._data;
937+
int ix = index; // relative to nrn_fast_imem->nrn_sav_rhs
938+
nrn_assert((ix >= 0) && (ix < nt.end));
939+
if (nt._permute) {
940+
node_permute(&ix, 1, nt._permute);
941+
}
942+
return nt._data + (i_mem + ix); // relative to nt._data
926943
} else if (mtype > 0 && mtype < n_memb_func) { //
927944
Memb_list* ml = nt._ml_list[mtype];
928945
nrn_assert(ml);
@@ -1150,6 +1167,10 @@ void nrn_cleanup(bool clean_ion_global_map) {
11501167
}
11511168

11521169
free_memory(nt->_ml_list);
1170+
1171+
if (nt->nrn_fast_imem) {
1172+
fast_imem_free();
1173+
}
11531174
}
11541175

11551176
#if NRN_MULTISEND

coreneuron/nrniv/nrniv_decl.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ THE POSSIBILITY OF SUCH DAMAGE.
3535
#include "coreneuron/utils/endianness.h"
3636
#include "coreneuron/nrniv/nrnoptarg.h"
3737
namespace coreneuron {
38+
39+
/// Mechanism type to be used from stdindex2ptr and nrn_dblpntr2nrncore (in Neuron)
40+
/// Values of the mechanism types should be negative numbers to avoid any conflict with
41+
/// mechanism types of Memb_list(>0) or time(0) passed from Neuron
42+
enum mech_type {voltage = -1, i_membrane_ = -2};
43+
3844
extern int cvode_active_;
3945
/// Vector of maps for negative presyns
4046
extern std::vector<std::map<int, PreSyn*> > neg_gid2out;

coreneuron/nrnoc/fadvance_core.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ THE POSSIBILITY OF SUCH DAMAGE.
3030
#include "coreneuron/nrnconf.h"
3131
#include "coreneuron/nrnoc/multicore.h"
3232
#include "coreneuron/nrnmpi/nrnmpi.h"
33+
#include "coreneuron/nrnoc/fast_imem.h"
3334
#include "coreneuron/nrnoc/nrnoc_decl.h"
3435
#include "coreneuron/nrniv/nrn_acc_manager.h"
3536
#include "coreneuron/utils/reports/nrnreport.h"
@@ -190,6 +191,9 @@ void update(NrnThread* _nt) {
190191
assert(_nt->tml->index == CAP);
191192
nrn_cur_capacitance(_nt, _nt->tml->ml, _nt->tml->index);
192193
}
194+
if (nrn_use_fast_imem) {
195+
nrn_calc_fast_imem(_nt);
196+
}
193197
}
194198

195199
void nonvint(NrnThread* _nt) {

coreneuron/nrnoc/fast_imem.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
Copyright (c) 2019, Blue Brain Project
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without modification,
6+
are permitted provided that the following conditions are met:
7+
1. Redistributions of source code must retain the above copyright notice,
8+
this list of conditions and the following disclaimer.
9+
2. Redistributions in binary form must reproduce the above copyright notice,
10+
this list of conditions and the following disclaimer in the documentation
11+
and/or other materials provided with the distribution.
12+
3. Neither the name of the copyright holder nor the names of its contributors
13+
may be used to endorse or promote products derived from this software
14+
without specific prior written permission.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26+
THE POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
#include "coreneuron/nrnconf.h"
30+
#include "coreneuron/nrnoc/fast_imem.h"
31+
#include "coreneuron/nrniv/memory.h"
32+
#include "coreneuron/nrnmpi/nrnmpi.h"
33+
34+
namespace coreneuron {
35+
36+
extern int nrn_nthread;
37+
extern NrnThread *nrn_threads;
38+
bool nrn_use_fast_imem;
39+
40+
void fast_imem_free() {
41+
for (NrnThread* nt = nrn_threads; nt < nrn_threads + nrn_nthread; ++nt) {
42+
if (nt->nrn_fast_imem) {
43+
free(nt->nrn_fast_imem->nrn_sav_rhs);
44+
free(nt->nrn_fast_imem->nrn_sav_d);
45+
free(nt->nrn_fast_imem);
46+
nt->nrn_fast_imem = nullptr;
47+
}
48+
}
49+
}
50+
51+
void nrn_fast_imem_alloc() {
52+
if (nrn_use_fast_imem) {
53+
fast_imem_free();
54+
for (NrnThread* nt = nrn_threads; nt < nrn_threads + nrn_nthread; ++nt) {
55+
int n = nt->end;
56+
nt->nrn_fast_imem = (NrnFastImem*)ecalloc(1, sizeof(NrnFastImem));
57+
nt->nrn_fast_imem->nrn_sav_rhs = (double*)emalloc_align(n * sizeof(double));
58+
nt->nrn_fast_imem->nrn_sav_d = (double*)emalloc_align(n * sizeof(double));
59+
}
60+
}
61+
}
62+
63+
void nrn_calc_fast_imem(NrnThread* nt) {
64+
int i1 = 0;
65+
int i3 = nt->end;
66+
67+
double* vec_rhs = nt->_actual_rhs;
68+
double* vec_area = nt->_actual_area;
69+
70+
double* fast_imem_d = nt->nrn_fast_imem->nrn_sav_d;
71+
double* fast_imem_rhs = nt->nrn_fast_imem->nrn_sav_rhs;
72+
for (int i = i1; i < i3 ; ++i) {
73+
fast_imem_rhs[i] = (fast_imem_d[i]*vec_rhs[i] + fast_imem_rhs[i])*vec_area[i]*0.01;
74+
}
75+
}
76+
77+
}
78+

coreneuron/nrnoc/fast_imem.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
Copyright (c) 2019, Blue Brain Project
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without modification,
6+
are permitted provided that the following conditions are met:
7+
1. Redistributions of source code must retain the above copyright notice,
8+
this list of conditions and the following disclaimer.
9+
2. Redistributions in binary form must reproduce the above copyright notice,
10+
this list of conditions and the following disclaimer in the documentation
11+
and/or other materials provided with the distribution.
12+
3. Neither the name of the copyright holder nor the names of its contributors
13+
may be used to endorse or promote products derived from this software
14+
without specific prior written permission.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26+
THE POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
#ifndef fast_imem_h
30+
#define fast_imem_h
31+
32+
#include "coreneuron/nrnoc/multicore.h"
33+
34+
namespace coreneuron {
35+
36+
/* Bool global variable to define if the fast_imem
37+
* calculations should be enabled.
38+
*/
39+
extern bool nrn_use_fast_imem;
40+
41+
/* Free memory allocated for the fast current membrane calculation.
42+
* Found in src/nrnoc/multicore.c in NEURON.
43+
*/
44+
void fast_imem_free();
45+
46+
/* Allocate memory for the rhs and d arrays needed for the fast
47+
* current membrane calculation.
48+
* Found in src/nrnoc/multicore.c in NEURON.
49+
*/
50+
static void fast_imem_alloc();
51+
52+
/* fast_imem_alloc() wrapper.
53+
* Found in src/nrnoc/multicore.c in NEURON.
54+
*/
55+
void nrn_fast_imem_alloc();
56+
57+
/* Calculate the new values of rhs array at every timestep.
58+
* Found in src/nrnoc/fadvance.c in NEURON.
59+
*/
60+
void nrn_calc_fast_imem(NrnThread* _nt);
61+
62+
} // namespace coreneuron
63+
#endif //fast_imem_h

coreneuron/nrnoc/finitialize.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ THE POSSIBILITY OF SUCH DAMAGE.
2727
*/
2828

2929
#include "coreneuron/nrnconf.h"
30+
#include "coreneuron/nrnoc/fast_imem.h"
3031
#include "coreneuron/nrnoc/multicore.h"
3132
#include "coreneuron/nrnoc/nrnoc_decl.h"
3233
#include "coreneuron/nrniv/profiler_interface.h"
3334

3435
namespace coreneuron {
36+
3537
void nrn_finitialize(int setv, double v) {
3638
int i;
3739
NrnThread* _nt;
@@ -98,6 +100,9 @@ void nrn_finitialize(int setv, double v) {
98100
}
99101
for (i = 0; i < nrn_nthread; ++i) {
100102
setup_tree_matrix_minimal(nrn_threads + i);
103+
if (nrn_use_fast_imem) {
104+
nrn_calc_fast_imem(nrn_threads + i);
105+
}
101106
}
102107
for (i = 0; i < nrn_nthread; ++i) {
103108
nrn_ba(nrn_threads + i, BEFORE_STEP);

coreneuron/nrnoc/multicore.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ void nrn_threads_create(int n) {
137137
nt->_watch_types = NULL;
138138
nt->mapping = NULL;
139139
nt->trajec_requests = NULL;
140+
141+
nt->nrn_fast_imem = nullptr;
140142
}
141143
}
142144
v_structure_change = 1;

coreneuron/nrnoc/multicore.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ struct NrnThreadBAList {
5959
NrnThreadBAList* next;
6060
};
6161

62+
struct NrnFastImem {
63+
double* nrn_sav_rhs;
64+
double* nrn_sav_d;
65+
};
66+
6267
struct TrajectoryRequests {
6368
void** vpr; /* PlayRecord Objects known by NEURON */
6469
double** scatter; /* if bsize == 0, each time step */
@@ -116,6 +121,10 @@ struct NrnThread {
116121
compartment */
117122
double* _shadow_d; /* Not pointer into _data. Avoid race for multiple POINT_PROCESS in same
118123
compartment */
124+
125+
/* Fast membrane current calculation struct */
126+
NrnFastImem* nrn_fast_imem;
127+
119128
int* _v_parent_index;
120129
int* _permute;
121130
char* _sp13mat; /* handle to general sparse matrix */

coreneuron/nrnoc/treeset_core.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ static void nrn_rhs(NrnThread* _nt) {
6767
vec_d[i] = 0.;
6868
}
6969

70+
if (_nt->nrn_fast_imem) {
71+
for (i = i1; i < i3; ++i) {
72+
_nt->nrn_fast_imem->nrn_sav_rhs[i] = 0.;
73+
_nt->nrn_fast_imem->nrn_sav_d[i] = 0.;
74+
}
75+
}
76+
7077
nrn_ba(_nt, BEFORE_BREAKPOINT);
7178
/* note that CAP has no current */
7279
for (tml = _nt->tml; tml; tml = tml->next)
@@ -82,6 +89,16 @@ static void nrn_rhs(NrnThread* _nt) {
8289
}
8390
#endif
8491
}
92+
93+
if (_nt->nrn_fast_imem) {
94+
/* _nrn_save_rhs has only the contribution of electrode current
95+
so here we transform so it only has membrane current contribution
96+
*/
97+
double* p = _nt->nrn_fast_imem->nrn_sav_rhs;
98+
for (i = i1; i < i3; ++i) {
99+
p[i] -= vec_rhs[i];
100+
}
101+
}
85102

86103
/* now the internal axial currents.
87104
The extracellular mechanism contribution is already done.
@@ -151,6 +168,16 @@ static void nrn_lhs(NrnThread* _nt) {
151168
double* vec_b = &(VEC_B(0));
152169
int* parent_index = _nt->_v_parent_index;
153170

171+
if (_nt->nrn_fast_imem) {
172+
/* _nrn_save_d has only the contribution of electrode current
173+
so here we transform so it only has membrane current contribution
174+
*/
175+
double* p = _nt->nrn_fast_imem->nrn_sav_d;
176+
for (i = i1; i < i3; ++i) {
177+
p[i] += vec_d[i];
178+
}
179+
}
180+
154181
/* now add the axial currents */
155182
// clang-format off
156183
#pragma acc parallel loop present( \

0 commit comments

Comments
 (0)