1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2003 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
11 #ifdef HAVE_SYS_TIME_H
17 /* FIXME: What is this test supposed to accomplish? */
19 #define LARGE_BUF (256 * 1024)
20 /* FIXME: MAX_BUF is too large */
21 #define MAX_BUF (32 * 1024 * 1024)
24 int *recvcounts, *displs;
26 /* #define dprintf printf */
36 void comm_tests(MPI_Comm comm);
37 double run_test(long long msg_size, MPI_Comm comm, test_t test_type, double *max_time);
38 int main(int argc, char **argv)
40 int comm_size, comm_rank;
42 MTest_Init(&argc, &argv);
43 MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
44 MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
46 fprintf(stderr, "At least 3 processes required\n");
47 MPI_Abort(MPI_COMM_WORLD, 1);
49 if (LARGE_BUF * comm_size > MAX_BUF)
51 sbuf = (void *) calloc(MAX_BUF, 1);
52 rbuf = (void *) calloc(MAX_BUF, 1);
54 recvcounts = (void *) malloc(comm_size * sizeof(int));
55 displs = (void *) malloc(comm_size * sizeof(int));
56 if (!recvcounts || !displs || !sbuf || !rbuf) {
57 fprintf(stderr, "Unable to allocate memory:\n");
59 fprintf(stderr, "\tsbuf of %d bytes\n", MAX_BUF);
61 fprintf(stderr, "\trbuf of %d bytes\n", MAX_BUF);
63 fprintf(stderr, "\trecvcounts of %zu bytes\n", comm_size * sizeof(int));
65 fprintf(stderr, "\tdispls of %zu bytes\n", comm_size * sizeof(int));
67 MPI_Abort(MPI_COMM_WORLD, -1);
70 dprintf("Message Range: (%d, %d); System size: %d\n", START_BUF, LARGE_BUF, comm_size);
73 /* COMM_WORLD tests */
75 dprintf("\n\n==========================================================\n");
76 dprintf(" MPI_COMM_WORLD\n");
77 dprintf("==========================================================\n");
79 comm_tests(MPI_COMM_WORLD);
80 /* non-COMM_WORLD tests */
82 dprintf("\n\n==========================================================\n");
83 dprintf(" non-COMM_WORLD\n");
84 dprintf("==========================================================\n");
86 MPI_Comm_split(MPI_COMM_WORLD, (comm_rank == comm_size - 1) ? 0 : 1, 0, &comm);
87 if (comm_rank < comm_size - 1)
90 /* Randomized communicator tests */
92 dprintf("\n\n==========================================================\n");
93 dprintf(" Randomized Communicator\n");
94 dprintf("==========================================================\n");
96 MPI_Comm_split(MPI_COMM_WORLD, 0, rand(), &comm);
104 MTest_Finalize(errs);
108 void comm_tests(MPI_Comm comm)
110 int comm_size, comm_rank;
111 double rtime = rtime; /* stop warning about unused variable */
114 MPI_Comm_size(comm, &comm_size);
115 MPI_Comm_rank(comm, &comm_rank);
116 for (msg_size = START_BUF; msg_size <= LARGE_BUF; msg_size *= 2) {
118 dprintf("\n====> MSG_SIZE: %d\n", (int) msg_size);
121 rtime = run_test(msg_size, comm, REGULAR, &max_time);
123 dprintf("REGULAR:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
126 rtime = run_test(msg_size, comm, BCAST, &max_time);
128 dprintf("BCAST:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
131 rtime = run_test(msg_size, comm, SPIKE, &max_time);
133 dprintf("SPIKE:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
136 rtime = run_test(msg_size, comm, HALF_FULL, &max_time);
138 dprintf("HALF_FULL:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
141 rtime = run_test(msg_size, comm, LINEAR_DECREASE, &max_time);
143 dprintf("LINEAR_DECREASE:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
146 rtime = run_test(msg_size, comm, BELL_CURVE, &max_time);
148 dprintf("BELL_CURVE:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
153 double run_test(long long msg_size, MPI_Comm comm, test_t test_type, double *max_time)
156 int comm_size, comm_rank;
158 double total_time, avg_time;
160 MPI_Comm_size(comm, &comm_size);
161 MPI_Comm_rank(comm, &comm_rank);
163 for (i = 0; i < comm_size; i++) {
164 if (test_type == REGULAR)
165 recvcounts[i] = msg_size;
166 else if (test_type == BCAST)
167 recvcounts[i] = (!i) ? msg_size : 0;
168 else if (test_type == SPIKE)
169 recvcounts[i] = (!i) ? (msg_size / 2) : (msg_size / (2 * (comm_size - 1)));
170 else if (test_type == HALF_FULL)
171 recvcounts[i] = (i < (comm_size / 2)) ? (2 * msg_size) : 0;
172 else if (test_type == LINEAR_DECREASE) {
173 tmp = 2 * msg_size * (comm_size - 1 - i) / (comm_size - 1);
174 if (tmp != (int) tmp) {
175 fprintf(stderr, "Integer overflow in variable tmp\n");
176 MPI_Abort(MPI_COMM_WORLD, 1);
178 recvcounts[i] = (int) tmp;
179 /* If the maximum message size is too large, don't run */
183 else if (test_type == BELL_CURVE) {
184 for (j = 0; j < i; j++) {
185 if (i - 1 + j >= comm_size)
187 tmp = msg_size * comm_size / (log(comm_size) * i);
188 recvcounts[i - 1 + j] = (int) tmp;
189 displs[i - 1 + j] = 0;
190 /* If the maximum message size is too large, don't run */
195 if (i < comm_size - 1)
196 displs[i + 1] = displs[i] + recvcounts[i];
199 * 1: sbuf is large enough
200 * 2: rbuf is large enough
201 * 3: There were no failures (e.g., tmp nowhere > rbuf size
205 for (i = 0; i < LOOPS; i++) {
206 MPI_Allgatherv(sbuf, recvcounts[comm_rank], MPI_CHAR,
207 rbuf, recvcounts, displs, MPI_CHAR, comm);
211 /* Convert to microseconds (why?) */
212 total_time = 1.0e6 * (end - start);
213 MPI_Reduce(&total_time, &avg_time, 1, MPI_DOUBLE, MPI_SUM, 0, comm);
214 MPI_Reduce(&total_time, max_time, 1, MPI_DOUBLE, MPI_MAX, 0, comm);
215 return (avg_time / (LOOPS * comm_size));