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

Commit f0acbda

Browse files
author
Nicolas Cornu
authored
Refactoring of nrn_setup.cpp in separate phases (phase1.cpp / phase2.cpp) (#283)
Major refactoring of monolithic nrn_setup.cpp into two separate phases that allows to re-use the code for file based transfer as well as memory transfer: * Rewrite phase1, phase2 and move into separate .cpp files * Remove global static user variables * Add OMP_Mutex wrapper for handling OpenMP mutex * VecPlay now use std::vector instead of raw pointers - Give ownership of y_, t_ to VecPlayContinuous * Remove lock / unlock from fixed_vector as it was not used * Remove things related to endianess : code as well as tests * Use name of phase instead of numbers with template arguments * Check mechanism compatibility before reading data - if mechanism / mod file is different, we can't read data because sizes between neuron and coreneuron will be different. This will result into segfault / memory error. - check mechanism compatibility right after mechanism information is available Co-authored-by: Omar Awile <[email protected]> Co-authored-by: pramodk <[email protected]> Thanks @alkino for major work!
1 parent a56aa84 commit f0acbda

32 files changed

+1993
-2629
lines changed

CMake/ClangFormatHelper.cmake

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,6 @@ if(CLANG_FORMAT_FOUND)
2323
${CORENEURON_PROJECT_SOURCE_DIR}/coreneuron/*.h*
2424
${CORENEURON_PROJECT_SOURCE_DIR}/coreneuron/*.ipp*)
2525

26-
# exclude ezoption headers
27-
list(REMOVE_ITEM SRC_FILES_FOR_CLANG_FORMAT
28-
${CORENEURON_PROJECT_SOURCE_DIR}/coreneuron/utils/ezoption/ezOptionParser.hpp
29-
${CORENEURON_PROJECT_SOURCE_DIR}/coreneuron/utils/endianness.h
30-
${CORENEURON_PROJECT_SOURCE_DIR}/coreneuron/utils/swap_endian.h)
31-
3226
# exclude random123
3327
file(GLOB_RECURSE RANDOM123_FILES
3428
${CORENEURON_PROJECT_SOURCE_DIR}/coreneuron/utils/randoms/Random123/*.cpp

coreneuron/apps/main1.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ extern "C" int run_solve_core(int argc, char** argv) {
603603

604604
{
605605
Instrumentor::phase p("checkpoint");
606-
write_checkpoint(nrn_threads, nrn_nthread, corenrn_param.checkpointpath.c_str(), nrn_need_byteswap);
606+
write_checkpoint(nrn_threads, nrn_nthread, corenrn_param.checkpointpath.c_str());
607607
}
608608

609609
// must be done after checkpoint (to avoid deleting events)

coreneuron/gpu/nrn_acc_manager.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#endif
2323
namespace coreneuron {
2424
extern InterleaveInfo* interleave_info;
25-
void copy_ivoc_vect_to_device(IvocVect*& iv, IvocVect*& div);
25+
void copy_ivoc_vect_to_device(const IvocVect& iv, IvocVect& div);
2626
void nrn_ion_global_map_copyto_device();
2727
void nrn_VecPlay_copyto_device(NrnThread* nt, void** d_vecplay);
2828

@@ -389,21 +389,19 @@ void setup_nrnthreads_on_device(NrnThread* threads, int nthreads) {
389389
#endif
390390
}
391391

392-
void copy_ivoc_vect_to_device(IvocVect*& iv, IvocVect*& div) {
392+
void copy_ivoc_vect_to_device(const IvocVect& from, IvocVect& to) {
393393
#ifdef _OPENACC
394-
if (iv) {
395-
IvocVect* d_iv = (IvocVect*)acc_copyin(iv, sizeof(IvocVect));
396-
acc_memcpy_to_device(&div, &d_iv, sizeof(IvocVect*));
397-
398-
size_t n = iv->size();
399-
if (n) {
400-
double* d_data = (double*)acc_copyin(iv->data(), sizeof(double) * n);
401-
acc_memcpy_to_device(&(d_iv->data_), &d_data, sizeof(double*));
402-
}
394+
IvocVect* d_iv = (IvocVect*)acc_copyin((void*)&from, sizeof(IvocVect));
395+
acc_memcpy_to_device(&to, d_iv, sizeof(IvocVect));
396+
397+
size_t n = from.size();
398+
if (n) {
399+
double* d_data = (double*)acc_copyin((void*)from.data(), sizeof(double) * n);
400+
acc_memcpy_to_device(&(d_iv->data_), &d_data, sizeof(double*));
403401
}
404402
#else
405-
(void)iv;
406-
(void)div;
403+
(void)from;
404+
(void)to;
407405
#endif
408406
}
409407

@@ -1004,8 +1002,10 @@ void nrn_VecPlay_copyto_device(NrnThread* nt, void** d_vecplay) {
10041002
/** copy y_, t_ and discon_indices_ */
10051003
copy_ivoc_vect_to_device(vecplay_instance->y_, d_vecplay_instance->y_);
10061004
copy_ivoc_vect_to_device(vecplay_instance->t_, d_vecplay_instance->t_);
1007-
copy_ivoc_vect_to_device(vecplay_instance->discon_indices_,
1008-
d_vecplay_instance->discon_indices_);
1005+
if (vecplay_instance->discon_indices_) {
1006+
copy_ivoc_vect_to_device(*(vecplay_instance->discon_indices_),
1007+
*(d_vecplay_instance->discon_indices_));
1008+
}
10091009

10101010
/** copy PlayRecordEvent : todo: verify this */
10111011
PlayRecordEvent* d_e_ =

coreneuron/io/mem_layout_util.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include "mem_layout_util.hpp"
2+
3+
namespace coreneuron {
4+
5+
/// calculate size after padding for specific memory layout
6+
// Warning: this function is declared extern in nrniv_decl.h
7+
int nrn_soa_padded_size(int cnt, int layout) {
8+
return soa_padded_size<NRN_SOA_PAD>(cnt, layout);
9+
}
10+
11+
/// return the new offset considering the byte aligment settings
12+
size_t nrn_soa_byte_align(size_t size) {
13+
if (LAYOUT == Layout::SoA) {
14+
size_t dbl_align = NRN_SOA_BYTE_ALIGN / sizeof(double);
15+
size_t remainder = size % dbl_align;
16+
if (remainder) {
17+
size += dbl_align - remainder;
18+
}
19+
nrn_assert((size * sizeof(double)) % NRN_SOA_BYTE_ALIGN == 0);
20+
}
21+
return size;
22+
}
23+
24+
int nrn_i_layout(int icnt, int cnt, int isz, int sz, int layout) {
25+
switch(layout) {
26+
case Layout::AoS:
27+
return icnt * sz + isz;
28+
case Layout::SoA:
29+
int padded_cnt = nrn_soa_padded_size(cnt, layout); // may want to factor out to save time
30+
return icnt + isz * padded_cnt;
31+
}
32+
33+
nrn_assert(false);
34+
return 0;
35+
}
36+
37+
// file data is AoS. ie.
38+
// organized as cnt array instances of mtype each of size sz.
39+
// So input index i refers to i_instance*sz + i_item offset
40+
// Return the corresponding SoA index -- taking into account the
41+
// alignment requirements. Ie. i_instance + i_item*align_cnt.
42+
43+
int nrn_param_layout(int i, int mtype, Memb_list* ml) {
44+
int layout = corenrn.get_mech_data_layout()[mtype];
45+
switch(layout) {
46+
case Layout::AoS:
47+
return i;
48+
case Layout::SoA:
49+
nrn_assert(layout == Layout::SoA);
50+
int sz = corenrn.get_prop_param_size()[mtype];
51+
return nrn_i_layout(i / sz, ml->nodecount, i % sz, sz, layout);
52+
}
53+
nrn_assert(false);
54+
return 0;
55+
}
56+
} // namespace coreneuron

coreneuron/io/mem_layout_util.hpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#pragma once
2+
3+
#include "coreneuron/coreneuron.hpp"
4+
#include "coreneuron/nrniv/nrniv_decl.h"
5+
6+
namespace coreneuron {
7+
8+
#if !defined(NRN_SOA_PAD)
9+
// for layout 0, every range variable array must have a size which
10+
// is a multiple of NRN_SOA_PAD doubles
11+
#define NRN_SOA_PAD 8
12+
#endif
13+
14+
// If MATRIX_LAYOUT is 1 then a,b,d,rhs,v,area is not padded using NRN_SOA_PAD
15+
// When MATRIX_LAYOUT is 0 then mechanism pdata index values into _actual_v
16+
// and _actual_area data need to be updated.
17+
enum Layout {
18+
SoA = 0,
19+
AoS = 1
20+
};
21+
22+
#if !defined(LAYOUT)
23+
#define LAYOUT Layout::AoS
24+
#define MATRIX_LAYOUT Layout::AoS
25+
#else
26+
#define MATRIX_LAYOUT LAYOUT
27+
#endif
28+
29+
/// return the new offset considering the byte aligment settings
30+
size_t nrn_soa_byte_align(size_t i);
31+
32+
/// This function return the index in a flat array of a matrix coordinate (icnt, isz).
33+
/// The matrix size is (cnt, sz)
34+
/// Depending of the layout some padding can be calculated
35+
int nrn_i_layout(int icnt, int cnt, int isz, int sz, int layout);
36+
37+
// file data is AoS. ie.
38+
// organized as cnt array instances of mtype each of size sz.
39+
// So input index i refers to i_instance*sz + i_item offset
40+
// Return the corresponding SoA index -- taking into account the
41+
// alignment requirements. Ie. i_instance + i_item*align_cnt.
42+
43+
int nrn_param_layout(int i, int mtype, Memb_list* ml);
44+
} // namespace coreneuron
45+

0 commit comments

Comments
 (0)