1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 #include "mpi.h"
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10 
11 #ifndef TRUE
12 #define TRUE 1
13 #endif
14 #ifndef FALSE
15 #define FALSE 0
16 #endif
17 
18 #define DEFAULT_RNDV_SIZE 24*1024
19 /* Prototypes */
20 int SendRecvTest(int, int);
21 int IsendIrecvTest(int);
22 int IsenIrecvTest2(int, int);
23 int OutOfOrderTest(int, int);
24 int ForceUnexpectedTest(int, int);
25 int RndvTest(int, int, int);
26 
SendRecvTest(int rank,int n)27 int SendRecvTest(int rank, int n)
28 {
29     int tag = 1;
30     MPI_Status status;
31     char buffer[100];
32     int i;
33 
34     if (rank == 0) {
35         strcpy(buffer, "Hello process one.");
36         for (i = 0; i < n; i++)
37             MPI_Send(buffer, 100, MPI_BYTE, 1, tag, MPI_COMM_WORLD);
38     } else if (rank == 1) {
39         for (i = 0; i < n; i++)
40             MPI_Recv(buffer, 100, MPI_BYTE, 0, tag, MPI_COMM_WORLD, &status);
41         /*printf("Rank 1: received message '%s'\n", buffer);fflush(stdout); */
42     }
43 
44     return TRUE;
45 }
46 
IsendIrecvTest(int rank)47 int IsendIrecvTest(int rank)
48 {
49     int tag = 1;
50     MPI_Status status;
51     MPI_Request request;
52     char buffer[100];
53 
54     if (rank == 0) {
55         strcpy(buffer, "Hello process one.");
56         MPI_Isend(buffer, 100, MPI_BYTE, 1, tag, MPI_COMM_WORLD, &request);
57         MPI_Wait(&request, &status);
58     } else if (rank == 1) {
59         MPI_Irecv(buffer, 100, MPI_BYTE, 0, tag, MPI_COMM_WORLD, &request);
60         MPI_Wait(&request, &status);
61         /*printf("Rank 1: received message '%s'\n", buffer);fflush(stdout); */
62     }
63 
64     return TRUE;
65 }
66 
67 int IsendIrecvTest2(int rank, int buf_size);
IsendIrecvTest2(int rank,int buf_size)68 int IsendIrecvTest2(int rank, int buf_size)
69 {
70     int tag1 = 1;
71     int tag2 = 2;
72     MPI_Status status;
73     MPI_Request request1, request2;
74     char *buffer;
75 
76     buffer = (char *) malloc(buf_size);
77     if (buffer == NULL)
78         return FALSE;
79     if (rank == 0) {
80         strcpy(buffer, "Hello process one.");
81         MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag1, MPI_COMM_WORLD, &request1);
82         MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag2, MPI_COMM_WORLD, &request2);
83         MPI_Wait(&request1, &status);
84         MPI_Wait(&request2, &status);
85     } else if (rank == 1) {
86         MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag1, MPI_COMM_WORLD, &request1);
87         MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag2, MPI_COMM_WORLD, &request2);
88         MPI_Wait(&request1, &status);
89         MPI_Wait(&request2, &status);
90         /*printf("Rank 1: received message '%s'\n", buffer);fflush(stdout); */
91     }
92 
93     free(buffer);
94     return TRUE;
95 }
96 
OutOfOrderTest(int rank,int buf_size)97 int OutOfOrderTest(int rank, int buf_size)
98 {
99     int tag1 = 1;
100     int tag2 = 2;
101     MPI_Status status;
102     MPI_Request request1, request2;
103     char *buffer;
104 
105     buffer = (char *) malloc(buf_size);
106     if (buffer == NULL)
107         return FALSE;
108     if (rank == 0) {
109         strcpy(buffer, "Hello process one.");
110         MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag1, MPI_COMM_WORLD, &request1);
111         MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag2, MPI_COMM_WORLD, &request2);
112         MPI_Wait(&request1, &status);
113         MPI_Wait(&request2, &status);
114     } else if (rank == 1) {
115         MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag2, MPI_COMM_WORLD, &request1);
116         MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag1, MPI_COMM_WORLD, &request2);
117         MPI_Wait(&request2, &status);
118         MPI_Wait(&request1, &status);
119         /*printf("Rank 1: received message '%s'\n", buffer);fflush(stdout); */
120     }
121 
122     free(buffer);
123     return TRUE;
124 }
125 
ForceUnexpectedTest(int rank,int buf_size)126 int ForceUnexpectedTest(int rank, int buf_size)
127 {
128     int tag1 = 1;
129     int tag2 = 2;
130     MPI_Status status;
131     MPI_Request request1, request2;
132     char *buffer;
133 
134     buffer = (char *) malloc(buf_size);
135     if (buffer == NULL)
136         return FALSE;
137 
138     if (rank == 0) {
139         strcpy(buffer, "Hello process one.");
140         MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag1, MPI_COMM_WORLD, &request1);
141         MPI_Isend(buffer, buf_size, MPI_BYTE, 1, tag2, MPI_COMM_WORLD, &request2);
142         MPI_Wait(&request1, &status);
143         MPI_Wait(&request2, &status);
144         MPI_Recv(buffer, buf_size, MPI_BYTE, 1, tag1, MPI_COMM_WORLD, &status);
145     } else if (rank == 1) {
146         MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag2, MPI_COMM_WORLD, &request2);
147         MPI_Wait(&request2, &status);
148         MPI_Irecv(buffer, buf_size, MPI_BYTE, 0, tag1, MPI_COMM_WORLD, &request1);
149         MPI_Wait(&request1, &status);
150         /*printf("Rank 1: received message '%s'\n", buffer);fflush(stdout); */
151         MPI_Send(buffer, buf_size, MPI_BYTE, 0, tag1, MPI_COMM_WORLD);
152     }
153 
154     free(buffer);
155 
156     return TRUE;
157 }
158 
RndvTest(int rank,int size,int reps)159 int RndvTest(int rank, int size, int reps)
160 {
161     int tag = 1;
162     MPI_Status status;
163     char *buffer;
164     int i;
165 
166     buffer = (char *) malloc(size);
167     if (buffer == NULL) {
168         printf("malloc failed to allocate %d bytes.\n", size);
169         exit(0);
170     }
171     if (rank == 0) {
172         for (i = 0; i < reps; i++) {
173             if (reps == 1) {
174                 printf("0: sending to process 1\n");
175                 fflush(stdout);
176             }
177             MPI_Send(buffer, size, MPI_BYTE, 1, tag, MPI_COMM_WORLD);
178             if (reps == 1) {
179                 printf("0: receiving from process 1\n");
180                 fflush(stdout);
181             }
182             MPI_Recv(buffer, size, MPI_BYTE, 1, tag, MPI_COMM_WORLD, &status);
183             if (reps == 1) {
184                 printf("0: done\n");
185                 fflush(stdout);
186             }
187         }
188     } else if (rank == 1) {
189         for (i = 0; i < reps; i++) {
190             if (reps == 1) {
191                 printf("1: receiving from process 0\n");
192                 fflush(stdout);
193             }
194             MPI_Recv(buffer, size, MPI_BYTE, 0, tag, MPI_COMM_WORLD, &status);
195             if (reps == 1) {
196                 printf("1: sending to process 0\n");
197                 fflush(stdout);
198             }
199             MPI_Send(buffer, size, MPI_BYTE, 0, tag, MPI_COMM_WORLD);
200             if (reps == 1) {
201                 printf("1: done\n");
202                 fflush(stdout);
203             }
204         }
205     }
206     free(buffer);
207 
208     return TRUE;
209 }
210 
main(int argc,char * argv[])211 int main(int argc, char *argv[])
212 {
213     int result;
214     int size, rank;
215     int bDoAll = FALSE;
216     int reps;
217     int rndv_size = DEFAULT_RNDV_SIZE;
218 
219     MPI_Init(&argc, &argv);
220     MPI_Comm_size(MPI_COMM_WORLD, &size);
221     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
222 
223     if (size < 2) {
224         printf("Two processes needed.\n");
225         printf("options:\n");
226         printf(" sr [reps] ............... send/recv\n");
227         printf(" isr ..................... isend/irecv\n");
228         printf(" iisr .................... isend,isend/irecv,irecv wait\n");
229         printf(" oo ...................... out of order isend/irecv\n");
230         printf(" unex .................... force unexpected msg\n");
231         printf(" rndv [size] ............. rndv\n");
232         printf(" rndv_reps [reps] [size] . rndv\n");
233         printf(" rndv_iisr [size] ........ rndv iisr\n");
234         printf(" rndv_oo [size] .......... rndv oo\n");
235         printf(" rndv_unex [size] ........ rndv unex\n");
236         printf("default rndv size = %d bytes\n", DEFAULT_RNDV_SIZE);
237         MPI_Finalize();
238         return 0;
239     }
240 
241     if (rank > 1) {
242         printf("Rank %d, I am not participating.\n", rank);
243         fflush(stdout);
244     } else {
245         if (argc < 2)
246             bDoAll = TRUE;
247 
248         if (bDoAll || (strcmp(argv[1], "sr") == 0)) {
249             reps = 1;
250             if (argc > 2) {
251                 reps = atoi(argv[2]);
252                 if (reps < 1)
253                     reps = 1;
254             }
255             if (rank == 0) {
256                 printf("Send/recv test: %d reps\n", reps);
257                 fflush(stdout);
258             }
259             result = SendRecvTest(rank, reps);
260             printf(result ? "%d:SUCCESS - sr\n" : "%d:FAILURE - sr\n", rank);
261             fflush(stdout);
262         }
263 
264         if (bDoAll || (strcmp(argv[1], "isr") == 0)) {
265             if (rank == 0) {
266                 printf("Isend/irecv wait test\n");
267                 fflush(stdout);
268             }
269             result = IsendIrecvTest(rank);
270             printf(result ? "%d:SUCCESS - isr\n" : "%d:FAILURE - isr\n", rank);
271             fflush(stdout);
272         }
273 
274         if (bDoAll || (strcmp(argv[1], "iisr") == 0)) {
275             if (rank == 0) {
276                 printf("Isend,isend/irecv,irecv wait wait test\n");
277                 fflush(stdout);
278             }
279             result = IsendIrecvTest2(rank, 100);
280             printf(result ? "%d:SUCCESS - iisr\n" : "%d:FAILURE - iisr\n", rank);
281             fflush(stdout);
282         }
283 
284         if (bDoAll || (strcmp(argv[1], "oo") == 0)) {
285             if (rank == 0) {
286                 printf("Out of order isend/irecv test\n");
287                 fflush(stdout);
288             }
289             result = OutOfOrderTest(rank, 100);
290             printf(result ? "%d:SUCCESS - oo\n" : "%d:FAILURE - oo\n", rank);
291             fflush(stdout);
292         }
293 
294         if (bDoAll || (strcmp(argv[1], "unex") == 0)) {
295             if (rank == 0) {
296                 printf("Force unexpected message test\n");
297                 fflush(stdout);
298             }
299             result = ForceUnexpectedTest(rank, 100);
300             printf(result ? "%d:SUCCESS - unex\n" : "%d:FAILURE - unex\n", rank);
301             fflush(stdout);
302         }
303 
304         if (bDoAll || (strcmp(argv[1], "rndv") == 0)) {
305             if (argc > 2) {
306                 rndv_size = atoi(argv[2]);
307                 if (rndv_size < 1024)
308                     rndv_size = 1024;
309             }
310             if (rank == 0) {
311                 printf("Rndv test\n");
312                 fflush(stdout);
313             }
314             result = RndvTest(rank, rndv_size, 1);
315             printf(result ? "%d:SUCCESS - rndv\n" : "%d:FAILURE - rndv\n", rank);
316             fflush(stdout);
317         }
318 
319         if (bDoAll || (strcmp(argv[1], "rndv_reps") == 0)) {
320             reps = 100;
321             if (argc > 2) {
322                 reps = atoi(argv[2]);
323                 if (reps < 1)
324                     reps = 1;
325             }
326             if (argc > 3) {
327                 rndv_size = atoi(argv[3]);
328             }
329             if (rank == 0) {
330                 printf("Rndv test: %d reps of size %d\n", reps, rndv_size);
331                 fflush(stdout);
332             }
333             result = RndvTest(rank, rndv_size, reps);
334             printf(result ? "%d:SUCCESS - rndv_reps\n" : "%d:FAILURE - rndv_reps\n", rank);
335             fflush(stdout);
336         }
337 
338         if (bDoAll || (strcmp(argv[1], "rndv_iisr") == 0)) {
339             if (rank == 0) {
340                 printf("Rndv isend,isend/irecv,irecv wait wait test\n");
341                 fflush(stdout);
342             }
343             if (argc > 2) {
344                 rndv_size = atoi(argv[2]);
345             }
346             result = IsendIrecvTest2(rank, rndv_size);
347             printf(result ? "%d:SUCCESS - rndv_iisr\n" : "%d:FAILURE - rndv_iisr\n", rank);
348             fflush(stdout);
349         }
350 
351         if (bDoAll || (strcmp(argv[1], "rndv_oo") == 0)) {
352             if (rank == 0) {
353                 printf("Rndv out of order isend/irecv test\n");
354                 fflush(stdout);
355             }
356             if (argc > 2) {
357                 rndv_size = atoi(argv[2]);
358             }
359             result = OutOfOrderTest(rank, rndv_size);
360             printf(result ? "%d:SUCCESS - rndv_oo\n" : "%d:FAILURE - rndv_oo\n", rank);
361             fflush(stdout);
362         }
363 
364         if (bDoAll || (strcmp(argv[1], "rndv_unex") == 0)) {
365             if (argc > 2) {
366                 rndv_size = atoi(argv[2]);
367                 if (rndv_size < 1024)
368                     rndv_size = 1024;
369             }
370             if (rank == 0) {
371                 printf("Force unexpected rndv message test\n");
372                 fflush(stdout);
373             }
374             result = ForceUnexpectedTest(rank, rndv_size);
375             printf(result ? "%d:SUCCESS - rndv_unex\n" : "%d:FAILURE - rndv_unex\n", rank);
376             fflush(stdout);
377         }
378     }
379 
380     MPI_Finalize();
381     return 0;
382 }
383