1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 #include <stdio.h>
7 #include "mpi.h"
8 #include "mpitest.h"
9 
10 #define MAX_BUF_SIZE_LG 22
11 #define NUM_MSGS_PER_BUF_SIZE 5
12 char buf[1 << MAX_BUF_SIZE_LG];
13 
14 /*
15  * This program verifies that MPI_Probe() is operating properly in the face of
16  * unexpected messages arriving after MPI_Probe() has
17  * been called.  This program may hang if MPI_Probe() does not return when the
18  * message finally arrives (see req #375).
19  */
main(int argc,char ** argv)20 int main(int argc, char **argv)
21 {
22     int p_size;
23     int p_rank;
24     int msg_size_lg;
25     int errs = 0;
26     int mpi_errno;
27 
28     MTest_Init(&argc, &argv);
29 
30     MPI_Comm_size(MPI_COMM_WORLD, &p_size);
31     MPI_Comm_rank(MPI_COMM_WORLD, &p_rank);
32     /* To improve reporting of problems about operations, we
33      * change the error handler to errors return */
34     MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
35 
36 
37     for (msg_size_lg = 0; msg_size_lg <= MAX_BUF_SIZE_LG; msg_size_lg++) {
38         const int msg_size = 1 << msg_size_lg;
39         int msg_cnt;
40 
41         MTestPrintfMsg(2, "testing messages of size %d\n", msg_size);
42         for (msg_cnt = 0; msg_cnt < NUM_MSGS_PER_BUF_SIZE; msg_cnt++) {
43             MPI_Status status;
44             const int tag = msg_size_lg * NUM_MSGS_PER_BUF_SIZE + msg_cnt;
45 
46             MTestPrintfMsg(2, "Message count %d\n", msg_cnt);
47             if (p_rank == 0) {
48                 int p;
49 
50                 for (p = 1; p < p_size; p++) {
51                     /* Wait for synchronization message */
52                     mpi_errno = MPI_Recv(NULL, 0, MPI_BYTE, MPI_ANY_SOURCE,
53                                          tag, MPI_COMM_WORLD, &status);
54                     if (mpi_errno != MPI_SUCCESS && errs++ < 10) {
55                         MTestPrintError(mpi_errno);
56                     }
57 
58                     if (status.MPI_TAG != tag && errs++ < 10) {
59                         printf
60                             ("ERROR: unexpected message tag from MPI_Recv(): lp=0, rp=%d, expected=%d, actual=%d, count=%d\n",
61                              status.MPI_SOURCE, status.MPI_TAG, tag, msg_cnt);
62                     }
63 #		    if defined(VERBOSE)
64                     {
65                         printf("sending message: p=%d s=%d c=%d\n",
66                                status.MPI_SOURCE, msg_size, msg_cnt);
67                     }
68 #		    endif
69 
70                     /* Send unexpected message which hopefully MPI_Probe() is
71                      * already waiting for at the remote process */
72                     mpi_errno = MPI_Send(buf, msg_size, MPI_BYTE,
73                                          status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD);
74                     if (mpi_errno != MPI_SUCCESS && errs++ < 10) {
75                         MTestPrintError(mpi_errno);
76                     }
77                 }
78             } else {
79                 int incoming_msg_size;
80 
81                 /* Send synchronization message */
82                 mpi_errno = MPI_Send(NULL, 0, MPI_BYTE, 0, tag, MPI_COMM_WORLD);
83                 if (mpi_errno != MPI_SUCCESS && errs++ < 10) {
84                     MTestPrintError(mpi_errno);
85                 }
86 
87                 /* Perform probe, hopefully before the main process can
88                  * send its reply */
89                 mpi_errno = MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
90                 if (mpi_errno != MPI_SUCCESS && errs++ < 10) {
91                     MTestPrintError(mpi_errno);
92                 }
93                 mpi_errno = MPI_Get_count(&status, MPI_BYTE, &incoming_msg_size);
94                 if (mpi_errno != MPI_SUCCESS && errs++ < 10) {
95                     MTestPrintError(mpi_errno);
96                 }
97                 if (status.MPI_SOURCE != 0 && errs++ < 10) {
98                     printf
99                         ("ERROR: unexpected message source from MPI_Probe(): p=%d, expected=0, actual=%d, count=%d\n",
100                          p_rank, status.MPI_SOURCE, msg_cnt);
101                 }
102                 if (status.MPI_TAG != tag && errs++ < 10) {
103                     printf
104                         ("ERROR: unexpected message tag from MPI_Probe(): p=%d, expected=%d, actual=%d, count=%d\n",
105                          p_rank, tag, status.MPI_TAG, msg_cnt);
106                 }
107                 if (incoming_msg_size != msg_size && errs++ < 10) {
108                     printf
109                         ("ERROR: unexpected message size from MPI_Probe(): p=%d, expected=%d, actual=%d, count=%d\n",
110                          p_rank, msg_size, incoming_msg_size, msg_cnt);
111                 }
112 
113                 /* Receive the probed message from the main process */
114                 mpi_errno = MPI_Recv(buf, msg_size, MPI_BYTE, 0, tag, MPI_COMM_WORLD, &status);
115                 if (mpi_errno != MPI_SUCCESS && errs++ < 10) {
116                     MTestPrintError(mpi_errno);
117                 }
118                 mpi_errno = MPI_Get_count(&status, MPI_BYTE, &incoming_msg_size);
119                 if (mpi_errno != MPI_SUCCESS && errs++ < 10) {
120                     MTestPrintError(mpi_errno);
121                 }
122                 if (status.MPI_SOURCE != 0 && errs++ < 10) {
123                     printf
124                         ("ERROR: unexpected message source from MPI_Recv(): p=%d, expected=0, actual=%d, count=%d\n",
125                          p_rank, status.MPI_SOURCE, msg_cnt);
126                 }
127                 if (status.MPI_TAG != tag && errs++ < 10) {
128                     printf
129                         ("ERROR: unexpected message tag from MPI_Recv(): p=%d, expected=%d, actual=%d, count=%d\n",
130                          p_rank, tag, status.MPI_TAG, msg_cnt);
131                 }
132                 if (incoming_msg_size != msg_size && errs++ < 10) {
133                     printf
134                         ("ERROR: unexpected message size from MPI_Recv(): p=%d, expected=%d, actual=%d, count=%d\n",
135                          p_rank, msg_size, incoming_msg_size, msg_cnt);
136                 }
137             }
138         }
139     }
140 
141     MTest_Finalize(errs);
142     return MTestReturnValue(errs);
143 }
144