12#include "gadgetconfig.h"
20#include "../data/allvars.h"
21#include "../data/dtypes.h"
22#include "../data/mymalloc.h"
23#include "../logs/logs.h"
24#include "../main/simulation.h"
25#include "../mpi_utils/mpi_utils.h"
26#include "../system/system.h"
28#define TEST_PACKET_SIZE_IN_MB 5
29#define WORK_LOOP_COUNTER 50000000
30#define WORK_NUMBER_OF_IPROBE_TESTS 1000000
32#ifndef MAX_VARIATION_TOLERANCE
33#define MAX_VARIATION_TOLERANCE 0.5
45 measure_hyper_cube_speed(
"Full hypercube:",
Communicator);
61 measure_hyper_cube_speed(
"Internode cube:", comm);
73 measure_hyper_cube_speed(
"Intranode cube, 1st node:", comm);
78 measure_iprobe_performance(
"Iprobe for any message:");
83double sim::measure_cpu_performance(MPI_Comm Communicator)
85 int loc_ntask, loc_thistask, loc_ptask;
92 for(loc_ptask = 0; loc_ntask > (1 << loc_ptask); loc_ptask++)
109 MPI_Allreduce(&tperf, &tperfsum, 1, MPI_DOUBLE, MPI_SUM,
Communicator);
110 double tavg = tperfsum / loc_ntask;
116 } local = {tperf,
ThisTask}, localnode = {tperf,
ThisNode}, min_time, max_time, min_timenode, max_timenode;
118 MPI_Allreduce(&local, &min_time, 1, MPI_DOUBLE_INT, MPI_MINLOC,
Communicator);
119 MPI_Allreduce(&local, &max_time, 1, MPI_DOUBLE_INT, MPI_MAXLOC,
Communicator);
121 MPI_Allreduce(&localnode, &min_timenode, 1, MPI_DOUBLE_INT, MPI_MINLOC,
Communicator);
122 MPI_Allreduce(&localnode, &max_timenode, 1, MPI_DOUBLE_INT, MPI_MAXLOC,
Communicator);
124 double variation = (max_time.t - min_time.t) / tavg;
129 "HEALTHTEST: %25s %8.3f sec %7.3f%% variation | Best=%g on Task=%d/Node=%d, Worst=%g on Task=%d/Node=%d, test "
131 "CPU performance:", tavg, 100.0 * variation, min_time.t, min_time.rank, min_timenode.rank, max_time.t, max_time.rank,
136 char name_maxnode[MPI_MAX_PROCESSOR_NAME];
139 MPI_Get_processor_name(name_maxnode, &len);
141 MPI_Bcast(name_maxnode, MPI_MAX_PROCESSOR_NAME, MPI_CHAR, max_time.rank,
Communicator);
143 char buf[1000 + MPI_MAX_PROCESSOR_NAME];
144 sprintf(buf,
"processes_%s.txt", name_maxnode);
146 mpi_printf(
"HEALTHTEST: We are dumping a process list to the file '%s'\n", buf);
150 char cmd[10000 + MPI_MAX_PROCESSOR_NAME];
151 sprintf(cmd,
"ps -ef >& %s", buf);
159 "\n\nHEALTHTEST: We issue a warning because the performance variation=%g of the CPUs lies above the prescribed tolerance "
160 "MAX_VARIATION_TOLERANCE=%g, possibly indicating a machine problem. (sum=%g)\n",
167double sim::measure_hyper_cube_speed(
const char *tag, MPI_Comm Communicator)
171 int loc_ntask, loc_thistask, loc_ptask;
176 for(loc_ptask = 0; loc_ntask > (1 << loc_ptask); loc_ptask++)
184 char *sendbuf = (
char *)
Mem.mymalloc_clear(
"send", bytecount *
sizeof(
char));
185 char *recvbuf = (
char *)
Mem.mymalloc_clear(
"recv", bytecount *
sizeof(
char));
188 for(
int ngrp = 1; ngrp < (1 << loc_ptask); ngrp++)
190 int recvTask = loc_thistask ^ ngrp;
194 if(recvTask < loc_ntask)
197 myMPI_Sendrecv(sendbuf, bytecount, MPI_BYTE, recvTask,
TAG_DENS_A, recvbuf, bytecount, MPI_BYTE, recvTask,
TAG_DENS_A,
209 double tperf = 0.5 * tall / count, tperfsum;
211 MPI_Allreduce(&tperf, &tperfsum, 1, MPI_DOUBLE, MPI_SUM,
Communicator);
212 double tavg = tperfsum / loc_ntask;
218 } local = {tperf,
ThisTask}, localnode = {tperf,
ThisNode}, min_time, max_time, min_timenode, max_timenode;
220 MPI_Allreduce(&local, &min_time, 1, MPI_DOUBLE_INT, MPI_MINLOC,
Communicator);
221 MPI_Allreduce(&local, &max_time, 1, MPI_DOUBLE_INT, MPI_MAXLOC,
Communicator);
223 MPI_Allreduce(&localnode, &min_timenode, 1, MPI_DOUBLE_INT, MPI_MINLOC,
Communicator);
224 MPI_Allreduce(&localnode, &max_timenode, 1, MPI_DOUBLE_INT, MPI_MAXLOC,
Communicator);
228 double variation = (bytecount / min_time.t - bytecount / max_time.t) / (bytecount / tavg);
231 "HEALTHTEST: %25s %8.1f MB/s per pair %7.3f%% variation | Best=%g on Task=%d/Node=%d, Worst=%g on Task=%d/Node=%d, test "
233 tag, bytecount / tavg *
TO_MBYTE_FAC, 100.0 * variation, bytecount / min_time.t *
TO_MBYTE_FAC, min_time.rank, min_timenode.rank,
238 "\nThe performance variation=%g of the communication speed lies above the prescribed tolerance MAX_VARIATION_TOLERANCE=%g, "
239 "possibly indicating a machine problem.\n",
245void sim::measure_iprobe_performance(
const char *tag)
254 MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG,
Communicator, &flag, &status);
265 } local = {tperf,
ThisTask}, min_time, max_time;
267 MPI_Allreduce(&local, &min_time, 1, MPI_DOUBLE_INT, MPI_MINLOC,
Communicator);
268 MPI_Allreduce(&local, &max_time, 1, MPI_DOUBLE_INT, MPI_MAXLOC,
Communicator);
271 MPI_Allreduce(&tperf, &tperfsum, 1, MPI_DOUBLE, MPI_SUM,
Communicator);
272 double tavg = tperfsum /
NTask;
274 char name_minnode[MPI_MAX_PROCESSOR_NAME];
275 char name_maxnode[MPI_MAX_PROCESSOR_NAME];
279 MPI_Get_processor_name(name_minnode, &len);
281 MPI_Get_processor_name(name_maxnode, &len);
283 MPI_Bcast(name_minnode, MPI_MAX_PROCESSOR_NAME, MPI_BYTE, min_time.rank,
Communicator);
284 MPI_Bcast(name_maxnode, MPI_MAX_PROCESSOR_NAME, MPI_BYTE, max_time.rank,
Communicator);
286 double variation = (max_time.t - min_time.t) / tavg;
289 "HEALTHTEST: %25s %g s per MPI_Ip%7.3f%% variation | Best=%g on Task=%d/Node=%s, Worst=%g on Task=%d/Node=%s, test took %g "
291 tag, tavg, 100.0 * variation, min_time.t, min_time.rank, name_minnode, max_time.t, max_time.rank, name_maxnode,
double timediff(double t0, double t1)
void mpi_printf(const char *fmt,...)
#define TEST_PACKET_SIZE_IN_MB
#define WORK_NUMBER_OF_IPROBE_TESTS
#define MAX_VARIATION_TOLERANCE
#define WORK_LOOP_COUNTER
int myMPI_Sendrecv(void *sendbuf, size_t sendcount, MPI_Datatype sendtype, int dest, int sendtag, void *recvbuf, size_t recvcount, MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, MPI_Status *status)