Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix dist
[simgrid.git] / teshsuite / smpi / mpich3-test / coll / allgatherv4.c
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  *
4  *  (C) 2003 by Argonne National Laboratory.
5  *      See COPYRIGHT in top-level directory.
6  */
7 #include "mpi.h"
8 #include "mpitest.h"
9 #include <stdio.h>
10 #include <stdlib.h>
11 #ifdef HAVE_SYS_TIME_H
12 #include <sys/time.h>
13 #endif
14 #include <time.h>
15 #include <math.h>
16 #include <assert.h>
17 /* FIXME: What is this test supposed to accomplish? */
18 #define START_BUF (1)
19 #define LARGE_BUF (256 * 1024)
20 /* FIXME: MAX_BUF is too large */
21 #define MAX_BUF   (32 * 1024 * 1024)
22 #define LOOPS 10
23 char *sbuf, *rbuf;
24 int *recvcounts, *displs;
25 int errs = 0;
26 /* #define dprintf printf */
27 #define dprintf(...)
28 typedef enum {
29     REGULAR,
30     BCAST,
31     SPIKE,
32     HALF_FULL,
33     LINEAR_DECREASE,
34     BELL_CURVE
35 } test_t;
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)
39 {
40     int comm_size, comm_rank;
41     MPI_Comm comm;
42     MTest_Init(&argc, &argv);
43     MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
44     MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
45     if (comm_size < 3) {
46         fprintf(stderr, "At least 3 processes required\n");
47         MPI_Abort(MPI_COMM_WORLD, 1);
48     }
49     if (LARGE_BUF * comm_size > MAX_BUF)
50         goto fn_exit;
51     sbuf = (void *) calloc(MAX_BUF, 1);
52     rbuf = (void *) calloc(MAX_BUF, 1);
53     srand(time(NULL));
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");
58         if (!sbuf)
59             fprintf(stderr, "\tsbuf of %d bytes\n", MAX_BUF);
60         if (!rbuf)
61             fprintf(stderr, "\trbuf of %d bytes\n", MAX_BUF);
62         if (!recvcounts)
63             fprintf(stderr, "\trecvcounts of %zd bytes\n", comm_size * sizeof(int));
64         if (!displs)
65             fprintf(stderr, "\tdispls of %zd bytes\n", comm_size * sizeof(int));
66         fflush(stderr);
67         MPI_Abort(MPI_COMM_WORLD, -1);
68     }
69     if (!comm_rank) {
70         dprintf("Message Range: (%d, %d); System size: %d\n", START_BUF, LARGE_BUF, comm_size);
71         fflush(stdout);
72     }
73     /* COMM_WORLD tests */
74     if (!comm_rank) {
75         dprintf("\n\n==========================================================\n");
76         dprintf("                         MPI_COMM_WORLD\n");
77         dprintf("==========================================================\n");
78     }
79     comm_tests(MPI_COMM_WORLD);
80     /* non-COMM_WORLD tests */
81     if (!comm_rank) {
82         dprintf("\n\n==========================================================\n");
83         dprintf("                         non-COMM_WORLD\n");
84         dprintf("==========================================================\n");
85     }
86     MPI_Comm_split(MPI_COMM_WORLD, (comm_rank == comm_size - 1) ? 0 : 1, 0, &comm);
87     if (comm_rank < comm_size - 1)
88         comm_tests(comm);
89     MPI_Comm_free(&comm);
90     /* Randomized communicator tests */
91     if (!comm_rank) {
92         dprintf("\n\n==========================================================\n");
93         dprintf("                         Randomized Communicator\n");
94         dprintf("==========================================================\n");
95     }
96     MPI_Comm_split(MPI_COMM_WORLD, 0, rand(), &comm);
97     comm_tests(comm);
98     MPI_Comm_free(&comm);
99     free(sbuf);
100     free(rbuf);
101     free(recvcounts);
102     free(displs);
103   fn_exit:
104     MTest_Finalize(errs);
105     MPI_Finalize();
106     return 0;
107 }
108 void comm_tests(MPI_Comm comm)
109 {
110     int comm_size, comm_rank;
111     double rtime = rtime;       /* stop warning about unused variable */
112     double max_time;
113     long long msg_size;
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) {
117         if (!comm_rank) {
118             dprintf("\n====> MSG_SIZE: %d\n", (int) msg_size);
119             fflush(stdout);
120         }
121         rtime = run_test(msg_size, comm, REGULAR, &max_time);
122         if (!comm_rank) {
123             dprintf("REGULAR:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
124             fflush(stdout);
125         }
126         rtime = run_test(msg_size, comm, BCAST, &max_time);
127         if (!comm_rank) {
128             dprintf("BCAST:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
129             fflush(stdout);
130         }
131         rtime = run_test(msg_size, comm, SPIKE, &max_time);
132         if (!comm_rank) {
133             dprintf("SPIKE:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
134             fflush(stdout);
135         }
136         rtime = run_test(msg_size, comm, HALF_FULL, &max_time);
137         if (!comm_rank) {
138             dprintf("HALF_FULL:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
139             fflush(stdout);
140         }
141         rtime = run_test(msg_size, comm, LINEAR_DECREASE, &max_time);
142         if (!comm_rank) {
143             dprintf("LINEAR_DECREASE:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
144             fflush(stdout);
145         }
146         rtime = run_test(msg_size, comm, BELL_CURVE, &max_time);
147         if (!comm_rank) {
148             dprintf("BELL_CURVE:\tAVG: %.3f\tMAX: %.3f\n", rtime, max_time);
149             fflush(stdout);
150         }
151     }
152 }
153 double run_test(long long msg_size, MPI_Comm comm, test_t test_type, double *max_time)
154 {
155     int i, j;
156     int comm_size, comm_rank;
157     double start, end;
158     double total_time, avg_time;
159     MPI_Aint tmp;
160     MPI_Comm_size(comm, &comm_size);
161     MPI_Comm_rank(comm, &comm_rank);
162     displs[0] = 0;
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);
177             }
178             recvcounts[i] = (int) tmp;
179             /* If the maximum message size is too large, don't run */
180             if (tmp > MAX_BUF)
181                 return 0;
182         }
183         else if (test_type == BELL_CURVE) {
184             for (j = 0; j < i; j++) {
185                 if (i - 1 + j >= comm_size)
186                     continue;
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 */
191                 if (tmp > MAX_BUF)
192                     return 0;
193             }
194         }
195         if (i < comm_size - 1)
196             displs[i + 1] = displs[i] + recvcounts[i];
197     }
198     /* Test that:
199      * 1: sbuf is large enough
200      * 2: rbuf is large enough
201      * 3: There were no failures (e.g., tmp nowhere > rbuf size
202      */
203     MPI_Barrier(comm);
204     start = MPI_Wtime();
205     for (i = 0; i < LOOPS; i++) {
206         MPI_Allgatherv(sbuf, recvcounts[comm_rank], MPI_CHAR,
207                        rbuf, recvcounts, displs, MPI_CHAR, comm);
208     }
209     end = MPI_Wtime();
210     MPI_Barrier(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));
216 }