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

Commit d16248b

Browse files
pramodkolupton
andauthored
(Minimum) Changes to avoid floating-point exceptions (#491)
* If coreneuron is compiled with MPI but run without --mpi flag then coreneuron crashes. This doesn't allow NEURON to run existing tests (e.g. using python API) * Instead of using MPI function, using wrappers from mpispike.cpp * Updated all reduce wrapper to accept size_t / unsigned long int than just size_t * Update cast and summary printf * Add test that can run without MPI launcher Co-authored-by: Olli Lupton <[email protected]>
1 parent 5a93d9b commit d16248b

File tree

4 files changed

+47
-46
lines changed

4 files changed

+47
-46
lines changed

coreneuron/io/mech_report.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace coreneuron {
1919
void write_mech_report() {
2020
/// mechanim count across all gids, local to rank
2121
const auto n_memb_func = corenrn.get_memb_funcs().size();
22-
std::vector<unsigned long long> local_mech_count(n_memb_func, 0);
22+
std::vector<long> local_mech_count(n_memb_func, 0);
2323

2424
/// each gid record goes on separate row, only check non-empty threads
2525
for (size_t i = 0; i < nrn_nthread; i++) {
@@ -31,16 +31,14 @@ void write_mech_report() {
3131
}
3232
}
3333

34-
std::vector<unsigned long long> total_mech_count(n_memb_func);
34+
std::vector<long> total_mech_count(n_memb_func);
3535

3636
#if NRNMPI
3737
/// get global sum of all mechanism instances
38-
MPI_Allreduce(&local_mech_count[0],
39-
&total_mech_count[0],
40-
local_mech_count.size(),
41-
MPI_UNSIGNED_LONG_LONG,
42-
MPI_SUM,
43-
nrnmpi_comm);
38+
nrnmpi_long_allreduce_vec(&local_mech_count[0],
39+
&total_mech_count[0],
40+
local_mech_count.size(),
41+
1);
4442

4543
#else
4644
total_mech_count = local_mech_count;
@@ -50,7 +48,7 @@ void write_mech_report() {
5048
printf("\n================ MECHANISMS COUNT BY TYPE ==================\n");
5149
printf("%4s %20s %10s\n", "Id", "Name", "Count");
5250
for (size_t i = 0; i < total_mech_count.size(); i++) {
53-
printf("%4lu %20s %10lld\n", i, nrn_get_mechname(i), total_mech_count[i]);
51+
printf("%4lu %20s %10ld\n", i, nrn_get_mechname(i), total_mech_count[i]);
5452
}
5553
printf("=============================================================\n");
5654
}

coreneuron/io/nrn_setup.cpp

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -996,18 +996,18 @@ size_t input_presyn_size(void) {
996996
}
997997

998998
size_t model_size(bool detailed_report) {
999-
size_t nbyte = 0;
999+
long nbyte = 0;
10001000
size_t sz_nrnThread = sizeof(NrnThread);
10011001
size_t sz_presyn = sizeof(PreSyn);
10021002
size_t sz_input_presyn = sizeof(InputPreSyn);
10031003
size_t sz_netcon = sizeof(NetCon);
10041004
size_t sz_pntproc = sizeof(Point_process);
10051005
size_t nccnt = 0;
10061006

1007-
std::vector<size_t> size_data(13, 0);
1008-
std::vector<size_t> global_size_data_min(13, 0);
1009-
std::vector<size_t> global_size_data_max(13, 0);
1010-
std::vector<size_t> global_size_data_sum(13, 0);
1007+
std::vector<long> size_data(13, 0);
1008+
std::vector<long> global_size_data_min(13, 0);
1009+
std::vector<long> global_size_data_max(13, 0);
1010+
std::vector<long> global_size_data_sum(13, 0);
10111011
std::vector<float> global_size_data_avg(13, 0.0);
10121012

10131013
for (int i = 0; i < nrn_nthread; ++i) {
@@ -1081,24 +1081,10 @@ size_t model_size(bool detailed_report) {
10811081
if (detailed_report) {
10821082
size_data[12] = nbyte;
10831083
#if NRNMPI
1084-
MPI_Allreduce(&size_data[0],
1085-
&global_size_data_min[0],
1086-
13,
1087-
MPI_UNSIGNED_LONG_LONG,
1088-
MPI_MIN,
1089-
nrnmpi_comm);
1090-
MPI_Allreduce(&size_data[0],
1091-
&global_size_data_max[0],
1092-
13,
1093-
MPI_UNSIGNED_LONG_LONG,
1094-
MPI_MAX,
1095-
nrnmpi_comm);
1096-
MPI_Allreduce(&size_data[0],
1097-
&global_size_data_sum[0],
1098-
13,
1099-
MPI_UNSIGNED_LONG_LONG,
1100-
MPI_SUM,
1101-
nrnmpi_comm);
1084+
// last arg is op type where 1 is sum, 2 is max and any other value is min
1085+
nrnmpi_long_allreduce_vec(&size_data[0], &global_size_data_sum[0], 13, 1);
1086+
nrnmpi_long_allreduce_vec(&size_data[0], &global_size_data_max[0], 13, 2);
1087+
nrnmpi_long_allreduce_vec(&size_data[0], &global_size_data_min[0], 13, 3);
11021088
for (int i = 0; i < 13; i++) {
11031089
global_size_data_avg[i] = global_size_data_sum[i] / float(nrnmpi_numprocs);
11041090
}
@@ -1201,10 +1187,9 @@ size_t model_size(bool detailed_report) {
12011187
}
12021188

12031189
#if NRNMPI
1204-
size_t global_nbyte = 0;
1205-
MPI_Allreduce(&nbyte, &global_nbyte, 1, MPI_UNSIGNED_LONG_LONG, MPI_SUM, nrnmpi_comm);
1190+
long global_nbyte = 0;
1191+
nrnmpi_long_allreduce_vec(&nbyte, &global_nbyte, 1, 1);
12061192
nbyte = global_nbyte;
1207-
12081193
#endif
12091194

12101195
return nbyte;

coreneuron/utils/nrn_stats.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,20 @@ void report_cell_stats(void) {
3333
long stat_array[NUM_STATS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, gstat_array[NUM_STATS];
3434

3535
for (int ith = 0; ith < nrn_nthread; ++ith) {
36-
stat_array[0] += (long) nrn_threads[ith].ncell; // number of cells
37-
stat_array[10] += (long) nrn_threads[ith].end; // number of compartments
38-
stat_array[1] += (long) nrn_threads[ith].n_presyn; // number of presyns
39-
stat_array[2] += (long) nrn_threads[ith].n_input_presyn; // number of input presyns
40-
stat_array[3] += (long) nrn_threads[ith].n_netcon; // number of netcons, synapses
41-
stat_array[4] += (long) nrn_threads[ith].n_pntproc; // number of point processes
36+
stat_array[0] += nrn_threads[ith].ncell; // number of cells
37+
stat_array[10] += nrn_threads[ith].end; // number of compartments
38+
stat_array[1] += nrn_threads[ith].n_presyn; // number of presyns
39+
stat_array[2] += nrn_threads[ith].n_input_presyn; // number of input presyns
40+
stat_array[3] += nrn_threads[ith].n_netcon; // number of netcons, synapses
41+
stat_array[4] += nrn_threads[ith].n_pntproc; // number of point processes
4242
if (nrn_partrans::transfer_thread_data_) {
4343
size_t n = nrn_partrans::transfer_thread_data_[ith].tar_indices.size();
44-
stat_array[11] += (long) n; // number of transfer targets
44+
stat_array[11] += n; // number of transfer targets
4545
n = nrn_partrans::transfer_thread_data_[ith].src_indices.size();
46-
stat_array[12] += (long) n; // number of transfer sources
46+
stat_array[12] += n; // number of transfer sources
4747
}
4848
}
49-
stat_array[5] = (long) spikevec_gid.size(); // number of spikes
49+
stat_array[5] = spikevec_gid.size(); // number of spikes
5050

5151
int spikevec_positive_gid_size = 0;
5252
for (std::size_t i = 0; i < spikevec_gid.size(); ++i) {
@@ -55,7 +55,7 @@ void report_cell_stats(void) {
5555
}
5656
}
5757

58-
stat_array[6] = (long) spikevec_positive_gid_size; // number of non-negative gid spikes
58+
stat_array[6] = spikevec_positive_gid_size; // number of non-negative gid spikes
5959

6060
#if NRNMPI
6161
nrnmpi_long_allreduce_vec(stat_array, gstat_array, NUM_STATS, 1);

tests/integration/CMakeLists.txt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ set(TEST_CASES_WITH_ARGS
3030
"ring_gap_permute2!${RING_GAP_COMMON_ARGS} ${GPU_ARGS} --outpath ${CMAKE_CURRENT_BINARY_DIR}/ring_gap_permute2 ${PERMUTE2_ARGS}"
3131
)
3232

33+
# ~~~
34+
# As reports require MPI, do not add test if report is enabled.
35+
# GPU tests need SLURM allocation and hence they won't run without srun
36+
# ~~~
37+
if(NOT CORENRN_ENABLE_REPORTING AND NOT CORENRN_ENABLE_GPU)
38+
list(
39+
APPEND
40+
TEST_CASES_WITH_ARGS
41+
"ring_serial!--tstop 100. --celsius 6.3 --datpath ${RING_DATASET_DIR} ${MODEL_STATS_ARG} --outpath ${CMAKE_CURRENT_BINARY_DIR}/ring_serial"
42+
)
43+
endif()
44+
3345
set(NEGATIVE_TEST_CASES_WITH_ARGS
3446
"ring_different_seed!${RING_COMMON_ARGS} ${GPU_ARGS} --outpath ${CMAKE_CURRENT_BINARY_DIR}/ring_different_seed --seed 123456"
3547
)
@@ -41,6 +53,7 @@ set(NEGATIVE_TEST_CASES_WITH_ARGS
4153
foreach(data_dir "ring" "ring_gap")
4254
foreach(
4355
test_suffix
56+
"serial"
4457
"multisend"
4558
"binqueue"
4659
"savestate_permute0"
@@ -67,7 +80,12 @@ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/ring/out.dat.ref"
6780
foreach(args_line ${TEST_CASES_WITH_ARGS})
6881
string(REPLACE "!" ";" string_line ${args_line})
6982
if(MPI_FOUND)
70-
string(REPLACE ";" " " SRUN_PREFIX "${TEST_MPI_EXEC_BIN};-n;2")
83+
# serial test run without srun or mpiexec
84+
if(args_line MATCHES "ring_serial.*")
85+
string(REPLACE ";" " " SRUN_PREFIX "")
86+
else()
87+
string(REPLACE ";" " " SRUN_PREFIX "${TEST_MPI_EXEC_BIN};-n;2")
88+
endif()
7189
endif()
7290
list(GET string_line 0 TEST_NAME)
7391
list(GET string_line 1 TEST_ARGS)

0 commit comments

Comments
 (0)