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

Commit 07bf5f1

Browse files
authored
Copies to NEURON the voltage, i_membrane_, and mechanism data. (#382)
* Copies to NEURON the voltage, i_membrane_, and mechanism data. Framework in place. * voltage and i_membrane_ transfer implemented. * Data return for mechanisms. * Completes the data-return implementation. Needs further testing. * Data return for NrnThread._t. Inverse permute was reversed! * For direct mode, only call modl_reg once.
1 parent 1e3a3a2 commit 07bf5f1

File tree

6 files changed

+226
-2
lines changed

6 files changed

+226
-2
lines changed

coreneuron/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ if(CORENRN_ENABLE_GPU)
107107
${CMAKE_CURRENT_SOURCE_DIR}/utils/randoms/nrnran123.cpp
108108
${CMAKE_CURRENT_SOURCE_DIR}/io/nrn_setup.cpp
109109
${CMAKE_CURRENT_SOURCE_DIR}/io/setup_fornetcon.cpp
110+
${CMAKE_CURRENT_SOURCE_DIR}/io/corenrn_data_return.cpp
110111
${CMAKE_CURRENT_SOURCE_DIR}/io/global_vars.cpp)
111112

112113
set_source_files_properties(${DIMPLIC_CODE_FILE} ${NMODL_INBUILT_MOD_OUTPUTS} PROPERTIES

coreneuron/apps/main1.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ THE POSSIBILITY OF SUCH DAMAGE.
6262
#include "coreneuron/network/multisend.hpp"
6363
#include "coreneuron/io/file_utils.hpp"
6464
#include "coreneuron/io/nrn2core_direct.h"
65+
#include "coreneuron/io/core2nrn_data_return.hpp"
6566

6667
extern "C" {
6768
const char* corenrn_version() {
@@ -609,6 +610,8 @@ extern "C" int run_solve_core(int argc, char** argv) {
609610
(*nrn2core_all_weights_return_)(weights);
610611
}
611612

613+
core2nrn_data_return();
614+
612615
{
613616
Instrumentor::phase p("checkpoint");
614617
write_checkpoint(nrn_threads, nrn_nthread, corenrn_param.checkpointpath.c_str());
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
Copyright (c) 2020, 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/coreneuron.hpp"
30+
#include "coreneuron/io/nrn2core_direct.h"
31+
#include "coreneuron/sim/multicore.hpp"
32+
#include "coreneuron/nrniv/nrniv_decl.h"
33+
#include "coreneuron/io/core2nrn_data_return.hpp"
34+
35+
/** @brief, Information from NEURON to help with copying data to NEURON.
36+
* Info for copying voltage, i_membrane_, and mechanism data.
37+
* See implementaton in
38+
* nrn/src/nrniv/nrnbbcore_write.cpp:nrnthreads_type_return.
39+
* Return is size of either the returned data pointer or the number
40+
* of pointers in mdata. tid is the thread index.
41+
*/
42+
size_t (*nrn2core_type_return_)(int type, int tid,
43+
double*& data, double**& mdata);
44+
45+
namespace coreneuron {
46+
47+
/** @brief permuted array copied to unpermuted array
48+
* If permute is NULL then just a copy
49+
*/
50+
static void inverse_permute_copy(size_t n, double* permuted_src, double* dest,
51+
int* permute)
52+
{
53+
if (permute) {
54+
for (size_t i = 0; i < n; ++i) {
55+
dest[i] = permuted_src[permute[i]];
56+
}
57+
}else{
58+
std::copy(permuted_src, permuted_src + n, dest);
59+
}
60+
}
61+
62+
/** @brief SoA permuted mechanism data copied to unpermuted AoS data.
63+
* dest is an array of n pointers to the beginning of each sz length array.
64+
* src is a contiguous array of sz segments of size stride. The stride
65+
* may be slightly greater than n for purposes of alignment.
66+
* Each of the sz segments of src are permuted.
67+
*/
68+
static void soa2aos_inverse_permute_copy(size_t n, int sz, int stride,
69+
double* src, double** dest, int* permute)
70+
{
71+
// src is soa and permuted. dest is n pointers to sz doubles (aos).
72+
for (size_t instance = 0; instance < n; ++instance) {
73+
double* d = dest[instance];
74+
double* s = src + permute[instance];
75+
for (int i = 0; i < sz; ++i) {
76+
d[i] = s[i*stride];
77+
}
78+
}
79+
}
80+
81+
/** @brief SoA unpermuted mechanism data copied to unpermuted AoS data.
82+
* dest is an array of n pointers to the beginning of each sz length array.
83+
* src is a contiguous array of sz segments of size stride. The stride
84+
* may be slightly greater than n for purposes of alignment.
85+
* Each of the sz segments of src have the same order as the n pointers
86+
* of dest.
87+
*/
88+
static void soa2aos_unpermuted_copy(size_t n, int sz, int stride,
89+
double* src, double** dest)
90+
{
91+
// src is soa and permuted. dest is n pointers to sz doubles (aos).
92+
for (size_t instance = 0; instance < n; ++instance) {
93+
double* d = dest[instance];
94+
double* s = src + instance;
95+
for (int i = 0; i < sz; ++i) {
96+
d[i] = s[i*stride];
97+
}
98+
}
99+
}
100+
101+
/** @brief AoS mechanism data copied to AoS data.
102+
* dest is an array of n pointers to the beginning of each sz length array.
103+
* src is a contiguous array of n segments of size sz.
104+
*/
105+
static void aos2aos_copy(size_t n, int sz, double* src, double** dest) {
106+
for (size_t instance = 0; instance < n; ++instance) {
107+
double* d = dest[instance];
108+
double* s = src + (instance*sz);
109+
std::copy(s, s + sz, d);
110+
}
111+
}
112+
113+
/** @brief copy data back to NEURON.
114+
* Copies t, voltage, i_membrane_ if it used, and mechanism param data.
115+
*/
116+
void core2nrn_data_return() {
117+
if (!nrn2core_type_return_) {
118+
return;
119+
}
120+
for (int tid = 0; tid < nrn_nthread; ++tid) {
121+
size_t n = 0;
122+
double* data = nullptr;
123+
double** mdata = nullptr;
124+
NrnThread& nt = nrn_threads[tid];
125+
126+
n = (*nrn2core_type_return_)(0, tid, data, mdata); // 0 means time
127+
if (n) { // not the empty thread
128+
data[0] = nt._t;
129+
}
130+
131+
if (nt.end) { // transfer voltage and possibly i_membrane_
132+
n = (*nrn2core_type_return_)(voltage, tid, data, mdata);
133+
assert(n == size_t(nt.end) && data);
134+
inverse_permute_copy(n, nt._actual_v, data, nt._permute);
135+
136+
if (nt.nrn_fast_imem) {
137+
n = (*nrn2core_type_return_)(i_membrane_, tid, data, mdata);
138+
assert(n == size_t(nt.end) && data);
139+
inverse_permute_copy(n, nt.nrn_fast_imem->nrn_sav_rhs, data, nt._permute);
140+
}
141+
}
142+
143+
for (NrnThreadMembList* tml = nt.tml; tml; tml = tml->next) {
144+
int mtype = tml->index;
145+
Memb_list* ml = tml->ml;
146+
n = (*nrn2core_type_return_)(mtype, tid, data, mdata);
147+
assert(n == size_t(ml->nodecount) && mdata);
148+
if (n == 0) {
149+
continue;
150+
}
151+
// NEURON is AoS, CoreNEURON may be SoA and may be permuted.
152+
// On the NEURON side, the data is actually contiguous because of
153+
// cache_efficient, but that may not be the case for ARTIFICIAL_CELL.
154+
// For initial implementation simplicity, use the mdata info which gives
155+
// a double* for each param_size mech instance.
156+
int* permute = ml->_permute;
157+
double* cndat = ml->data;
158+
int layout = corenrn.get_mech_data_layout()[mtype];
159+
int sz = corenrn.get_prop_param_size()[mtype];
160+
if (layout == 0) { /* SoA */
161+
int stride = ml->_nodecount_padded;
162+
if (permute) {
163+
soa2aos_inverse_permute_copy(n, sz, stride, cndat, mdata, permute);
164+
} else {
165+
soa2aos_unpermuted_copy(n, sz, stride, cndat, mdata);
166+
}
167+
} else { /* AoS */
168+
aos2aos_copy(n, sz, cndat, mdata);
169+
}
170+
}
171+
}
172+
}
173+
174+
} // namespace coreneuron
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
Copyright (c) 2016, 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 _H_CORENRNDATARETURN_
30+
#define _H_CORENRNDATARETURN_
31+
32+
namespace coreneuron {
33+
34+
/** @brief Copies back to NEURON the voltage, i_membrane_, and mechanism data.
35+
*/
36+
extern void core2nrn_data_return();
37+
38+
} // namespace coreneuron
39+
#endif // _H_CORENRNDATARETURN_
40+

coreneuron/io/nrn2core_direct.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ extern int (*nrn2core_all_spike_vectors_return_)(std::vector<double>& spikevec,
113113
/* send all weights to NEURON */
114114
extern void (*nrn2core_all_weights_return_)(std::vector<double*>& weights);
115115

116+
/* get data array pointer from NEURON to copy into. */
117+
extern size_t (*nrn2core_type_return_)(int type, int tid, double*& data,
118+
double**& mdata);
116119
} // extern "C"
117120

118121
#endif /* nrn2core_direct_h */

coreneuron/mechanism/mech/enginemech.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,11 @@ int corenrn_embedded_run(int nthread,
9595
mk_mech_init(argc, argv);
9696

9797
// initialize extra arguments built into special-core
98-
coreneuron::modl_reg();
99-
98+
static bool modl_reg_called = false;
99+
if (!modl_reg_called) {
100+
coreneuron::modl_reg();
101+
modl_reg_called = true;
102+
}
100103
// run simulation
101104
run_solve_core(argc, argv);
102105

0 commit comments

Comments
 (0)