2 * This file tests that message truncation errors are properly detected and
3 * handled (in particular, that data is NOT overwritten).
10 /* Prototypes for picky compilers */
11 int SetupRecvBuf ( int * );
12 int CheckRecvErr ( int, MPI_Status *, int *, const char * );
14 int main( int argc, char **argv )
18 MPI_Comm comm, dupcomm;
20 int partner, merr, flag;
23 int i, sendbuf[10], recvbuf[10];
25 MPI_Init( &argc, &argv );
26 MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
28 comm = MPI_COMM_WORLD;
29 MPI_Comm_dup( comm, &dupcomm );
30 MPI_Comm_rank( comm, &rank );
31 MPI_Comm_size( comm, &size );
33 /* We'll RECEIVE into rank 0, just to simplify any debugging. The tests are
35 send( count = 10 ) recv(count = 1)
38 wait recv(count=1) (unexpected recv)
41 send( count = 10) wait (expected/err trunc)
44 send( count = 10) test (expected/err trunc)
48 fprintf( stderr, "This test requires at least 2 processes\n" );
49 MPI_Abort( MPI_COMM_WORLD, 1 );
52 /* Only return on the RECEIVERS side */
53 MPI_Errhandler_set( comm, MPI_ERRORS_RETURN );
55 SetupRecvBuf( recvbuf );
56 merr = MPI_Recv( recvbuf, 1, MPI_INT, partner, 1, comm, &status );
57 err += CheckRecvErr( merr, &status, recvbuf, "Recv" );
58 MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 0,
59 MPI_BOTTOM, 0, MPI_INT, partner, 0,
62 SetupRecvBuf( recvbuf );
63 merr = MPI_Recv( recvbuf, 1, MPI_INT, partner, 2, comm, &status );
64 err += CheckRecvErr( merr, &status, recvbuf, "Unexpected Recv" );
66 SetupRecvBuf( recvbuf );
67 merr = MPI_Irecv( recvbuf, 1, MPI_INT, partner, 3, comm, &request );
69 MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 0,
70 MPI_BOTTOM, 0, MPI_INT, partner, 0,
72 merr = MPI_Wait( &request, &status );
73 err += CheckRecvErr( merr, &status, recvbuf, "Irecv/Wait" );
75 SetupRecvBuf( recvbuf );
76 merr = MPI_Irecv( recvbuf, 1, MPI_INT, partner, 4, comm, &request );
77 MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 0,
78 MPI_BOTTOM, 0, MPI_INT, partner, 0,
81 merr = MPI_Test( &request, &flag, &status );
82 } while (merr == 0 && flag == 0);
83 err += CheckRecvErr( merr, &status, recvbuf, "Irecv/Test" );
85 else if (rank == size - 1) {
89 MPI_Send( sendbuf, 10, MPI_INT, partner, 1, comm );
90 MPI_Isend( sendbuf, 10, MPI_INT, partner, 2, comm, &request );
91 MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 0,
92 MPI_BOTTOM, 0, MPI_INT, partner, 0,
94 MPI_Wait( &request, &status );
96 MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 0,
97 MPI_BOTTOM, 0, MPI_INT, partner, 0,
99 MPI_Send( sendbuf, 10, MPI_INT, partner, 3, comm );
100 MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 0,
101 MPI_BOTTOM, 0, MPI_INT, partner, 0,
103 MPI_Send( sendbuf, 10, MPI_INT, partner, 4, comm );
105 MPI_Comm_free( &dupcomm );
107 MPI_Allreduce( &err, &toterr, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
108 if (world_rank == 0) {
110 printf( " No Errors\n" );
112 printf( "Found %d errors in Truncated Message test\n", toterr );
118 int SetupRecvBuf( recvbuf )
127 int CheckRecvErr( merr, status, recvbuf, msg )
134 char buf[MPI_MAX_ERROR_STRING];
136 /* Get the MPI Error class from merr */
137 MPI_Error_class( merr, &class );
139 case MPI_ERR_TRUNCATE:
140 /* Check that data buf is ok */
141 if (recvbuf[1] != 2) {
144 "Receive buffer overwritten! Found %d in 2nd pos.\n",
149 case MPI_ERR_IN_STATUS:
150 /* Check for correct message */
151 /* ERR IN STATUS is correct ONLY for multiple completion routines */
152 /* if (status->MPI_ERROR == MPI_ERR_TRUNCATE)
154 /* Else, fall through into default... */
156 /* Wrong error; get message and print */
157 MPI_Error_string( merr, buf, &rlen );
159 "Got unexpected error message from %s: %s\n", msg, buf );