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

Commit 318e25a

Browse files
nrnhinesalexsavulescuoluptonpramodk
authored
BinQ and spike compression fixes (#701)
* Bug fixes with regard to option --spkcompress <nspike> * After compressed spike exchange, do interthread_enqueue. * nrn binq must be initialized before core2nrn queue transfer. * nrncore binq must be initialized before nrn2core queue transfer * interthread buffer must be enqueued at beginning of psolve. * Initialization of binq consistent everywhere. * Avoid Random123 globalindex warning if the index has not changed. Release random123 instance when multisend setup no longer needs it. Psolve restores a few more arg default values. * Revert nrnran123.cu Eliminating the warning when Random123 global index does not change, increases the chance of hiding a bug. * update nmodl submodule * ntasks=16 for gpu tests as well Co-authored-by: Alexandru Săvulescu <alexandru.savulescu@epfl.ch> Co-authored-by: Olli Lupton <oliver.lupton@epfl.ch> Co-authored-by: Pramod Kumbhar <pramod.s.kumbhar@gmail.com>
1 parent 4d2893d commit 318e25a

File tree

13 files changed

+61
-10
lines changed

13 files changed

+61
-10
lines changed

.gitlab-ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ spack_setup:
4949
.gpu_node:
5050
variables:
5151
bb5_constraint: volta
52+
bb5_ntasks: 16
5253
.test_neuron:
5354
extends: [.ctest]
5455
stage: test_neuron

coreneuron/apps/main1.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ static void* load_dynamic_mpi(const std::string& libname) {
472472
extern "C" void mk_mech_init(int argc, char** argv) {
473473
// reset all parameters to their default values
474474
corenrn_param.reset();
475+
475476
// read command line parameters and parameter config files
476477
corenrn_param.parse(argc, argv);
477478

coreneuron/io/core2nrn_data_return.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,14 @@ static void core2nrn_corepointer(int tid, NrnThreadMembList* tml) {
170170
*/
171171
static void core2nrn_tqueue(NrnThread&);
172172

173+
/** @brief Callback to clear NEURON thread queues.
174+
In particular need to initialize bin queues to the current time before
175+
transferring events.
176+
*/
177+
extern "C" {
178+
void (*core2nrn_clear_queues_)(double t);
179+
}
180+
173181
/** @brief All activated WATCH statements need activation on NEURON side.
174182
*/
175183
// vector in unpermuted Memb_list index order of vector of
@@ -200,6 +208,9 @@ void core2nrn_data_return() {
200208
if (!nrn2core_type_return_) {
201209
return;
202210
}
211+
212+
(*core2nrn_clear_queues_)(nrn_threads[0]._t); // all threads at same time
213+
203214
for (int tid = 0; tid < nrn_nthread; ++tid) {
204215
size_t n = 0;
205216
double* data = nullptr;

coreneuron/io/nrn2core_data_init.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ void direct_mode_initialize() {
5151
dt2thread(-1.);
5252
nrn_thread_table_check();
5353

54+
clear_event_queue();
55+
5456
// Reproduce present NEURON WATCH activation
5557
// Start from nothing active.
5658
watch_activate_clear();

coreneuron/io/nrn_setup.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ void nrn_read_filesdat(int& ngrp, int*& grp, const char* filesdat) {
180180
FILE* fp = fopen(filesdat, "r");
181181

182182
if (!fp) {
183-
nrn_fatal_error("No input file with nrnthreads, exiting...");
183+
nrn_fatal_error("No input file ( %s ) with nrnthreads, exiting...", filesdat);
184184
}
185185

186186
char version[256];
@@ -710,6 +710,9 @@ void nrn_cleanup_ion_map() {
710710

711711
void nrn_cleanup() {
712712
clear_event_queue(); // delete left-over TQItem
713+
for (auto psi: gid2in) {
714+
delete psi.second;
715+
}
713716
gid2in.clear();
714717
gid2out.clear();
715718

coreneuron/mpi/lib/mpispike.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extern MPI_Comm nrnmpi_comm;
2424

2525
static int np;
2626
static int* displs{nullptr};
27-
static int* byteovfl; /* for the compressed transfer method */
27+
static int* byteovfl{nullptr}; /* for the compressed transfer method */
2828
static MPI_Datatype spike_type;
2929

3030
static void* emalloc(size_t size) {
@@ -175,7 +175,7 @@ The allgather sends the first part of the buf and the allgatherv buffer
175175
sends any overflow.
176176
*/
177177
int nrnmpi_spike_exchange_compressed_impl(int localgid_size,
178-
unsigned char* spfixin_ovfl,
178+
unsigned char*& spfixin_ovfl,
179179
int send_nspike,
180180
int* nin,
181181
int ovfl_capacity,
@@ -187,9 +187,10 @@ int nrnmpi_spike_exchange_compressed_impl(int localgid_size,
187187
np = nrnmpi_numprocs_;
188188
displs = (int*) emalloc(np * sizeof(int));
189189
displs[0] = 0;
190+
}
191+
if (!byteovfl) {
190192
byteovfl = (int*) emalloc(np * sizeof(int));
191193
}
192-
193194
MPI_Allgather(
194195
spikeout_fixed, ag_send_size, MPI_BYTE, spikein_fixed, ag_send_size, MPI_BYTE, nrnmpi_comm);
195196
int novfl = 0;

coreneuron/mpi/lib/nrnmpi.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ static void nrn_fatal_error(const char* msg) {
3535
}
3636

3737
nrnmpi_init_ret_t nrnmpi_init_impl(int* pargc, char*** pargv, bool is_quiet) {
38+
// Execute at most once per launch. Avoid memory leak.
39+
static bool executed = false;
40+
if (executed) {
41+
return {nrnmpi_numprocs_, nrnmpi_myid_};
42+
}
43+
3844
nrnmpi_under_nrncontrol_ = true;
3945

4046
if (!nrnmpi_initialized_impl()) {
@@ -62,6 +68,7 @@ nrnmpi_init_ret_t nrnmpi_init_impl(int* pargc, char*** pargv, bool is_quiet) {
6268
#endif
6369
}
6470

71+
executed = true;
6572
return {nrnmpi_numprocs_, nrnmpi_myid_};
6673
}
6774

coreneuron/mpi/nrnmpidec.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ extern mpi_function<cnrn_make_integral_constant_t(nrnmpi_write_file_impl)> nrnmp
3737
extern "C" int nrnmpi_spike_exchange_impl(int* nin, NRNMPI_Spike* spikeout, int icapacity, NRNMPI_Spike** spikein, int& ovfl, int nout, NRNMPI_Spikebuf* spbufout, NRNMPI_Spikebuf* spbufin);
3838
extern mpi_function<cnrn_make_integral_constant_t(nrnmpi_spike_exchange_impl)>
3939
nrnmpi_spike_exchange;
40-
extern "C" int nrnmpi_spike_exchange_compressed_impl(int, unsigned char*, int, int*, int, unsigned char*, int, unsigned char*, int& ovfl);
40+
extern "C" int nrnmpi_spike_exchange_compressed_impl(int, unsigned char*&, int, int*, int, unsigned char*, int, unsigned char*, int& ovfl);
4141
extern mpi_function<cnrn_make_integral_constant_t(nrnmpi_spike_exchange_compressed_impl)>
4242
nrnmpi_spike_exchange_compressed;
4343
extern "C" int nrnmpi_int_allmax_impl(int i);

coreneuron/network/multisend_setup.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ void TarList::alloc() {
224224

225225
// for two phase
226226

227-
static nrnran123_State* ranstate;
227+
static nrnran123_State* ranstate{nullptr};
228228

229229
static void random_init(int i) {
230230
if (!ranstate) {
@@ -236,6 +236,14 @@ static unsigned int get_random() {
236236
return nrnran123_ipick(ranstate);
237237
}
238238

239+
// Avoid warnings if the global index is changed on subsequent psolve.
240+
static void random_delete() {
241+
if (ranstate) {
242+
nrnran123_deletestream(ranstate);
243+
ranstate = nullptr;
244+
}
245+
}
246+
239247
static int iran(int i1, int i2) {
240248
// discrete uniform random integer from i2 to i2 inclusive. Must
241249
// work if i1 == i2
@@ -575,6 +583,7 @@ static std::vector<int> setup_target_lists(bool use_phase2) {
575583
phase2organize(tl);
576584
}
577585
}
586+
random_delete();
578587
}
579588

580589
// For clarity, use the all2allv_int style of information flow

coreneuron/network/netcvode.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ void NetCvodeThreadData::interthread_send(double td, DiscreteEvent* db, NrnThrea
135135
inter_thread_events_.emplace_back(InterThreadEvent{db, td});
136136
}
137137

138+
void interthread_enqueue(NrnThread* nt) {
139+
net_cvode_instance->p[nt->id].enqueue(net_cvode_instance, nt);
140+
}
141+
138142
void NetCvodeThreadData::enqueue(NetCvode* nc, NrnThread* nt) {
139143
std::lock_guard<OMP_Mutex> lock(mut);
140144
for (const auto& ite: inter_thread_events_) {
@@ -229,14 +233,14 @@ void NetCvode::clear_events() {
229233
d.unreffed_event_cnt_ = 0;
230234
d.inter_thread_events_.clear();
231235
d.tqe_->nshift_ = -1;
232-
d.tqe_->shift_bin(nrn_threads->_t);
236+
d.tqe_->shift_bin(nrn_threads->_t - 0.5 * nrn_threads->_dt);
233237
}
234238
}
235239

236240
void NetCvode::init_events() {
237241
for (int i = 0; i < nrn_nthread; ++i) {
238242
p[i].tqe_->nshift_ = -1;
239-
p[i].tqe_->shift_bin(nrn_threads->_t);
243+
p[i].tqe_->shift_bin(nrn_threads->_t - 0.5 * nrn_threads->_dt);
240244
}
241245

242246
for (int tid = 0; tid < nrn_nthread; ++tid) { // can be done in parallel

0 commit comments

Comments
 (0)