Skip to content

Commit

Permalink
Copies to NEURON the voltage, i_membrane_, and mechanism data. (BlueB…
Browse files Browse the repository at this point in the history
…rain/CoreNeuron#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.

CoreNEURON Repo SHA: BlueBrain/CoreNeuron@07bf5f1
  • Loading branch information
nrnhines authored Aug 26, 2020
1 parent 8212af9 commit 0868ba4
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/coreneuron/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ if(CORENRN_ENABLE_GPU)
${CMAKE_CURRENT_SOURCE_DIR}/utils/randoms/nrnran123.cpp
${CMAKE_CURRENT_SOURCE_DIR}/io/nrn_setup.cpp
${CMAKE_CURRENT_SOURCE_DIR}/io/setup_fornetcon.cpp
${CMAKE_CURRENT_SOURCE_DIR}/io/corenrn_data_return.cpp
${CMAKE_CURRENT_SOURCE_DIR}/io/global_vars.cpp)

set_source_files_properties(${DIMPLIC_CODE_FILE} ${NMODL_INBUILT_MOD_OUTPUTS} PROPERTIES
Expand Down
3 changes: 3 additions & 0 deletions src/coreneuron/apps/main1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ THE POSSIBILITY OF SUCH DAMAGE.
#include "coreneuron/network/multisend.hpp"
#include "coreneuron/io/file_utils.hpp"
#include "coreneuron/io/nrn2core_direct.h"
#include "coreneuron/io/core2nrn_data_return.hpp"

extern "C" {
const char* corenrn_version() {
Expand Down Expand Up @@ -609,6 +610,8 @@ extern "C" int run_solve_core(int argc, char** argv) {
(*nrn2core_all_weights_return_)(weights);
}

core2nrn_data_return();

{
Instrumentor::phase p("checkpoint");
write_checkpoint(nrn_threads, nrn_nthread, corenrn_param.checkpointpath.c_str());
Expand Down
174 changes: 174 additions & 0 deletions src/coreneuron/io/core2nrn_data_return.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/*
Copyright (c) 2020, Blue Brain Project
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "coreneuron/coreneuron.hpp"
#include "coreneuron/io/nrn2core_direct.h"
#include "coreneuron/sim/multicore.hpp"
#include "coreneuron/nrniv/nrniv_decl.h"
#include "coreneuron/io/core2nrn_data_return.hpp"

/** @brief, Information from NEURON to help with copying data to NEURON.
* Info for copying voltage, i_membrane_, and mechanism data.
* See implementaton in
* nrn/src/nrniv/nrnbbcore_write.cpp:nrnthreads_type_return.
* Return is size of either the returned data pointer or the number
* of pointers in mdata. tid is the thread index.
*/
size_t (*nrn2core_type_return_)(int type, int tid,
double*& data, double**& mdata);

namespace coreneuron {

/** @brief permuted array copied to unpermuted array
* If permute is NULL then just a copy
*/
static void inverse_permute_copy(size_t n, double* permuted_src, double* dest,
int* permute)
{
if (permute) {
for (size_t i = 0; i < n; ++i) {
dest[i] = permuted_src[permute[i]];
}
}else{
std::copy(permuted_src, permuted_src + n, dest);
}
}

/** @brief SoA permuted mechanism data copied to unpermuted AoS data.
* dest is an array of n pointers to the beginning of each sz length array.
* src is a contiguous array of sz segments of size stride. The stride
* may be slightly greater than n for purposes of alignment.
* Each of the sz segments of src are permuted.
*/
static void soa2aos_inverse_permute_copy(size_t n, int sz, int stride,
double* src, double** dest, int* permute)
{
// src is soa and permuted. dest is n pointers to sz doubles (aos).
for (size_t instance = 0; instance < n; ++instance) {
double* d = dest[instance];
double* s = src + permute[instance];
for (int i = 0; i < sz; ++i) {
d[i] = s[i*stride];
}
}
}

/** @brief SoA unpermuted mechanism data copied to unpermuted AoS data.
* dest is an array of n pointers to the beginning of each sz length array.
* src is a contiguous array of sz segments of size stride. The stride
* may be slightly greater than n for purposes of alignment.
* Each of the sz segments of src have the same order as the n pointers
* of dest.
*/
static void soa2aos_unpermuted_copy(size_t n, int sz, int stride,
double* src, double** dest)
{
// src is soa and permuted. dest is n pointers to sz doubles (aos).
for (size_t instance = 0; instance < n; ++instance) {
double* d = dest[instance];
double* s = src + instance;
for (int i = 0; i < sz; ++i) {
d[i] = s[i*stride];
}
}
}

/** @brief AoS mechanism data copied to AoS data.
* dest is an array of n pointers to the beginning of each sz length array.
* src is a contiguous array of n segments of size sz.
*/
static void aos2aos_copy(size_t n, int sz, double* src, double** dest) {
for (size_t instance = 0; instance < n; ++instance) {
double* d = dest[instance];
double* s = src + (instance*sz);
std::copy(s, s + sz, d);
}
}

/** @brief copy data back to NEURON.
* Copies t, voltage, i_membrane_ if it used, and mechanism param data.
*/
void core2nrn_data_return() {
if (!nrn2core_type_return_) {
return;
}
for (int tid = 0; tid < nrn_nthread; ++tid) {
size_t n = 0;
double* data = nullptr;
double** mdata = nullptr;
NrnThread& nt = nrn_threads[tid];

n = (*nrn2core_type_return_)(0, tid, data, mdata); // 0 means time
if (n) { // not the empty thread
data[0] = nt._t;
}

if (nt.end) { // transfer voltage and possibly i_membrane_
n = (*nrn2core_type_return_)(voltage, tid, data, mdata);
assert(n == size_t(nt.end) && data);
inverse_permute_copy(n, nt._actual_v, data, nt._permute);

if (nt.nrn_fast_imem) {
n = (*nrn2core_type_return_)(i_membrane_, tid, data, mdata);
assert(n == size_t(nt.end) && data);
inverse_permute_copy(n, nt.nrn_fast_imem->nrn_sav_rhs, data, nt._permute);
}
}

for (NrnThreadMembList* tml = nt.tml; tml; tml = tml->next) {
int mtype = tml->index;
Memb_list* ml = tml->ml;
n = (*nrn2core_type_return_)(mtype, tid, data, mdata);
assert(n == size_t(ml->nodecount) && mdata);
if (n == 0) {
continue;
}
// NEURON is AoS, CoreNEURON may be SoA and may be permuted.
// On the NEURON side, the data is actually contiguous because of
// cache_efficient, but that may not be the case for ARTIFICIAL_CELL.
// For initial implementation simplicity, use the mdata info which gives
// a double* for each param_size mech instance.
int* permute = ml->_permute;
double* cndat = ml->data;
int layout = corenrn.get_mech_data_layout()[mtype];
int sz = corenrn.get_prop_param_size()[mtype];
if (layout == 0) { /* SoA */
int stride = ml->_nodecount_padded;
if (permute) {
soa2aos_inverse_permute_copy(n, sz, stride, cndat, mdata, permute);
} else {
soa2aos_unpermuted_copy(n, sz, stride, cndat, mdata);
}
} else { /* AoS */
aos2aos_copy(n, sz, cndat, mdata);
}
}
}
}

} // namespace coreneuron
40 changes: 40 additions & 0 deletions src/coreneuron/io/core2nrn_data_return.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
Copyright (c) 2016, Blue Brain Project
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef _H_CORENRNDATARETURN_
#define _H_CORENRNDATARETURN_

namespace coreneuron {

/** @brief Copies back to NEURON the voltage, i_membrane_, and mechanism data.
*/
extern void core2nrn_data_return();

} // namespace coreneuron
#endif // _H_CORENRNDATARETURN_

3 changes: 3 additions & 0 deletions src/coreneuron/io/nrn2core_direct.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ extern int (*nrn2core_all_spike_vectors_return_)(std::vector<double>& spikevec,
/* send all weights to NEURON */
extern void (*nrn2core_all_weights_return_)(std::vector<double*>& weights);

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

#endif /* nrn2core_direct_h */
7 changes: 5 additions & 2 deletions src/coreneuron/mechanism/mech/enginemech.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,11 @@ int corenrn_embedded_run(int nthread,
mk_mech_init(argc, argv);

// initialize extra arguments built into special-core
coreneuron::modl_reg();

static bool modl_reg_called = false;
if (!modl_reg_called) {
coreneuron::modl_reg();
modl_reg_called = true;
}
// run simulation
run_solve_core(argc, argv);

Expand Down

0 comments on commit 0868ba4

Please sign in to comment.