From 7a34d78d569fc365fca115590564e08d4187ce76 Mon Sep 17 00:00:00 2001 From: Nicolas Cornu Date: Tue, 6 Jun 2023 16:18:18 +0200 Subject: [PATCH] New mpi way --- cmake/NeuronFileLists.cmake | 6 +- src/ivoc/nrnmain.cpp | 3 - src/nrniv/CMakeLists.txt | 34 +-- src/nrniv/bbsavestate.cpp | 7 - src/nrniv/multisend.cpp | 5 - src/nrniv/netpar.cpp | 57 +++- src/nrniv/splitcell.cpp | 2 - src/nrnmpi/core/resolve.cpp | 25 ++ src/nrnmpi/{ => lib}/bbsmpipack.cpp | 56 ++-- src/nrnmpi/{ => lib}/mpispike.cpp | 180 ++++++------ src/nrnmpi/lib/mpispike.h | 0 src/nrnmpi/{ => lib}/nrnmpi.cpp | 24 +- src/nrnmpi/{nrnmpi_impl.h => lib/nrnmpi.hpp} | 0 src/nrnmpi/mkdynam.sh | 58 ---- src/nrnmpi/mpispike.h | 53 ---- src/nrnmpi/notes_nrnrt | 62 ---- src/nrnmpi/nrnmpi.h | 71 +++++ src/nrnmpi/nrnmpi_def_cinc | 27 -- src/nrnmpi/nrnmpi_dynam.cpp | 259 ----------------- src/nrnmpi/nrnmpi_dynam_stubs.cpp | 31 -- src/nrnmpi/nrnmpidec.h | 283 +++++++++++-------- src/oc/nrnmpi.h | 5 - src/oc/nrnmpi_dynam_stubs.cpp | 1 - src/parallel/bbsclimpi.cpp | 2 - src/parallel/bbsdirectmpi.cpp | 1 - src/parallel/bbssrvmpi.cpp | 4 +- 26 files changed, 453 insertions(+), 803 deletions(-) create mode 100644 src/nrnmpi/core/resolve.cpp rename src/nrnmpi/{ => lib}/bbsmpipack.cpp (91%) rename src/nrnmpi/{ => lib}/mpispike.cpp (77%) create mode 100644 src/nrnmpi/lib/mpispike.h rename src/nrnmpi/{ => lib}/nrnmpi.cpp (94%) rename src/nrnmpi/{nrnmpi_impl.h => lib/nrnmpi.hpp} (100%) delete mode 100644 src/nrnmpi/mkdynam.sh delete mode 100644 src/nrnmpi/mpispike.h delete mode 100644 src/nrnmpi/notes_nrnrt create mode 100644 src/nrnmpi/nrnmpi.h delete mode 100644 src/nrnmpi/nrnmpi_def_cinc delete mode 100644 src/nrnmpi/nrnmpi_dynam.cpp delete mode 100644 src/nrnmpi/nrnmpi_dynam_stubs.cpp delete mode 100644 src/oc/nrnmpi_dynam_stubs.cpp diff --git a/cmake/NeuronFileLists.cmake b/cmake/NeuronFileLists.cmake index 8e73003a7e..33e09fe5ef 100644 --- a/cmake/NeuronFileLists.cmake +++ b/cmake/NeuronFileLists.cmake @@ -533,8 +533,6 @@ set(NMODL_FILES_LIST set(IVOS_FILES_LIST listimpl.cpp string.cpp observe.cpp regexp.cpp resource.cpp) -set(MPI_DYNAMIC_INCLUDE nrnmpi_dynam.h nrnmpi_dynam_cinc nrnmpi_dynam_wrappers.inc) - set(NRN_MUSIC_FILES_LIST nrnmusic.cpp) # ============================================================================= @@ -570,7 +568,7 @@ nrn_create_file_list(NRN_SPARSE13_SRC_FILES ${PROJECT_SOURCE_DIR}/src/sparse13 ${SPARSE13_FILES_LIST}) nrn_create_file_list(NRN_SCOPMATH_SRC_FILES ${PROJECT_SOURCE_DIR}/src/scopmath ${SCOPMATH_FILES_LIST}) -nrn_create_file_list(NRN_NRNMPI_SRC_FILES ${PROJECT_SOURCE_DIR}/src/nrnmpi ${NRNMPI_FILES_LIST}) +nrn_create_file_list(NRN_NRNMPI_SRC_FILES ${PROJECT_SOURCE_DIR}/src/nrnmpi/lib ${NRNMPI_FILES_LIST}) nrn_create_file_list(NRN_NRNGNU_SRC_FILES ${PROJECT_SOURCE_DIR}/src/gnu ${NRNGNU_FILES_LIST}) nrn_create_file_list(NRN_NRNPYTHON_SRC_FILES ${PROJECT_SOURCE_DIR}/src/nrnpython ${NRNPYTHON_FILES_LIST}) @@ -579,8 +577,6 @@ nrn_create_file_list(NRN_BIN_SRC_FILES ${PROJECT_SOURCE_DIR}/src/ivoc/ nrnmain.c nrn_create_file_list(NRN_BIN_SRC_FILES ${PROJECT_SOURCE_DIR}/src/oc/ ockludge.cpp modlreg.cpp) nrn_create_file_list(NRN_MODLUNIT_SRC_FILES ${NRN_MODLUNIT_SRC_DIR} ${MODLUNIT_FILES_LIST}) nrn_create_file_list(NRN_NMODL_SRC_FILES ${NRN_NMODL_SRC_DIR} ${NMODL_FILES_LIST}) -nrn_create_file_list(NRNMPI_DYNAMIC_INCLUDE_FILE ${PROJECT_SOURCE_DIR}/src/nrnmpi - ${MPI_DYNAMIC_INCLUDE}) nrn_create_file_list(NRN_IVOS_SRC_FILES ${NRN_IVOS_SRC_DIR} ${IVOS_FILES_LIST}) nrn_create_file_list(NRN_MUSIC_SRC_FILES ${NRN_MUSIC_SRC_DIR} ${NRN_MUSIC_FILES_LIST}) list(APPEND NRN_OC_SRC_FILES ${PROJECT_BINARY_DIR}/src/oc/hocusr.h) diff --git a/src/ivoc/nrnmain.cpp b/src/ivoc/nrnmain.cpp index 5b5b7ee5d6..2d2fd514f7 100644 --- a/src/ivoc/nrnmain.cpp +++ b/src/ivoc/nrnmain.cpp @@ -16,9 +16,6 @@ void nrnmpi_load_or_exit(bool is_python); void nrnmusic_load(); #endif // NRN_MUSIC #endif // NRNMPI_DYNAMICLOAD -#if NRNMPI -extern "C" void nrnmpi_init(int nrnmpi_under_nrncontrol, int* pargc, char*** pargv); -#endif int main(int argc, char** argv, char** env) { nrn_main_launch = 1; diff --git a/src/nrniv/CMakeLists.txt b/src/nrniv/CMakeLists.txt index 7dc4b67315..d23596db6c 100644 --- a/src/nrniv/CMakeLists.txt +++ b/src/nrniv/CMakeLists.txt @@ -156,14 +156,17 @@ set(NRN_NRNIV_LIB_SRC_FILES ${NRN_SPARSE13_SRC_FILES} ${NRN_SUNDIALS_SRC_FILES}) +set(NRN_MPI_LIB_NAME "nrn_mpi" CACHE INTERNAL "") if(NRN_ENABLE_MPI) list(APPEND NRN_NRNIV_LIB_SRC_FILES ${NRN_PARALLEL_SRC_FILES}) -endif() -if(NRN_ENABLE_MPI_DYNAMIC) - list(APPEND NRN_NRNIV_LIB_SRC_FILES ${PROJECT_SOURCE_DIR}/src/nrnmpi/nrnmpi_dynam.cpp) -else() - list(APPEND NRN_NRNIV_LIB_SRC_FILES ${NRN_NRNMPI_SRC_FILES}) + if(NRN_ENABLE_MPI_DYNAMIC) + add_library(${NRN_MPI_LIB_NAME} OBJECT ${NRN_NRNMPI_SRC_FILES}) + target_include_directories( + ${NRN_MPI_LIB_NAME} PRIVATE ${MPI_C_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src) + set_property(TARGET ${NRN_MPI_LIB_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON) + set(CORENRN_MPI_OBJ $init(i); diff --git a/src/nrniv/netpar.cpp b/src/nrniv/netpar.cpp index f31951bbe8..d7f4e46fb3 100644 --- a/src/nrniv/netpar.cpp +++ b/src/nrniv/netpar.cpp @@ -34,6 +34,55 @@ static int n_multisend_interval; int nrnmusic; #endif +#ifndef nrn_spikebuf_size +#define nrn_spikebuf_size 0 +#endif + +// Variable from MPI +#if nrn_spikebuf_size > 0 +typedef struct { + int nspike; + int gid[nrn_spikebuf_size]; + double spiketime[nrn_spikebuf_size]; +} NRNMPI_Spikebuf; +#endif + + +#define icapacity_ nrnmpi_i_capacity_ +#define spikeout_ nrnmpi_spikeout_ +#define spikein_ nrnmpi_spikein_ +#define nout_ nrnmpi_nout_ +#define nin_ nrnmpi_nin_ +extern int nout_; +extern int* nin_; +extern int icapacity_; +extern NRNMPI_Spike* spikeout_; +extern NRNMPI_Spike* spikein_; + +#define spfixout_ nrnmpi_spikeout_fixed_ +#define spfixin_ nrnmpi_spikein_fixed_ +#define spfixin_ovfl_ nrnmpi_spikein_fixed_ovfl_ +#define localgid_size_ nrnmpi_localgid_size_ +#define ag_send_size_ nrnmpi_ag_send_size_ +#define ag_send_nspike_ nrnmpi_send_nspike_ +#define ovfl_capacity_ nrnmpi_ovfl_capacity_ +#define ovfl_ nrnmpi_ovfl_ +extern int localgid_size_; /* bytes */ +extern int ag_send_size_; /* bytes */ +extern int ag_send_nspike_; /* spikes */ +extern int ovfl_capacity_; /* spikes */ +extern int ovfl_; /* spikes */ +extern unsigned char* spfixout_; +extern unsigned char* spfixin_; +extern unsigned char* spfixin_ovfl_; +//end variables + +#if nrn_spikebuf_size > 0 +#define spbufout_ nrnmpi_spbufout_ +#define spbufin_ nrnmpi_spbufin_ +extern NRNMPI_Spikebuf* spbufout_; +extern NRNMPI_Spikebuf* spbufin_; +#endif static Symbol* netcon_sym_; static Gid2PreSyn gid2out_; static Gid2PreSyn gid2in_; @@ -88,11 +137,9 @@ static double set_mindelay(double maxdelay); #if NRNMPI -#include "../nrnmpi/mpispike.h" +// #include "../nrnmpi/mpispike.h" void nrn_timeout(int); -extern int nrnmpi_int_allmax(int); -extern void nrnmpi_int_allgather(int*, int*, int); void nrn2ncs_outputevent(int netcon_output_index, double firetime); bool nrn_use_compress_; // global due to bbsavestate #define use_compress_ nrn_use_compress_ @@ -574,7 +621,7 @@ void nrn_spike_exchange(NrnThread* nt) { nrnmpi_barrier(); nrnmpi_step_wait_ += nrnmpi_wtime() - wt; } - n = nrnmpi_spike_exchange(); + n = nrnmpi_spike_exchange(nin_, &nout_, &icapacity_, &spikein_, &spikeout_); wt_ = nrnmpi_wtime() - wt; wt = nrnmpi_wtime(); TBUF @@ -670,7 +717,7 @@ void nrn_spike_exchange_compressed(NrnThread* nt) { nrnmpi_barrier(); nrnmpi_step_wait_ += nrnmpi_wtime() - wt; } - n = nrnmpi_spike_exchange_compressed(); + n = nrnmpi_spike_exchange_compressed(nin_, spfixin_ovfl_, spfixout_, spfixin_, ag_send_size_, ag_send_nspike_, localgid_size_, &ovfl_capacity_, &ovfl_); wt_ = nrnmpi_wtime() - wt; wt = nrnmpi_wtime(); TBUF diff --git a/src/nrniv/splitcell.cpp b/src/nrniv/splitcell.cpp index b21bbf7fc5..1b4fa3205f 100644 --- a/src/nrniv/splitcell.cpp +++ b/src/nrniv/splitcell.cpp @@ -21,8 +21,6 @@ the subtrees is no longer required by this implementation. #if PARANEURON void nrnmpi_split_clear(); extern void (*nrnmpi_splitcell_compute_)(); -extern void nrnmpi_send_doubles(double*, int cnt, int dest, int tag); -extern void nrnmpi_recv_doubles(double*, int cnt, int src, int tag); extern double nrnmpi_splitcell_wait_; static int change_cnt_; diff --git a/src/nrnmpi/core/resolve.cpp b/src/nrnmpi/core/resolve.cpp new file mode 100644 index 0000000000..ecb47894a6 --- /dev/null +++ b/src/nrnmpi/core/resolve.cpp @@ -0,0 +1,25 @@ +#include +#include +#include "../nrnmpi.h" + +// Those functions are part of a mechanism to dynamically load mpi or not +void mpi_manager_t::resolve_symbols(void* handle) { + for (auto* ptr: m_function_ptrs) { + assert(!(*ptr)); + ptr->resolve(handle); + assert(*ptr); + } +} + +void mpi_function_base::resolve(void* handle) { + dlerror(); + void* ptr = dlsym(handle, m_name); + const char* error = dlerror(); + if (error) { + std::ostringstream oss; + oss << "Could not get symbol " << m_name << " from handle " << handle << ": " << error; + throw std::runtime_error(oss.str()); + } + assert(ptr); + m_fptr = ptr; +} diff --git a/src/nrnmpi/bbsmpipack.cpp b/src/nrnmpi/lib/bbsmpipack.cpp similarity index 91% rename from src/nrnmpi/bbsmpipack.cpp rename to src/nrnmpi/lib/bbsmpipack.cpp index c939cb852d..847383a3f4 100644 --- a/src/nrnmpi/bbsmpipack.cpp +++ b/src/nrnmpi/lib/bbsmpipack.cpp @@ -5,10 +5,6 @@ /* do not want the redef in the dynamic load case */ #include -#if NRNMPI_DYNAMICLOAD -#include -#endif - #include #if NRNMPI @@ -19,7 +15,7 @@ #include #include #include -#include +#include "nrnmpi.hpp" #include #if 0 @@ -98,7 +94,7 @@ static void unpack(void* buf, int count, int my_datatype, bbsmpibuf* r, const ch guard(MPI_Unpack(r->buf, r->size, &r->upkpos, buf, count, mytypes[my_datatype], nrn_bbs_comm)); } -void nrnmpi_upkbegin(bbsmpibuf* r) { +void nrnmpi_upkbegin_impl(bbsmpibuf* r) { int type; int p; #if debug @@ -126,7 +122,7 @@ void nrnmpi_upkbegin(bbsmpibuf* r) { r->keypos = p; } -char* nrnmpi_getkey(bbsmpibuf* r) { +char* nrnmpi_getkey_impl(bbsmpibuf* r) { char* s; int type; type = r->upkpos; @@ -144,7 +140,7 @@ char* nrnmpi_getkey(bbsmpibuf* r) { return s; } -int nrnmpi_getid(bbsmpibuf* r) { +int nrnmpi_getid_impl(bbsmpibuf* r) { int i, type; type = r->upkpos; r->upkpos = r->keypos; @@ -159,19 +155,19 @@ int nrnmpi_getid(bbsmpibuf* r) { return i; } -int nrnmpi_upkint(bbsmpibuf* r) { +int nrnmpi_upkint_impl(bbsmpibuf* r) { int i; unpack(&i, 1, my_MPI_INT, r, "upkint"); return i; } -double nrnmpi_upkdouble(bbsmpibuf* r) { +double nrnmpi_upkdouble_impl(bbsmpibuf* r) { double x; unpack(&x, 1, my_MPI_DOUBLE, r, "upkdouble"); return x; } -void nrnmpi_upkvec(int n, double* x, bbsmpibuf* r) { +void nrnmpi_upkvec_impl(int n, double* x, bbsmpibuf* r) { unpack(x, n, my_MPI_DOUBLE, r, "upkvec"); } @@ -183,7 +179,7 @@ So fill this in explicitly in nrnmpi_dynam.cpp char* (*p_cxx_char_alloc)(int len); #endif -char* nrnmpi_upkstr(bbsmpibuf* r) { +char* nrnmpi_upkstr_impl(bbsmpibuf* r) { int len; char* s; unpack(&len, 1, my_MPI_INT, r, "upkstr length"); @@ -197,7 +193,7 @@ char* nrnmpi_upkstr(bbsmpibuf* r) { return s; } -char* nrnmpi_upkpickle(size_t* size, bbsmpibuf* r) { +char* nrnmpi_upkpickle_impl(size_t* size, bbsmpibuf* r) { int len; char* s; unpack(&len, 1, my_MPI_INT, r, "upkpickle length"); @@ -221,7 +217,7 @@ static void resize(bbsmpibuf* r, int size) { } } -void nrnmpi_pkbegin(bbsmpibuf* r) { +void nrnmpi_pkbegin_impl(bbsmpibuf* r) { int type; if (nrnmpi_myid_bbs == -1) { hoc_execerror("subworld process with nhost > 0 cannot use", "the bulletin board"); @@ -235,7 +231,7 @@ void nrnmpi_pkbegin(bbsmpibuf* r) { guard(MPI_Pack(&type, 1, MPI_INT, r->buf, r->size, &r->pkposition, nrn_bbs_comm)); } -void nrnmpi_enddata(bbsmpibuf* r) { +void nrnmpi_enddata_impl(bbsmpibuf* r) { int p, type, isize, oldsize; p = r->pkposition; type = 0; @@ -303,36 +299,36 @@ static void pack(void* inbuf, int incount, int my_datatype, bbsmpibuf* r, const #endif } -void nrnmpi_pkint(int i, bbsmpibuf* r) { +void nrnmpi_pkint_impl(int i, bbsmpibuf* r) { int ii; ii = i; pack(&ii, 1, my_MPI_INT, r, "pkint"); } -void nrnmpi_pkdouble(double x, bbsmpibuf* r) { +void nrnmpi_pkdouble_impl(double x, bbsmpibuf* r) { double xx; xx = x; pack(&xx, 1, my_MPI_DOUBLE, r, "pkdouble"); } -void nrnmpi_pkvec(int n, double* x, bbsmpibuf* r) { +void nrnmpi_pkvec_impl(int n, double* x, bbsmpibuf* r) { pack(x, n, my_MPI_DOUBLE, r, "pkvec"); } -void nrnmpi_pkstr(const char* s, bbsmpibuf* r) { +void nrnmpi_pkstr_impl(const char* s, bbsmpibuf* r) { int len; len = strlen(s); pack(&len, 1, my_MPI_INT, r, "pkstr length"); pack((char*) s, len, my_MPI_CHAR, r, "pkstr string"); } -void nrnmpi_pkpickle(const char* s, size_t size, bbsmpibuf* r) { +void nrnmpi_pkpickle_impl(const char* s, size_t size, bbsmpibuf* r) { int len = size; pack(&len, 1, my_MPI_INT, r, "pkpickle length"); pack((char*) s, len, my_MPI_PICKLE, r, "pkpickle data"); } -void nrnmpi_bbssend(int dest, int tag, bbsmpibuf* r) { +void nrnmpi_bbssend_impl(int dest, int tag, bbsmpibuf* r) { #if debug printf("%d nrnmpi_bbssend %p dest=%d tag=%d size=%d\n", nrnmpi_myid_bbs, @@ -369,7 +365,7 @@ void nrnmpi_bbssend(int dest, int tag, bbsmpibuf* r) { #endif } -int nrnmpi_bbsrecv(int source, bbsmpibuf* r) { +int nrnmpi_bbsrecv_impl(int source, bbsmpibuf* r) { MPI_Status status; int size; if (source == -1) { @@ -408,7 +404,7 @@ int nrnmpi_bbsrecv(int source, bbsmpibuf* r) { return status.MPI_TAG; } -int nrnmpi_bbssendrecv(int dest, int tag, bbsmpibuf* s, bbsmpibuf* r) { +int nrnmpi_bbssendrecv_impl(int dest, int tag, bbsmpibuf* s, bbsmpibuf* r) { int size, itag, source; int msgtag; MPI_Status status; @@ -424,7 +420,7 @@ int nrnmpi_bbssendrecv(int dest, int tag, bbsmpibuf* s, bbsmpibuf* r) { return nrnmpi_bbsrecv(dest, r); } -int nrnmpi_iprobe(int* size, int* tag, int* source) { +int nrnmpi_iprobe_impl(int* size, int* tag, int* source) { int flag = 0; MPI_Status status; guard(MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, nrn_bbs_comm, &flag, &status)); @@ -439,7 +435,7 @@ int nrnmpi_iprobe(int* size, int* tag, int* source) { return flag; } -void nrnmpi_probe(int* size, int* tag, int* source) { +void nrnmpi_probe_impl(int* size, int* tag, int* source) { int flag = 0; MPI_Status status; guard(MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, nrn_bbs_comm, &status)); @@ -451,7 +447,7 @@ void nrnmpi_probe(int* size, int* tag, int* source) { guard(MPI_Get_count(&status, MPI_PACKED, size)); } -bbsmpibuf* nrnmpi_newbuf(int size) { +bbsmpibuf* nrnmpi_newbuf_impl(int size) { bbsmpibuf* buf; buf = (bbsmpibuf*) hoc_Emalloc(sizeof(bbsmpibuf)); hoc_malchk(); @@ -474,7 +470,7 @@ bbsmpibuf* nrnmpi_newbuf(int size) { return buf; } -void nrnmpi_copy(bbsmpibuf* dest, bbsmpibuf* src) { +void nrnmpi_copy_impl(bbsmpibuf* dest, bbsmpibuf* src) { int i; resize(dest, src->size); for (i = 0; i < src->size; ++i) { @@ -498,12 +494,12 @@ static void nrnmpi_free(bbsmpibuf* buf) { #endif } -void nrnmpi_ref(bbsmpibuf* buf) { +void nrnmpi_ref_impl(bbsmpibuf* buf) { assert(buf); buf->refcount += 1; } -void nrnmpi_unref(bbsmpibuf* buf) { +void nrnmpi_unref_impl(bbsmpibuf* buf) { if (buf) { --buf->refcount; if (buf->refcount <= 0) { @@ -513,7 +509,7 @@ void nrnmpi_unref(bbsmpibuf* buf) { } #if nrnmpidebugleak -void nrnmpi_checkbufleak() { +void nrnmpi_checkbufleak_impl() { if (nrnmpi_bufcnt_ > 0) { printf("%d nrnmpi_bufcnt=%d\n", nrnmpi_myid_bbs, nrnmpi_bufcnt_); } diff --git a/src/nrnmpi/mpispike.cpp b/src/nrnmpi/lib/mpispike.cpp similarity index 77% rename from src/nrnmpi/mpispike.cpp rename to src/nrnmpi/lib/mpispike.cpp index 5524c0f233..ceea6e0d9d 100644 --- a/src/nrnmpi/mpispike.cpp +++ b/src/nrnmpi/lib/mpispike.cpp @@ -7,16 +7,12 @@ /* do not want the redef in the dynamic load case */ #include -#if NRNMPI_DYNAMICLOAD -#include -#endif - #include #include #if NRNMPI #include "nrnmpidec.h" -#include "nrnmpi_impl.h" +#include "nrnmpi.hpp" #include "mpispike.h" #include @@ -58,7 +54,7 @@ static void make_spike_type() { MPI_Op_create((MPI_User_function*) pgvts_op, 1, &mpi_pgvts_op); } -void nrnmpi_spike_initialize() { +void nrnmpi_spike_initialize_impl_impl() { make_spike_type(); } @@ -95,7 +91,7 @@ static void make_spikebuf_type() { } #endif -int nrnmpi_spike_exchange() { +int nrnmpi_spike_exchange_impl(int* nin, int* nout, int* icapacity, NRNMPI_Spike** spikein, NRNMPI_Spike** spikeout) { int i, n, novfl, n1; if (!displs) { np = nrnmpi_numprocs; @@ -108,52 +104,52 @@ int nrnmpi_spike_exchange() { } nrnbbs_context_wait(); #if nrn_spikebuf_size == 0 - MPI_Allgather(&nout_, 1, MPI_INT, nin_, 1, MPI_INT, nrnmpi_comm); - n = nin_[0]; + MPI_Allgather(nout, 1, MPI_INT, nin, 1, MPI_INT, nrnmpi_comm); + n = nin[0]; for (i = 1; i < np; ++i) { displs[i] = n; - n += nin_[i]; + n += nin[i]; } if (n) { - if (icapacity_ < n) { - icapacity_ = n + 10; - free(spikein_); - spikein_ = (NRNMPI_Spike*) hoc_Emalloc(icapacity_ * sizeof(NRNMPI_Spike)); + if (*icapacity < n) { + *icapacity = n + 10; + free(*spikein); + *spikein = (NRNMPI_Spike*) hoc_Emalloc(*icapacity * sizeof(NRNMPI_Spike)); hoc_malchk(); } MPI_Allgatherv( - spikeout_, nout_, spike_type, spikein_, nin_, displs, spike_type, nrnmpi_comm); + *spikeout, *nout, spike_type, *spikein, nin, displs, spike_type, nrnmpi_comm); } #else MPI_Allgather(spbufout_, 1, spikebuf_type, spbufin_, 1, spikebuf_type, nrnmpi_comm); novfl = 0; n = spbufin_[0].nspike; if (n > nrn_spikebuf_size) { - nin_[0] = n - nrn_spikebuf_size; - novfl += nin_[0]; + nin[0] = n - nrn_spikebuf_size; + novfl += nin[0]; } else { - nin_[0] = 0; + nin[0] = 0; } for (i = 1; i < np; ++i) { displs[i] = novfl; n1 = spbufin_[i].nspike; n += n1; if (n1 > nrn_spikebuf_size) { - nin_[i] = n1 - nrn_spikebuf_size; - novfl += nin_[i]; + nin[i] = n1 - nrn_spikebuf_size; + novfl += nin[i]; } else { - nin_[i] = 0; + nin[i] = 0; } } if (novfl) { - if (icapacity_ < novfl) { - icapacity_ = novfl + 10; - free(spikein_); - spikein_ = (NRNMPI_Spike*) hoc_Emalloc(icapacity_ * sizeof(NRNMPI_Spike)); + if (*icapacity < novfl) { + *icapacity = novfl + 10; + free(*spikein); + *spikein = (NRNMPI_Spike*) hoc_Emalloc(*icapacity * sizeof(NRNMPI_Spike)); hoc_malchk(); } - n1 = (nout_ > nrn_spikebuf_size) ? nout_ - nrn_spikebuf_size : 0; - MPI_Allgatherv(spikeout_, n1, spike_type, spikein_, nin_, displs, spike_type, nrnmpi_comm); + n1 = (*nout > nrn_spikebuf_size) ? *nout - nrn_spikebuf_size : 0; + MPI_Allgatherv(*spikeout, n1, spike_type, *spikein, nin, displs, spike_type, nrnmpi_comm); } ovfl_ = novfl; #endif @@ -178,7 +174,7 @@ a sequence of spiketime, localgid pairs. There are nspike of them. The allgather sends the first part of the buf and the allgatherv buffer sends any overflow. */ -int nrnmpi_spike_exchange_compressed() { +int nrnmpi_spike_exchange_compressed_impl(int* nin, unsigned char*& spfixin_ovfl, unsigned char* spikeout_fixed, unsigned char* spikein_fixed, int ag_send_size, int ag_send_nspike, int localgid_size, int* ovfl_capacity, int* ovfl) { int i, novfl, n, ntot, idx, bs, bstot; /* n is #spikes, bs is #byte overflow */ if (!displs) { np = nrnmpi_numprocs; @@ -193,55 +189,55 @@ int nrnmpi_spike_exchange_compressed() { nrnbbs_context_wait(); MPI_Allgather( - spfixout_, ag_send_size_, MPI_BYTE, spfixin_, ag_send_size_, MPI_BYTE, nrnmpi_comm); + spikeout_fixed, ag_send_size, MPI_BYTE, spikein_fixed, ag_send_size, MPI_BYTE, nrnmpi_comm); novfl = 0; ntot = 0; bstot = 0; for (i = 0; i < np; ++i) { displs[i] = bstot; - idx = i * ag_send_size_; - n = spfixin_[idx++] * 256; - n += spfixin_[idx++]; + idx = i * ag_send_size; + n = spikein_fixed[idx++] * 256; + n += spikein_fixed[idx++]; ntot += n; - nin_[i] = n; - if (n > ag_send_nspike_) { - bs = 2 + n * (1 + localgid_size_) - ag_send_size_; + nin[i] = n; + if (n > ag_send_nspike) { + bs = 2 + n * (1 + localgid_size) - ag_send_size; byteovfl[i] = bs; bstot += bs; - novfl += n - ag_send_nspike_; + novfl += n - ag_send_nspike; } else { byteovfl[i] = 0; } } if (novfl) { - if (ovfl_capacity_ < novfl) { - ovfl_capacity_ = novfl + 10; - free(spfixin_ovfl_); - spfixin_ovfl_ = (unsigned char*) hoc_Emalloc(ovfl_capacity_ * (1 + localgid_size_) * + if (*ovfl_capacity < novfl) { + *ovfl_capacity = novfl + 10; + free(spfixin_ovfl); + spfixin_ovfl = (unsigned char*) hoc_Emalloc(*ovfl_capacity * (1 + localgid_size) * sizeof(unsigned char)); hoc_malchk(); } bs = byteovfl[nrnmpi_myid]; /* - note that the spfixout_ buffer is one since the overflow - is contiguous to the first part. But the spfixin_ovfl_ is - completely separate from the spfixin_ since the latter + note that the spikeout_fixed buffer is one since the overflow + is contiguous to the first part. But the spfixin_ovfl is + completely separate from the spikein_fixed since the latter dynamically changes its size during a run. */ - MPI_Allgatherv(spfixout_ + ag_send_size_, + MPI_Allgatherv(spikeout_fixed + ag_send_size, bs, MPI_BYTE, - spfixin_ovfl_, + spfixin_ovfl, byteovfl, displs, MPI_BYTE, nrnmpi_comm); } - ovfl_ = novfl; + *ovfl = novfl; return ntot; } -double nrnmpi_mindelay(double m) { +double nrnmpi_mindelay_impl(double m) { double result; if (!nrnmpi_use) { return m; @@ -251,7 +247,7 @@ double nrnmpi_mindelay(double m) { return result; } -int nrnmpi_int_allmax(int x) { +int nrnmpi_int_allmax_impl(int x) { int result; if (nrnmpi_numprocs < 2) { return x; @@ -349,7 +345,7 @@ static int MPI_Alltoallv_sparse(void* sendbuf, } -extern void nrnmpi_dbl_alltoallv_sparse(double* s, +extern void nrnmpi_dbl_alltoallv_sparse_impl(double* s, int* scnt, int* sdispl, double* r, @@ -357,7 +353,7 @@ extern void nrnmpi_dbl_alltoallv_sparse(double* s, int* rdispl) { MPI_Alltoallv_sparse(s, scnt, sdispl, MPI_DOUBLE, r, rcnt, rdispl, MPI_DOUBLE, nrnmpi_comm); } -extern void nrnmpi_int_alltoallv_sparse(int* s, +extern void nrnmpi_int_alltoallv_sparse_impl(int* s, int* scnt, int* sdispl, int* r, @@ -366,7 +362,7 @@ extern void nrnmpi_int_alltoallv_sparse(int* s, MPI_Alltoallv_sparse(s, scnt, sdispl, MPI_INT, r, rcnt, rdispl, MPI_INT, nrnmpi_comm); } -extern void nrnmpi_long_alltoallv_sparse(int64_t* s, +extern void nrnmpi_long_alltoallv_sparse_impl(int64_t* s, int* scnt, int* sdispl, int64_t* r, @@ -376,35 +372,35 @@ extern void nrnmpi_long_alltoallv_sparse(int64_t* s, } -extern void nrnmpi_int_gather(int* s, int* r, int cnt, int root) { +extern void nrnmpi_int_gather_impl(int* s, int* r, int cnt, int root) { MPI_Gather(s, cnt, MPI_INT, r, cnt, MPI_INT, root, nrnmpi_comm); } -extern void nrnmpi_int_gatherv(int* s, int scnt, int* r, int* rcnt, int* rdispl, int root) { +extern void nrnmpi_int_gatherv_impl(int* s, int scnt, int* r, int* rcnt, int* rdispl, int root) { MPI_Gatherv(s, scnt, MPI_INT, r, rcnt, rdispl, MPI_INT, root, nrnmpi_comm); } -extern void nrnmpi_char_gatherv(char* s, int scnt, char* r, int* rcnt, int* rdispl, int root) { +extern void nrnmpi_char_gatherv_impl(char* s, int scnt, char* r, int* rcnt, int* rdispl, int root) { MPI_Gatherv(s, scnt, MPI_CHAR, r, rcnt, rdispl, MPI_CHAR, root, nrnmpi_comm); } -extern void nrnmpi_int_scatter(int* s, int* r, int cnt, int root) { +extern void nrnmpi_int_scatter_impl(int* s, int* r, int cnt, int root) { MPI_Scatter(s, cnt, MPI_INT, r, cnt, MPI_INT, root, nrnmpi_comm); } -extern void nrnmpi_char_scatterv(char* s, int* scnt, int* sdispl, char* r, int rcnt, int root) { +extern void nrnmpi_char_scatterv_impl(char* s, int* scnt, int* sdispl, char* r, int rcnt, int root) { MPI_Scatterv(s, scnt, sdispl, MPI_CHAR, r, rcnt, MPI_CHAR, root, nrnmpi_comm); } -extern void nrnmpi_int_alltoall(int* s, int* r, int n) { +extern void nrnmpi_int_alltoall_impl(int* s, int* r, int n) { MPI_Alltoall(s, n, MPI_INT, r, n, MPI_INT, nrnmpi_comm); } -extern void nrnmpi_int_alltoallv(int* s, int* scnt, int* sdispl, int* r, int* rcnt, int* rdispl) { +extern void nrnmpi_int_alltoallv_impl(int* s, int* scnt, int* sdispl, int* r, int* rcnt, int* rdispl) { MPI_Alltoallv(s, scnt, sdispl, MPI_INT, r, rcnt, rdispl, MPI_INT, nrnmpi_comm); } -extern void nrnmpi_long_alltoallv(int64_t* s, +extern void nrnmpi_long_alltoallv_impl(int64_t* s, int* scnt, int* sdispl, int64_t* r, @@ -413,7 +409,7 @@ extern void nrnmpi_long_alltoallv(int64_t* s, MPI_Alltoallv(s, scnt, sdispl, MPI_INT64_T, r, rcnt, rdispl, MPI_INT64_T, nrnmpi_comm); } -extern void nrnmpi_dbl_alltoallv(double* s, +extern void nrnmpi_dbl_alltoallv_impl(double* s, int* scnt, int* sdispl, double* r, @@ -422,7 +418,7 @@ extern void nrnmpi_dbl_alltoallv(double* s, MPI_Alltoallv(s, scnt, sdispl, MPI_DOUBLE, r, rcnt, rdispl, MPI_DOUBLE, nrnmpi_comm); } -extern void nrnmpi_char_alltoallv(char* s, +extern void nrnmpi_char_alltoallv_impl(char* s, int* scnt, int* sdispl, char* r, @@ -433,55 +429,55 @@ extern void nrnmpi_char_alltoallv(char* s, /* following are for the partrans */ -void nrnmpi_int_allgather(int* s, int* r, int n) { +void nrnmpi_int_allgather_impl(int* s, int* r, int n) { MPI_Allgather(s, n, MPI_INT, r, n, MPI_INT, nrnmpi_comm); } -void nrnmpi_int_allgather_inplace(int* srcdest, int n) { +void nrnmpi_int_allgather_inplace_impl(int* srcdest, int n) { MPI_Allgather(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, srcdest, n, MPI_INT, nrnmpi_comm); } -void nrnmpi_int_allgatherv(int* s, int* r, int* n, int* dspl) { +void nrnmpi_int_allgatherv_impl(int* s, int* r, int* n, int* dspl) { MPI_Allgatherv(s, n[nrnmpi_myid], MPI_INT, r, n, dspl, MPI_INT, nrnmpi_comm); } -void nrnmpi_int_allgatherv_inplace(int* srcdest, int* n, int* dspl) { +void nrnmpi_int_allgatherv_inplace_impl(int* srcdest, int* n, int* dspl) { MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, srcdest, n, dspl, MPI_INT, nrnmpi_comm); } -void nrnmpi_char_allgatherv(char* s, char* r, int* n, int* dspl) { +void nrnmpi_char_allgatherv_impl(char* s, char* r, int* n, int* dspl) { MPI_Allgatherv(s, n[nrnmpi_myid], MPI_CHAR, r, n, dspl, MPI_CHAR, nrnmpi_comm); } -void nrnmpi_long_allgatherv(int64_t* s, int64_t* r, int* n, int* dspl) { +void nrnmpi_long_allgatherv_impl(int64_t* s, int64_t* r, int* n, int* dspl) { MPI_Allgatherv(s, n[nrnmpi_myid], MPI_INT64_T, r, n, dspl, MPI_INT64_T, nrnmpi_comm); } -void nrnmpi_long_allgatherv_inplace(long* srcdest, int* n, int* dspl) { +void nrnmpi_long_allgatherv_inplace_impl(long* srcdest, int* n, int* dspl) { MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, srcdest, n, dspl, MPI_LONG, nrnmpi_comm); } -void nrnmpi_dbl_allgatherv(double* s, double* r, int* n, int* dspl) { +void nrnmpi_dbl_allgatherv_impl(double* s, double* r, int* n, int* dspl) { MPI_Allgatherv(s, n[nrnmpi_myid], MPI_DOUBLE, r, n, dspl, MPI_DOUBLE, nrnmpi_comm); } -void nrnmpi_dbl_allgatherv_inplace(double* srcdest, int* n, int* dspl) { +void nrnmpi_dbl_allgatherv_inplace_impl(double* srcdest, int* n, int* dspl) { MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, srcdest, n, dspl, MPI_DOUBLE, nrnmpi_comm); } -void nrnmpi_dbl_broadcast(double* buf, int cnt, int root) { +void nrnmpi_dbl_broadcast_impl(double* buf, int cnt, int root) { MPI_Bcast(buf, cnt, MPI_DOUBLE, root, nrnmpi_comm); } -void nrnmpi_int_broadcast(int* buf, int cnt, int root) { +void nrnmpi_int_broadcast_impl(int* buf, int cnt, int root) { MPI_Bcast(buf, cnt, MPI_INT, root, nrnmpi_comm); } -void nrnmpi_char_broadcast(char* buf, int cnt, int root) { +void nrnmpi_char_broadcast_impl(char* buf, int cnt, int root) { MPI_Bcast(buf, cnt, MPI_CHAR, root, nrnmpi_comm); } -void nrnmpi_str_broadcast_world(std::string& str, int root) { +void nrnmpi_str_broadcast_world_impl(std::string& str, int root) { assert(str.size() <= std::numeric_limits::max()); // broadcast the size from `root` to everyone int sz = str.size(); @@ -493,13 +489,13 @@ void nrnmpi_str_broadcast_world(std::string& str, int root) { } } -int nrnmpi_int_sum_reduce(int in) { +int nrnmpi_int_sum_reduce_impl(int in) { int result; MPI_Allreduce(&in, &result, 1, MPI_INT, MPI_SUM, nrnmpi_comm); return result; } -void nrnmpi_assert_opstep(int opstep, double t) { +void nrnmpi_assert_opstep_impl(int opstep, double t) { /* all machines in comm should have same opstep and same t. */ double buf[2]; if (nrnmpi_numprocs < 2) { @@ -515,7 +511,7 @@ void nrnmpi_assert_opstep(int opstep, double t) { } } -double nrnmpi_dbl_allmin(double x) { +double nrnmpi_dbl_allmin_impl(double x) { double result; if (nrnmpi_numprocs < 2) { return x; @@ -557,7 +553,7 @@ static void pgvts_op(double* in, double* inout, int* len, MPI_Datatype* dptr) { } } -int nrnmpi_pgvts_least(double* t, int* op, int* init) { +int nrnmpi_pgvts_least_impl(double* t, int* op, int* init) { int i; double ibuf[4], obuf[4]; ibuf[0] = *t; @@ -588,32 +584,32 @@ int nrnmpi_pgvts_least(double* t, int* op, int* init) { } /* following for splitcell.cpp transfer */ -void nrnmpi_send_doubles(double* pd, int cnt, int dest, int tag) { +void nrnmpi_send_doubles_impl(double* pd, int cnt, int dest, int tag) { MPI_Send(pd, cnt, MPI_DOUBLE, dest, tag, nrnmpi_comm); } -void nrnmpi_recv_doubles(double* pd, int cnt, int src, int tag) { +void nrnmpi_recv_doubles_impl(double* pd, int cnt, int src, int tag) { MPI_Status status; MPI_Recv(pd, cnt, MPI_DOUBLE, src, tag, nrnmpi_comm, &status); } -void nrnmpi_postrecv_doubles(double* pd, int cnt, int src, int tag, void** request) { +void nrnmpi_postrecv_doubles_impl(double* pd, int cnt, int src, int tag, void** request) { MPI_Irecv(pd, cnt, MPI_DOUBLE, src, tag, nrnmpi_comm, (MPI_Request*) request); } -void nrnmpi_wait(void** request) { +void nrnmpi_wait_impl(void** request) { MPI_Status status; MPI_Wait((MPI_Request*) request, &status); } -void nrnmpi_barrier() { +void nrnmpi_barrier_impl() { if (nrnmpi_numprocs < 2) { return; } MPI_Barrier(nrnmpi_comm); } -double nrnmpi_dbl_allreduce(double x, int type) { +double nrnmpi_dbl_allreduce_impl(double x, int type) { double result; MPI_Op t; if (nrnmpi_numprocs < 2) { @@ -630,7 +626,7 @@ double nrnmpi_dbl_allreduce(double x, int type) { return result; } -extern "C" void nrnmpi_dbl_allreduce_vec(double* src, double* dest, int cnt, int type) { +extern "C" void nrnmpi_dbl_allreduce_vec_impl(double* src, double* dest, int cnt, int type) { int i; MPI_Op t; assert(src != dest); @@ -651,7 +647,7 @@ extern "C" void nrnmpi_dbl_allreduce_vec(double* src, double* dest, int cnt, int return; } -void nrnmpi_longdbl_allreduce_vec(longdbl* src, longdbl* dest, int cnt, int type) { +void nrnmpi_longdbl_allreduce_vec_impl(long double* src, long double* dest, int cnt, int type) { int i; MPI_Op t; assert(src != dest); @@ -672,7 +668,7 @@ void nrnmpi_longdbl_allreduce_vec(longdbl* src, longdbl* dest, int cnt, int type return; } -void nrnmpi_long_allreduce_vec(long* src, long* dest, int cnt, int type) { +void nrnmpi_long_allreduce_vec_impl(long* src, long* dest, int cnt, int type) { int i; MPI_Op t; assert(src != dest); @@ -693,19 +689,19 @@ void nrnmpi_long_allreduce_vec(long* src, long* dest, int cnt, int type) { return; } -void nrnmpi_dbl_allgather(double* s, double* r, int n) { +void nrnmpi_dbl_allgather_impl(double* s, double* r, int n) { MPI_Allgather(s, n, MPI_DOUBLE, r, n, MPI_DOUBLE, nrnmpi_comm); } static MPI_Comm bgp_comm; -void nrnmpi_multisend_comm() { +void nrnmpi_multisend_comm_impl() { if (!bgp_comm) { MPI_Comm_dup(nrnmpi_comm, &bgp_comm); } } -void nrnmpi_multisend_multisend(NRNMPI_Spike* spk, int n, int* hosts) { +void nrnmpi_multisend_multisend_impl(NRNMPI_Spike* spk, int n, int* hosts) { int i; MPI_Request r; MPI_Status status; @@ -715,7 +711,7 @@ void nrnmpi_multisend_multisend(NRNMPI_Spike* spk, int n, int* hosts) { } } -int nrnmpi_multisend_single_advance(NRNMPI_Spike* spk) { +int nrnmpi_multisend_single_advance_impl(NRNMPI_Spike* spk) { int flag = 0; MPI_Status status; MPI_Iprobe(MPI_ANY_SOURCE, 1, bgp_comm, &flag, &status); @@ -726,7 +722,7 @@ int nrnmpi_multisend_single_advance(NRNMPI_Spike* spk) { } static int iii; -int nrnmpi_multisend_conserve(int nsend, int nrecv) { +int nrnmpi_multisend_conserve_impl(int nsend, int nrecv) { int tcnts[2]; tcnts[0] = nsend - nrecv; MPI_Allreduce(tcnts, tcnts + 1, 1, MPI_INT, MPI_SUM, bgp_comm); diff --git a/src/nrnmpi/lib/mpispike.h b/src/nrnmpi/lib/mpispike.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/nrnmpi/nrnmpi.cpp b/src/nrnmpi/lib/nrnmpi.cpp similarity index 94% rename from src/nrnmpi/nrnmpi.cpp rename to src/nrnmpi/lib/nrnmpi.cpp index 5cce25fd6e..adaf2a1066 100644 --- a/src/nrnmpi/nrnmpi.cpp +++ b/src/nrnmpi/lib/nrnmpi.cpp @@ -7,12 +7,9 @@ /* do not want the redef in the dynamic load case */ #include -#if NRNMPI_DYNAMICLOAD -#include /* define all the nrnmpi functions name to f_name */ -#endif -#include -#include +#include "nrnmpi.h" +#include "mpispike.h" #if NRNMPI_DYNAMICLOAD @@ -42,18 +39,13 @@ MPI_Comm nrn_bbs_comm; static MPI_Group grp_bbs; static MPI_Group grp_net; -extern void nrnmpi_spike_initialize(); - #define nrnmpidebugleak 0 -#if nrnmpidebugleak -extern void nrnmpi_checkbufleak(); -#endif static int nrnmpi_under_nrncontrol_; static int nrnmpi_is_setup_; #endif -extern "C" void nrnmpi_init(int nrnmpi_under_nrncontrol, int* pargc, char*** pargv) { +extern "C" void nrnmpi_init_impl(int nrnmpi_under_nrncontrol, int* pargc, char*** pargv) { #if NRNMPI int i, b, flag; if (nrnmpi_use) { @@ -173,7 +165,7 @@ for (i=0; i < *pargc; ++i) { #endif /* NRNMPI */ } -double nrnmpi_wtime() { +double nrnmpi_wtime_impl() { #if NRNMPI if (nrnmpi_use) { return MPI_Wtime(); @@ -182,7 +174,7 @@ double nrnmpi_wtime() { return nrn_timeus(); } -void nrnmpi_terminate() { +void nrnmpi_terminate_impl() { #if NRNMPI if (nrnmpi_use) { #if 0 @@ -207,7 +199,7 @@ void nrnmpi_terminate() { #endif /*NRNMPI*/ } -void nrnmpi_abort(int errcode) { +void nrnmpi_abort_impl(int errcode) { #if NRNMPI int flag; MPI_Initialized(&flag); @@ -224,7 +216,7 @@ void nrnmpi_abort(int errcode) { #if NRNMPI -void nrnmpi_subworld_size(int n) { +void nrnmpi_subworld_size_impl(int n) { /* n is the (desired) size of a subworld (pc.nhost) */ /* A subworld (net) is contiguous */ /* In case pc.nhost_world/n is not an integer, there are @@ -326,7 +318,7 @@ void nrnmpi_subworld_size(int n) { } /* so src/nrnpython/inithoc.cpp does not have to include a c++ mpi.h */ -int nrnmpi_wrap_mpi_init(int* flag) { +int nrnmpi_wrap_mpi_init_impl(int* flag) { return MPI_Initialized(flag); } diff --git a/src/nrnmpi/nrnmpi_impl.h b/src/nrnmpi/lib/nrnmpi.hpp similarity index 100% rename from src/nrnmpi/nrnmpi_impl.h rename to src/nrnmpi/lib/nrnmpi.hpp diff --git a/src/nrnmpi/mkdynam.sh b/src/nrnmpi/mkdynam.sh deleted file mode 100644 index 78a1707ab8..0000000000 --- a/src/nrnmpi/mkdynam.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash - -names=`sed -n ' -/extern /s/extern [a-z*]* \(nrnmpi_[a-zA-Z0-9_]*\)(.*);/\1/p -' nrnmpidec.h` - -#generate nrnmpi_dynam_wrappers.inc -sed -n ' -/extern void/s/extern \(void\) \(nrnmpi_[a-zA-Z0-9_]*\)\(.*\);/\1 \2\3 {@ (*p_\2)\3;@}/p -/extern [^v]/s/extern \([a-z*]*\) \(nrnmpi_[a-zA-Z0-9_]*\)\(.*\);/\1 \2\3 {@ return (*p_\2)\3;@}/p -' nrnmpidec.h | tr '@' '\n' | sed ' -/p_nrnmpi/ { -s/, [a-zA-Z0-9_*]* /, /g -s/)([a-zA-Z_0-9*]* /)(/ -s/char\* //g -s/std::string& //g -} -'> nrnmpi_dynam_wrappers.inc - -#generate nrnmpi_dynam.h -( -echo ' -#ifndef nrnmpi_dynam_h -#define nrnmpi_dynam_h -/* generated by mkdynam.sh */ - -#if NRNMPI_DYNAMICLOAD -' -for i in $names ; do - echo "#define $i f_$i" -done - -echo ' -#endif /* NRNMPI_DYNAMICLOAD */ - -#endif -' -) > nrnmpi_dynam.h - -#generate nrnmpi_dynam_cinc -( - -sed -n ' -/extern/s/extern \([a-z*]*\) \(nrnmpi_[a-zA-Z0-9_]*\)\(.*\);/static \1 (*p_\2)\3;/p -' nrnmpidec.h -echo ' -static struct { - const char* name; - void** ppf; -} ftable[] = {' -for i in $names ; do - echo " \"f_$i\", (void**)&p_$i," -done -echo ' 0,0 -}; -' -) > nrnmpi_dynam_cinc - diff --git a/src/nrnmpi/mpispike.h b/src/nrnmpi/mpispike.h deleted file mode 100644 index b96263cf4a..0000000000 --- a/src/nrnmpi/mpispike.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef nrnmpispike_h -#define nrnmpispike_h - -#ifndef nrn_spikebuf_size -#define nrn_spikebuf_size 0 -#endif - -#if nrn_spikebuf_size > 0 -typedef struct { - int nspike; - int gid[nrn_spikebuf_size]; - double spiketime[nrn_spikebuf_size]; -} NRNMPI_Spikebuf; -#endif - - -#define icapacity_ nrnmpi_i_capacity_ -#define spikeout_ nrnmpi_spikeout_ -#define spikein_ nrnmpi_spikein_ -#define nout_ nrnmpi_nout_ -#define nin_ nrnmpi_nin_ -extern int nout_; -extern int* nin_; -extern int icapacity_; -extern NRNMPI_Spike* spikeout_; -extern NRNMPI_Spike* spikein_; - -#define spfixout_ nrnmpi_spikeout_fixed_ -#define spfixin_ nrnmpi_spikein_fixed_ -#define spfixin_ovfl_ nrnmpi_spikein_fixed_ovfl_ -#define localgid_size_ nrnmpi_localgid_size_ -#define ag_send_size_ nrnmpi_ag_send_size_ -#define ag_send_nspike_ nrnmpi_send_nspike_ -#define ovfl_capacity_ nrnmpi_ovfl_capacity_ -#define ovfl_ nrnmpi_ovfl_ -extern int localgid_size_; /* bytes */ -extern int ag_send_size_; /* bytes */ -extern int ag_send_nspike_; /* spikes */ -extern int ovfl_capacity_; /* spikes */ -extern int ovfl_; /* spikes */ -extern unsigned char* spfixout_; -extern unsigned char* spfixin_; -extern unsigned char* spfixin_ovfl_; - -#if nrn_spikebuf_size > 0 -#define spbufout_ nrnmpi_spbufout_ -#define spbufin_ nrnmpi_spbufin_ -extern NRNMPI_Spikebuf* spbufout_; -extern NRNMPI_Spikebuf* spbufin_; -#endif - - -#endif diff --git a/src/nrnmpi/notes_nrnrt b/src/nrnmpi/notes_nrnrt deleted file mode 100644 index cdbc4dbd0f..0000000000 --- a/src/nrnmpi/notes_nrnrt +++ /dev/null @@ -1,62 +0,0 @@ -Building linux with rtai -see http://www.fdn.fr/~brouchou/rtai/rtai-doc-prj/installation-guide.html -also extremely helpful, especially for the initial transformation of -neuron was: http://people.mech.kuleuven.be/~psoetens/portingtolxrt.html - -using -rtai-3.2 -linux-2.6.10 -patched with rtai-3.2/base/arch/i386/patches/hal-linux-2.6.10-i386-r9.patch - -cp /boot/config-2.6.12-1.1372_FC3 .config -make oldconfig #accept default for everything -make gconfig -General setup - LOCALVERSION -adeos -Loadable module support - Enable loadable module support - ` MODVERSIONS N -Power management options - Power Management support PM (I left it on but ...) -Processor type and features - REGPARM N (Y prevents testsuites/user tests from working) - -make -su -make modules_install -make install - -I've been uninstalling my failures by removing /boot/*2.6.10* -/lib/modules/2.6.10* -and editing /boot/grub/grub.conf - -I'm not quite sure, but after the linux config is built and even before -building, installing, and rebooting, I think it might be a good idea -to configure rtai-3.2 -I created $HOME/rtlinux/rtaibuild and did -make -f ../rtai-3.2/makefile srctree=../rtai-3.2 gconfig -General - Installation directory /home/hines/rtlinux/realtime - Linux source tree /home/hines/rtlinux/linux-2.6.10 - Machine - Number of CPUs 1 (my guess, I am not sure) - IPC support - I turned on Yes for Semaphores, Message, and Mailboxes. - I'm not sure if that was necessary, but I do not know what - M (Maybe?) means -at any rate, after that, configure succeeded. - -Also it is not clear to me that it is necessary to reboot linux before -building rtai but I generally have rebooted first and then in rtaibuild -make -su -make install - -moved the realtime/lib files out of the way except for liblxrt.a to avoid -some link warnings. - -One then tests with - -copy a tests .runinfo and run to a test directory and modify the -.runinfo to read -latency:lxrt+sem+mbx+msg:/home/hines/neuron/nrnrt/i686/bin/nrngui -realtime hhap.hoc diff --git a/src/nrnmpi/nrnmpi.h b/src/nrnmpi/nrnmpi.h new file mode 100644 index 0000000000..9b74fcf2c6 --- /dev/null +++ b/src/nrnmpi/nrnmpi.h @@ -0,0 +1,71 @@ +/* +# ============================================================================= +# Copyright (c) 2016 - 2021 Blue Brain Project/EPFL +# +# See top-level LICENSE file for details. +# =============================================================================. +*/ + +#pragma once + +#include +#include +#include +#include + +#ifndef nrn_spikebuf_size +#define nrn_spikebuf_size 0 +#endif + +// Those functions and classes are part of a mechanism to dynamically or statically load mpi +// functions +struct mpi_function_base; + +struct mpi_manager_t { + void register_function(mpi_function_base* ptr) { + m_function_ptrs.push_back(ptr); + } + void resolve_symbols(void* dlsym_handle); + + private: + std::vector m_function_ptrs; + // true when symbols are resolved +}; + +inline mpi_manager_t& mpi_manager() { + static mpi_manager_t x; + return x; +} + +struct mpi_function_base { + void resolve(void* dlsym_handle); + operator bool() const { + return m_fptr; + } + mpi_function_base(const char* name) + : m_name{name} { + mpi_manager().register_function(this); + } + + protected: + void* m_fptr{}; + const char* m_name; +}; + +template +struct mpi_function: mpi_function_base { + using mpi_function_base::mpi_function_base; + template // in principle deducible from `function_ptr` + auto operator()(Args&&... args) const { +#ifdef NRNMPI_DYNAMICLOAD + // Dynamic MPI, m_fptr should have been initialised via dlsym. + assert(m_fptr); + return (*reinterpret_cast(m_fptr))(std::forward(args)...); +#else + // No dynamic MPI, use `fptr` directly. Will produce link errors if libmpi.so is not linked. + return (*fptr)(std::forward(args)...); +#endif + } +}; + +#include "nrnmpidec.h" diff --git a/src/nrnmpi/nrnmpi_def_cinc b/src/nrnmpi/nrnmpi_def_cinc deleted file mode 100644 index d470eb34fb..0000000000 --- a/src/nrnmpi/nrnmpi_def_cinc +++ /dev/null @@ -1,27 +0,0 @@ -int nrnmpi_use; -int nrnmpi_numprocs = 1; /* size */ -int nrnmpi_myid = 0; /* rank */ -int nrnmpi_numprocs_world = 1; -int nrnmpi_myid_world = 0; -int nrnmpi_numprocs_bbs = 1; -int nrnmpi_myid_bbs = 0; -// increment from within void nrnmpi_subworld_size(int n) -int nrnmpi_subworld_change_cnt = 0; -int nrnmpi_subworld_id = -1; -int nrnmpi_numprocs_subworld = 1; - -int nrnmpi_nout_; -int* nrnmpi_nin_; -int nrnmpi_i_capacity_; -NRNMPI_Spike* nrnmpi_spikeout_; -NRNMPI_Spike* nrnmpi_spikein_; - -int nrnmpi_localgid_size_; -int nrnmpi_ag_send_size_; -int nrnmpi_send_nspike_; -int nrnmpi_ovfl_capacity_; -int nrnmpi_ovfl_; -unsigned char* nrnmpi_spikeout_fixed_; -unsigned char* nrnmpi_spikein_fixed_; -unsigned char* nrnmpi_spikein_fixed_ovfl_; -int nrn_cannot_use_threads_and_mpi; diff --git a/src/nrnmpi/nrnmpi_dynam.cpp b/src/nrnmpi/nrnmpi_dynam.cpp deleted file mode 100644 index 07bf763cc0..0000000000 --- a/src/nrnmpi/nrnmpi_dynam.cpp +++ /dev/null @@ -1,259 +0,0 @@ -#include <../../nrnconf.h> -#include "nrnmpiuse.h" -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if NRNMPI_DYNAMICLOAD /* to end of file */ - -#include "nrnwrap_dlfcn.h" - -#include "nrnmpi.h" - -extern char* cxx_char_alloc(size_t); -extern std::string corenrn_mpi_library; - -#if DARWIN -extern void nrn_possible_mismatched_arch(const char*); -#endif - -#if DARWIN || defined(__linux__) -extern const char* path_prefix_to_libnrniv(); -#endif - -#include -#include // for nrnmpi_str_broadcast_world - -#include "mpispike.h" -#include "nrnmpi_def_cinc" /* nrnmpi global variables */ -extern "C" { -#include "nrnmpi_dynam_cinc" /* autogenerated file */ -} -#include "nrnmpi_dynam_wrappers.inc" /* autogenerated file */ -#include "nrnmpi_dynam_stubs.cpp" - -static void* load_mpi(const char* name, std::string& mes) { - void* handle = dlopen(name, RTLD_NOW | RTLD_GLOBAL); - mes.append(name); - mes.append(": "); - if (!handle) { -#if DARWIN - nrn_possible_mismatched_arch(name); -#endif - mes.append(dlerror()); - } else { - mes.append("successful"); - } - mes.append(1, '\n'); - return handle; -} - -static void* load_nrnmpi(const char* name, std::string& mes) { - void* handle = dlopen(name, RTLD_NOW | RTLD_GLOBAL); - mes.append("load_nrnmpi: "); - if (!handle) { - mes.append(dlerror()); - mes.append("\n"); - return nullptr; - } - mes.append(name); - mes.append("successful\n"); - for (int i = 0; ftable[i].name; ++i) { - void* p = dlsym(handle, ftable[i].name); - if (!p) { - mes.append("load_nrnmpi: "); - mes.append(ftable[i].name); - mes.append(1, ' '); - mes.append(dlerror()); - mes.append(1, '\n'); - dlclose(handle); - return nullptr; - } - *ftable[i].ppf = p; - } - { - auto* const p = reinterpret_cast( - dlsym(handle, "p_cxx_char_alloc")); - if (!p) { - mes.append("load_nrnmpi: p_cxx_char_alloc "); - mes.append(dlerror()); - mes.append("\n"); - dlclose(handle); - return nullptr; - } - *p = cxx_char_alloc; - } - return handle; -} - -std::string nrnmpi_load(int is_python) { - std::string pmes; - void* handle = nullptr; - // If libmpi already in memory, find name and dlopen that. - void* sym = dlsym(RTLD_DEFAULT, "MPI_Initialized"); - if (sym) { - Dl_info info; - if (dladdr(sym, &info)) { - if (info.dli_fname[0] == '/' || strchr(info.dli_fname, ':')) { - pmes = " is loaded in the sense the MPI_Initialized has an address\n"; - handle = load_mpi(info.dli_fname, pmes); - if (handle) { - // Normally corenrn_mpi_library points to an - // libcorenrnmpi_X.{so, ...} file, why do we want it to - // point to libmpi.{so, ...} in this case? - corenrn_mpi_library = info.dli_fname; - } - } - } - } - - if (!handle) { - // Otherwise, try to "dlopen(libmpi)", trying a few different search paths - // that are slightly different for different platforms. MPI_LIB_NRN_PATH may - // be set explicitly by the user, or by NEURON's Python code via - // ctypes.find_library(). - using const_char_ptr = const char*; - std::array libmpi_names { -#if defined(DARWIN) - "libmpi.dylib", const_char_ptr{std::getenv("MPI_LIB_NRN_PATH")}, -#elif defined(MINGW) - "msmpi.dll" -#else // Linux - // libmpi.so is not standard but used by most of the implemenntation - // (mpich, openmpi, intel-mpi, parastation-mpi, hpe-mpt) but not - // cray-mpich. we first load libmpi and then libmpich.so as a fallaback - // for cray systems. - "libmpi.so", const_char_ptr{std::getenv("MPI_LIB_NRN_PATH")}, "libmpich.so" -#endif - }; - - // Look for the MPI implementation in this search path - pmes = "Tried loading an MPI library from:\n"; - for (auto const* mpi_path: libmpi_names) { - if (!mpi_path) { - // MPI_LIB_NRN_PATH might not be set - continue; - } - handle = load_mpi(mpi_path, pmes); - if (handle) { - // Success - break; - } - } - } - - if (!handle) { - // Failed to find an MPI implementation - pmes.append( - "Is an MPI library such as openmpi, mpich, intel-mpi or sgi-mpt installed? If yes, it " - "may be installed in a non-standard location that you can add to LD_LIBRARY_PATH (or " - "DYLD_LIBRARY_PATH on macOS), or on Linux or macOS you can provide a full path in " - "MPI_LIB_NRN_PATH\n"); - return pmes; - } - -#if !defined(DARWIN) && !defined(MINGW) - // Linux-specific hack; with CMake the problem of Python launch on Linux not - // resolving variables from already loaded shared libraries has returned. - { - std::string error{"Promoted none of"}; - auto const promote_to_global = [&error](const char* lib) { - if (!dlopen(lib, RTLD_NOW | RTLD_NOLOAD | RTLD_GLOBAL)) { - char const* dlerr = dlerror(); - error = error + ' ' + lib + " (" + (dlerr ? dlerr : "nullptr") + ')'; - return false; - } - return true; - }; - if (!promote_to_global("libnrniv.so") && !promote_to_global("libnrniv-without-nvidia.so")) { - std::cerr << error << " to RTLD_GLOBAL" << std::endl; - } - } -#endif - - // Found the MPI implementation, `handle` refers to it . Now deduce which - // MPI implementation that actually is - assert(handle); - auto const mpi_implementation = [handle] { -#ifdef MINGW - return "msmpi"; -#else - if (dlsym(handle, "ompi_mpi_init")) { - // OpenMPI - return "ompi"; - } else if (dlsym(handle, "MPI_SGI_vtune_is_running")) { - // Got sgi-mpt. MPI_SGI_init exists in both mpt and hmpt, so we look - // for MPI_SGI_vtune_is_running which only exists in the non-hmpt - // version. - return "mpt"; - } else { - // Assume mpich. Could check for MPID_nem_mpich_init... - return "mpich"; - } -#endif - }(); - - // Figure out where to find lib[core]nrnmpi{...} libraries. Older versions - // of this code used @loader_path on macOS, which caused problems in now that the code that - // calls dlopen(libcorenrnmpi_...) is in libcorenrnmech.so (in some - // model-specific directory) rather than the CoreNEURON installation - // directory where libcorenrnmpi_*.so live. Now libcorenrnmpi_*.so will be - // looked for in the same directory as libnrniv.so, which will be incorrect - // if CoreNEURON is built externally with dynamic MPI enabled. - auto const libnrnmpi_prefix = []() -> std::string { -#ifdef MINGW - // Preserve old behaviour on Windows - return {}; -#else - if (const char* nrn_home = std::getenv("NRNHOME")) { - // TODO: what about windows path separators? - return std::string{nrn_home} + "/lib/"; - } else { - // Use the directory libnrniv.so is in - return path_prefix_to_libnrniv(); - } -#endif - }(); - - - auto const mpi_path = [&](std::string_view middle) { - std::string name{libnrnmpi_prefix}; - name.append(neuron::config::shared_library_prefix); - name.append(middle); - name.append(mpi_implementation); - name.append(neuron::config::shared_library_suffix); - return name; - }; - auto const nrn_mpi_library = mpi_path("nrnmpi_"); - // TODO this will be wrong if CoreNEURON is installed externally - corenrn_mpi_library = mpi_path("corenrnmpi_"); - - if (!load_nrnmpi(nrn_mpi_library.c_str(), pmes)) { - return pmes; - } - - // No error, return an empty string. We have called dlopen(...) on the - // libnrnmpi_* shared library and potentially on "libmpi" without - // corresponding calls to dlclose(). - return {}; -} - -// nrnmpi_load cannot safely be called from nrnmpi.cpp because of pre/post-C++11 -// ABI compatibility issues with std::string. See -// https://github.com/neuronsimulator/nrn/issues/1963 for more information. -void nrnmpi_load_or_exit(bool is_python) { - auto const err = nrnmpi_load(is_python); - if (!err.empty()) { - std::cout << err << std::endl; - std::exit(1); - } -} - -#endif diff --git a/src/nrnmpi/nrnmpi_dynam_stubs.cpp b/src/nrnmpi/nrnmpi_dynam_stubs.cpp deleted file mode 100644 index 1e7b9209b7..0000000000 --- a/src/nrnmpi/nrnmpi_dynam_stubs.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* a few calls to nrnmpi functions are made even when MPI not available */ -/* these need enough implementation to work with nrnmpi_numprocs = 1 */ - -#include "nrnmpiuse.h" -#if NRNMPI_DYNAMICLOAD /* to end of file */ - -#include -#include "nrnmpidec.h" - -extern double nrn_timeus(); - -static void stub_nrnmpi_init(int nrnmpi_under_nrncontrol, int* pargc, char*** pargv) {} -static void stub_nrnmpi_terminate() {} -static double stub_nrnmpi_mindelay(double m) { - return m; -} -static int stub_nrnmpi_int_allmax(int x) { - return x; -} -static void stub_nrnmpi_barrier() {} - -void nrnmpi_stubs() { - p_nrnmpi_init = stub_nrnmpi_init; - p_nrnmpi_terminate = stub_nrnmpi_terminate; - p_nrnmpi_wtime = nrn_timeus; - p_nrnmpi_mindelay = stub_nrnmpi_mindelay; - p_nrnmpi_int_allmax = stub_nrnmpi_int_allmax; - p_nrnmpi_barrier = stub_nrnmpi_barrier; -} - -#endif diff --git a/src/nrnmpi/nrnmpidec.h b/src/nrnmpi/nrnmpidec.h index 11e182cfab..bcc03e53e7 100644 --- a/src/nrnmpi/nrnmpidec.h +++ b/src/nrnmpi/nrnmpidec.h @@ -1,124 +1,179 @@ -/* -This file is processed by mkdynam.sh and so it is important that -the prototypes be of the form "type foo(type arg, ...)" -*/ +#pragma once -#ifndef nrnmpidec_h -#define nrnmpidec_h -#include -#include -typedef long double longdbl; -#if NRNMPI -#include -#include - -/* from bbsmpipack.cpp */ -typedef struct bbsmpibuf { +#include "./nrnmpi.h" +// bbsmpipack.cpp +struct bbsmpibuf { char* buf; int size; int pkposition; int upkpos; int keypos; int refcount; -} bbsmpibuf; - -// olupton 2022-07-06: dynamic MPI needs to dlopen some of these (slightly -// redefined) symbol names, so keep C linkage for simplicity -extern "C" { -// clang-format off -extern bbsmpibuf* nrnmpi_newbuf(int size); -extern void nrnmpi_copy(bbsmpibuf* dest, bbsmpibuf* src); -extern void nrnmpi_ref(bbsmpibuf* buf); -extern void nrnmpi_unref(bbsmpibuf* buf); - -extern void nrnmpi_upkbegin(bbsmpibuf* buf); -extern char* nrnmpi_getkey(bbsmpibuf* buf); -extern int nrnmpi_getid(bbsmpibuf* buf); -extern int nrnmpi_upkint(bbsmpibuf* buf); -extern double nrnmpi_upkdouble(bbsmpibuf* buf); -extern void nrnmpi_upkvec(int n, double* x, bbsmpibuf* buf); -extern char* nrnmpi_upkstr(bbsmpibuf* buf); -extern char* nrnmpi_upkpickle(size_t* size, bbsmpibuf* buf); - -extern void nrnmpi_pkbegin(bbsmpibuf* buf); -extern void nrnmpi_enddata(bbsmpibuf* buf); -extern void nrnmpi_pkint(int i, bbsmpibuf* buf); -extern void nrnmpi_pkdouble(double x, bbsmpibuf* buf); -extern void nrnmpi_pkvec(int n, double* x, bbsmpibuf* buf); -extern void nrnmpi_pkstr(const char* s, bbsmpibuf* buf); -extern void nrnmpi_pkpickle(const char* s, size_t size, bbsmpibuf* buf); - -extern int nrnmpi_iprobe(int* size, int* tag, int* source); -extern void nrnmpi_probe(int* size, int* tag, int* source); -extern void nrnmpi_bbssend(int dest, int tag, bbsmpibuf* r); -extern int nrnmpi_bbsrecv(int source, bbsmpibuf* r); -extern int nrnmpi_bbssendrecv(int dest, int tag, bbsmpibuf* s, bbsmpibuf* r); - -/* from nrnmpi.cpp */ -extern void nrnmpi_init(int nrnmpi_under_nrncontrol, int* pargc, char*** pargv); -extern int nrnmpi_wrap_mpi_init(int* flag); -extern double nrnmpi_wtime(); -extern void nrnmpi_terminate(); -extern void nrnmpi_abort(int errcode); -extern void nrnmpi_subworld_size(int n); - - -/* from mpispike.cpp */ -extern void nrnmpi_spike_initialize(); -extern int nrnmpi_spike_exchange(); -extern int nrnmpi_spike_exchange_compressed(); -extern double nrnmpi_mindelay(double maxdel); -extern int nrnmpi_int_allmax(int i); -extern void nrnmpi_int_gather(int* s, int* r, int cnt, int root); -extern void nrnmpi_int_gatherv(int* s, int scnt, int* r, int* rcnt, int* rdispl, int root); -extern void nrnmpi_char_gatherv(char* s, int scnt, char* r, int* rcnt, int* rdispl, int root); -extern void nrnmpi_int_scatter(int* s, int* r, int cnt, int root); -extern void nrnmpi_char_scatterv(char* s, int* scnt, int* sdispl, char* r, int rcnt, int root); -extern void nrnmpi_int_allgather(int* s, int* r, int n); -extern void nrnmpi_int_allgather_inplace(int* srcdest, int n); -extern void nrnmpi_int_allgatherv_inplace(int* srcdest, int* n, int* dspl); -extern void nrnmpi_int_allgatherv(int* s, int* r, int* n, int* dspl); -extern void nrnmpi_char_allgatherv(char* s, char* r, int* n, int* dspl); -extern void nrnmpi_int_alltoall(int* s, int* r, int n); -extern void nrnmpi_int_alltoallv(int* s, int* scnt, int* sdispl, int* r, int* rcnt, int* rdispl); -extern void nrnmpi_int_alltoallv_sparse(int* s, int* scnt, int* sdispl, int* r, int* rcnt, int* rdispl); -extern void nrnmpi_long_allgatherv(int64_t* s, int64_t* r, int* n, int* dspl); -extern void nrnmpi_long_allgatherv_inplace(long* srcdest, int* n, int* dspl); -extern void nrnmpi_long_alltoallv(int64_t* s, int* scnt, int* sdispl, int64_t* r, int* rcnt, int* rdispl); -extern void nrnmpi_long_alltoallv_sparse(int64_t* s, int* scnt, int* sdispl, int64_t* r, int* rcnt, int* rdispl); -extern void nrnmpi_dbl_allgatherv(double* s, double* r, int* n, int* dspl); -extern void nrnmpi_dbl_allgatherv_inplace(double* srcdest, int* n, int* dspl); -extern void nrnmpi_dbl_alltoallv(double* s, int* scnt, int* sdispl, double* r, int* rcnt, int* rdispl); -extern void nrnmpi_dbl_alltoallv_sparse(double* s, int* scnt, int* sdispl, double* r, int* rcnt, int* rdispl); -extern void nrnmpi_char_alltoallv(char* s, int* scnt, int* sdispl, char* r, int* rcnt, int* rdispl); -extern void nrnmpi_dbl_broadcast(double* buf, int cnt, int root); -extern void nrnmpi_int_broadcast(int* buf, int cnt, int root); -extern void nrnmpi_char_broadcast(char* buf, int cnt, int root); -extern void nrnmpi_str_broadcast_world(std::string& str, int root); -extern int nrnmpi_int_sum_reduce(int in); -extern void nrnmpi_assert_opstep(int opstep, double t); -extern double nrnmpi_dbl_allmin(double x); -extern int nrnmpi_pgvts_least(double* t, int* op, int* init); -extern void nrnmpi_send_doubles(double* pd, int cnt, int dest, int tag); -extern void nrnmpi_recv_doubles(double* pd, int cnt, int src, int tag); -extern void nrnmpi_postrecv_doubles(double* pd, int cnt, int src, int tag, void** request); -extern void nrnmpi_wait(void** request); -extern void nrnmpi_barrier(); -extern double nrnmpi_dbl_allreduce(double x, int type); +}; -extern void nrnmpi_dbl_allreduce_vec(double* src, double* dest, int cnt, int type); -extern void nrnmpi_longdbl_allreduce_vec(longdbl* src, longdbl* dest, int cnt, int type); -extern void nrnmpi_long_allreduce_vec(long* src, long* dest, int cnt, int type); +typedef struct { + int gid; + double spiketime; +} NRNMPI_Spike; -extern void nrnmpi_dbl_allgather(double* s, double* r, int n); -#if NRNMPI -extern void nrnmpi_multisend_comm(); -extern void nrnmpi_multisend_multisend(NRNMPI_Spike* spk, int n, int* hosts); -extern int nrnmpi_multisend_single_advance(NRNMPI_Spike* spk); -extern int nrnmpi_multisend_conserve(int nsend, int nrecv); -#endif -// clang-format on -} -#endif -#endif +extern "C" bbsmpibuf* nrnmpi_newbuf_impl(int size); +extern mpi_function nrnmpi_newbuf; +extern "C" void nrnmpi_copy_impl(bbsmpibuf* dest, bbsmpibuf* src); +extern mpi_function nrnmpi_copy; +extern "C" void nrnmpi_ref_impl(bbsmpibuf* buf); +extern mpi_function nrnmpi_ref; +extern "C" void nrnmpi_unref_impl(bbsmpibuf* buf); +extern mpi_function nrnmpi_unref; +extern "C" void nrnmpi_upkbegin_impl(bbsmpibuf* buf); +extern mpi_function nrnmpi_upkbegin; +extern "C" char* nrnmpi_getkey_impl(bbsmpibuf* buf); +extern mpi_function nrnmpi_getkey; +extern "C" int nrnmpi_getid_impl(bbsmpibuf* buf); +extern mpi_function nrnmpi_getid; +extern "C" int nrnmpi_upkint_impl(bbsmpibuf* buf); +extern mpi_function nrnmpi_upkint; +extern "C" double nrnmpi_upkdouble_impl(bbsmpibuf* buf); +extern mpi_function nrnmpi_upkdouble; +extern "C" void nrnmpi_upkvec_impl(int n, double* x, bbsmpibuf* buf); +extern mpi_function nrnmpi_upkvec; +extern "C" char* nrnmpi_upkstr_impl(bbsmpibuf* buf); +extern mpi_function nrnmpi_upkstr; +extern "C" char* nrnmpi_upkpickle_impl(size_t* size, bbsmpibuf* buf); +extern mpi_function nrnmpi_upkpickle; +extern "C" void nrnmpi_pkbegin_impl(bbsmpibuf* buf); +extern mpi_function nrnmpi_pkbegin; +extern "C" void nrnmpi_enddata_impl(bbsmpibuf* buf); +extern mpi_function nrnmpi_enddata; +extern "C" void nrnmpi_pkint_impl(int i, bbsmpibuf* buf); +extern mpi_function nrnmpi_pkint; +extern "C" void nrnmpi_pkdouble_impl(double x, bbsmpibuf* buf); +extern mpi_function nrnmpi_pkdouble; +extern "C" void nrnmpi_pkvec_impl(int n, double* x, bbsmpibuf* buf); +extern mpi_function nrnmpi_pkvec; +extern "C" void nrnmpi_pkstr_impl(const char* s, bbsmpibuf* buf); +extern mpi_function nrnmpi_pkstr; +extern "C" void nrnmpi_pkpickle_impl(const char* s, size_t size, bbsmpibuf* buf); +extern mpi_function nrnmpi_pkpickle; +extern "C" int nrnmpi_iprobe_impl(int* size, int* tag, int* source); +extern mpi_function nrnmpi_iprobe; +extern "C" void nrnmpi_probe_impl(int* size, int* tag, int* source); +extern mpi_function nrnmpi_probe; +extern "C" void nrnmpi_bbssend_impl(int dest, int tag, bbsmpibuf* r); +extern mpi_function nrnmpi_bbssend; +extern "C" int nrnmpi_bbsrecv_impl(int source, bbsmpibuf* r); +extern mpi_function nrnmpi_bbsrecv; +extern "C" int nrnmpi_bbssendrecv_impl(int dest, int tag, bbsmpibuf* s, bbsmpibuf* r); +extern mpi_function nrnmpi_bbssendrecv; +// nrnmpi.cpp +extern "C" void nrnmpi_init_impl(int nrnmpi_under_nrncontrol, int* pargc, char*** pargv); +extern mpi_function nrnmpi_init; +extern "C" int nrnmpi_wrap_mpi_init_impl(int* flag); +extern mpi_function nrnmpi_wrap_mpi_init; +extern "C" double nrnmpi_wtime_impl(); +extern mpi_function nrnmpi_wtime; +extern "C" void nrnmpi_terminate_impl(); +extern mpi_function nrnmpi_terminate; +extern "C" void nrnmpi_abort_impl(int errcode); +extern mpi_function nrnmpi_abort; +extern "C" void nrnmpi_subworld_size_impl(int n); +extern mpi_function nrnmpi_subworld_size; +// mpispike.cpp +extern "C" void nrnmpi_spike_initialize_impl(); +extern mpi_function nrnmpi_spike_initialize; +extern "C" int nrnmpi_spike_exchange_impl(int* nin, int* nout, int* icapacity, NRNMPI_Spike** spikein, NRNMPI_Spike** spikeout); +extern mpi_function nrnmpi_spike_exchange; +extern "C" int nrnmpi_spike_exchange_compressed_impl(int* nin, unsigned char* spfixin_ovfl, unsigned char* spikeout_fixed, unsigned char* spikein_fixed, int ag_send_size, int ag_send_nspike, int localgid_size, int* ovfl_capacity, int* ovfl); +extern mpi_function nrnmpi_spike_exchange_compressed; +extern "C" double nrnmpi_mindelay_impl(double maxdel); +extern mpi_function nrnmpi_mindelay; +extern "C" int nrnmpi_int_allmax_impl(int i); +extern mpi_function nrnmpi_int_allmax; +extern "C" void nrnmpi_int_gather_impl(int* s, int* r, int cnt, int root); +extern mpi_function nrnmpi_int_gather; +extern "C" void nrnmpi_int_gatherv_impl(int* s, int scnt, int* r, int* rcnt, int* rdispl, int root); +extern mpi_function nrnmpi_int_gatherv; +extern "C" void nrnmpi_char_gatherv_impl(char* s, int scnt, char* r, int* rcnt, int* rdispl, int root); +extern mpi_function nrnmpi_char_gatherv; +extern "C" void nrnmpi_int_scatter_impl(int* s, int* r, int cnt, int root); +extern mpi_function nrnmpi_int_scatter; +extern "C" void nrnmpi_char_scatterv_impl(char* s, int* scnt, int* sdispl, char* r, int rcnt, int root); +extern mpi_function nrnmpi_char_scatterv; +extern "C" void nrnmpi_int_allgather_impl(int* s, int* r, int n); +extern mpi_function nrnmpi_int_allgather; +extern "C" void nrnmpi_int_allgather_inplace_impl(int* srcdest, int n); +extern mpi_function nrnmpi_int_allgather_inplace; +extern "C" void nrnmpi_int_allgatherv_inplace_impl(int* srcdest, int* n, int* dspl); +extern mpi_function nrnmpi_int_allgatherv_inplace; +extern "C" void nrnmpi_int_allgatherv_impl(int* s, int* r, int* n, int* dspl); +extern mpi_function nrnmpi_int_allgatherv; +extern "C" void nrnmpi_char_allgatherv_impl(char* s, char* r, int* n, int* dspl); +extern mpi_function nrnmpi_char_allgatherv; +extern "C" void nrnmpi_int_alltoall_impl(int* s, int* r, int n); +extern mpi_function nrnmpi_int_alltoall; +extern "C" void nrnmpi_int_alltoallv_impl(int* s, int* scnt, int* sdispl, int* r, int* rcnt, int* rdispl); +extern mpi_function nrnmpi_int_alltoallv; +extern "C" void nrnmpi_int_alltoallv_sparse_impl(int* s, int* scnt, int* sdispl, int* r, int* rcnt, int* rdispl); +extern mpi_function nrnmpi_int_alltoallv_sparse; +extern "C" void nrnmpi_long_allgatherv_impl(int64_t* s, int64_t* r, int* n, int* dspl); +extern mpi_function nrnmpi_long_allgatherv; +extern "C" void nrnmpi_long_allgatherv_inplace_impl(long* srcdest, int* n, int* dspl); +extern mpi_function nrnmpi_long_allgatherv_inplace; +extern "C" void nrnmpi_long_alltoallv_impl(int64_t* s, int* scnt, int* sdispl, int64_t* r, int* rcnt, int* rdispl); +extern mpi_function nrnmpi_long_alltoallv; +extern "C" void nrnmpi_long_alltoallv_sparse_impl(int64_t* s, int* scnt, int* sdispl, int64_t* r, int* rcnt, int* rdispl); +extern mpi_function nrnmpi_long_alltoallv_sparse; +extern "C" void nrnmpi_dbl_allgatherv_impl(double* s, double* r, int* n, int* dspl); +extern mpi_function nrnmpi_dbl_allgatherv; +extern "C" void nrnmpi_dbl_allgatherv_inplace_impl(double* srcdest, int* n, int* dspl); +extern mpi_function nrnmpi_dbl_allgatherv_inplace; +extern "C" void nrnmpi_dbl_alltoallv_impl(double* s, int* scnt, int* sdispl, double* r, int* rcnt, int* rdispl); +extern mpi_function nrnmpi_dbl_alltoallv; +extern "C" void nrnmpi_dbl_alltoallv_sparse_impl(double* s, int* scnt, int* sdispl, double* r, int* rcnt, int* rdispl); +extern mpi_function nrnmpi_dbl_alltoallv_sparse; +extern "C" void nrnmpi_char_alltoallv_impl(char* s, int* scnt, int* sdispl, char* r, int* rcnt, int* rdispl); +extern mpi_function nrnmpi_char_alltoallv; +extern "C" void nrnmpi_dbl_broadcast_impl(double* buf, int cnt, int root); +extern mpi_function nrnmpi_dbl_broadcast; +extern "C" void nrnmpi_int_broadcast_impl(int* buf, int cnt, int root); +extern mpi_function nrnmpi_int_broadcast; +extern "C" void nrnmpi_char_broadcast_impl(char* buf, int cnt, int root); +extern mpi_function nrnmpi_char_broadcast; +extern "C" void nrnmpi_str_broadcast_world_impl(std::string& str, int root); +extern mpi_function nrnmpi_str_broadcast_world; +extern "C" int nrnmpi_int_sum_reduce_impl(int in); +extern mpi_function nrnmpi_int_sum_reduce; +extern "C" void nrnmpi_assert_opstep_impl(int opstep, double t); +extern mpi_function nrnmpi_assert_opstep; +extern "C" double nrnmpi_dbl_allmin_impl(double x); +extern mpi_function nrnmpi_dbl_allmin; +extern "C" int nrnmpi_pgvts_least_impl(double* t, int* op, int* init); +extern mpi_function nrnmpi_pgvts_least; +extern "C" void nrnmpi_send_doubles_impl(double* pd, int cnt, int dest, int tag); +extern mpi_function nrnmpi_send_doubles; +extern "C" void nrnmpi_recv_doubles_impl(double* pd, int cnt, int src, int tag); +extern mpi_function nrnmpi_recv_doubles; +extern "C" void nrnmpi_postrecv_doubles_impl(double* pd, int cnt, int src, int tag, void** request); +extern mpi_function nrnmpi_postrecv_doubles; +extern "C" void nrnmpi_wait_impl(void** request); +extern mpi_function nrnmpi_wait; +extern "C" void nrnmpi_barrier_impl(); +extern mpi_function nrnmpi_barrier; +extern "C" double nrnmpi_dbl_allreduce_impl(double x, int type); +extern mpi_function nrnmpi_dbl_allreduce; +extern "C" void nrnmpi_dbl_allreduce_vec_impl(double* src, double* dest, int cnt, int type); +extern mpi_function nrnmpi_dbl_allreduce_vec; +extern "C" void nrnmpi_longdbl_allreduce_vec_impl(long double* src, long double* dest, int cnt, int type); +extern mpi_function nrnmpi_longdbl_allreduce_vec; +extern "C" void nrnmpi_long_allreduce_vec_impl(long* src, long* dest, int cnt, int type); +extern mpi_function nrnmpi_long_allreduce_vec; +extern "C" void nrnmpi_dbl_allgather_impl(double* s, double* r, int n); +extern mpi_function nrnmpi_dbl_allgather; +extern "C" void nrnmpi_multisend_comm_impl(); +extern mpi_function nrnmpi_multisend_comm; +extern "C" void nrnmpi_multisend_multisend_impl(NRNMPI_Spike* spk, int n, int* hosts); +extern mpi_function nrnmpi_multisend_multisend; +extern "C" int nrnmpi_multisend_single_advance_impl(NRNMPI_Spike* spk); +extern mpi_function nrnmpi_multisend_single_advance; +extern "C" int nrnmpi_multisend_conserve_impl(int nsend, int nrecv); +extern mpi_function nrnmpi_multisend_conserve; diff --git a/src/oc/nrnmpi.h b/src/oc/nrnmpi.h index 69e4ee75a4..ce47d6acbd 100644 --- a/src/oc/nrnmpi.h +++ b/src/oc/nrnmpi.h @@ -17,11 +17,6 @@ extern int nrnmpi_subworld_change_cnt; /* increment from within void nrnmpi_subw extern int nrnmpi_subworld_id; /* subworld index on all ranks */ extern int nrnmpi_numprocs_subworld; /* number of ranks in subworld on all ranks */ -typedef struct { - int gid; - double spiketime; -} NRNMPI_Spike; - #if NRNMPI diff --git a/src/oc/nrnmpi_dynam_stubs.cpp b/src/oc/nrnmpi_dynam_stubs.cpp deleted file mode 100644 index 72034f9e51..0000000000 --- a/src/oc/nrnmpi_dynam_stubs.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "../nrnmpi/nrnmpi_dynam_stubs.cpp" diff --git a/src/parallel/bbsclimpi.cpp b/src/parallel/bbsclimpi.cpp index 61387bbc71..33994ed894 100644 --- a/src/parallel/bbsclimpi.cpp +++ b/src/parallel/bbsclimpi.cpp @@ -13,8 +13,6 @@ #include "bbsrcli.h" #include "bbssrv.h" -extern void nrnmpi_int_broadcast(int*, int, int); - #define debug 0 #if defined(HAVE_STL) diff --git a/src/parallel/bbsdirectmpi.cpp b/src/parallel/bbsdirectmpi.cpp index fc1e4f67e5..1797545a62 100644 --- a/src/parallel/bbsdirectmpi.cpp +++ b/src/parallel/bbsdirectmpi.cpp @@ -12,7 +12,6 @@ #include "bbssrv2mpi.h" #include "bbssrv.h" -extern void nrnmpi_int_broadcast(int*, int, int); #if defined(HAVE_STL) #if defined(HAVE_SSTREAM) // the standard ... diff --git a/src/parallel/bbssrvmpi.cpp b/src/parallel/bbssrvmpi.cpp index 894d48e651..1c7655c727 100644 --- a/src/parallel/bbssrvmpi.cpp +++ b/src/parallel/bbssrvmpi.cpp @@ -104,7 +104,7 @@ void BBSDirectServer::handle1(int size, int tag, int cid) { nrnmpi_bbssend(cid, LOOK_YES, send); nrnmpi_unref(send); } else { - nrnmpi_bbssend(cid, LOOK_NO, nil); + nrnmpi_bbssend(cid, LOOK_NO, nullptr); } break; case LOOK_TAKE: @@ -119,7 +119,7 @@ void BBSDirectServer::handle1(int size, int tag, int cid) { nrnmpi_bbssend(cid, LOOK_TAKE_YES, send); nrnmpi_unref(send); } else { - nrnmpi_bbssend(cid, LOOK_TAKE_NO, nil); + nrnmpi_bbssend(cid, LOOK_TAKE_NO, nullptr); } break; case TAKE: