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