Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
handle nested datatypes in smpi (structs of vectors for example), which previously...
[simgrid.git] / teshsuite / smpi / mpich-test / pt2pt / trunc.c
1 /*
2  * This file tests that message truncation errors are properly detected and
3  * handled (in particular, that data is NOT overwritten).
4  */
5
6 #include "mpi.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "test.h"
10 /* Prototypes for picky compilers */
11 int SetupRecvBuf ( int * );
12 int CheckRecvErr ( int, MPI_Status *, int *, const char * );
13
14 int main( int argc, char **argv )
15 {
16     int         err = 0, toterr;
17     int         world_rank;
18     MPI_Comm    comm, dupcomm;
19     int         rank, size;
20     int         partner, merr, flag;
21     MPI_Status  status;
22     MPI_Request request;
23     int         i, sendbuf[10], recvbuf[10];
24
25     MPI_Init( &argc, &argv );
26     MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
27
28     comm = MPI_COMM_WORLD;
29     MPI_Comm_dup( comm, &dupcomm );
30     MPI_Comm_rank( comm, &rank );
31     MPI_Comm_size( comm, &size );
32
33 /* We'll RECEIVE into rank 0, just to simplify any debugging.  The tests are
34    sender                                     receiver
35    send( count = 10 )                         recv(count = 1)
36    isend( count = 10 )
37    sendrecv                                   sendrecv
38    wait                                       recv(count=1) (unexpected recv)
39                                               irecv( count = 1)
40    sendrecv                                   sendrecv               
41    send( count = 10)                          wait (expected/err trunc)
42                                               irecv( count = 1)
43    sendrecv                                   sendrecv
44    send( count = 10)                          test (expected/err trunc)
45  */
46    
47     if (size < 2) {
48         fprintf( stderr, "This test requires at least 2 processes\n" );
49         MPI_Abort( MPI_COMM_WORLD, 1 );
50     }
51     if (rank == 0) {
52         /* Only return on the RECEIVERS side */
53         MPI_Errhandler_set( comm, MPI_ERRORS_RETURN );
54         partner = size - 1;
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,
60                       dupcomm, &status );
61
62         SetupRecvBuf( recvbuf );
63         merr = MPI_Recv( recvbuf, 1, MPI_INT, partner, 2, comm, &status );
64         err += CheckRecvErr( merr, &status, recvbuf, "Unexpected Recv" );
65
66         SetupRecvBuf( recvbuf );
67         merr = MPI_Irecv( recvbuf, 1, MPI_INT, partner, 3, comm, &request );
68     
69         MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 0,
70                       MPI_BOTTOM, 0, MPI_INT, partner, 0,
71                       dupcomm, &status );
72         merr = MPI_Wait( &request, &status );
73         err += CheckRecvErr( merr, &status, recvbuf, "Irecv/Wait" );
74
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,
79                       dupcomm, &status );
80         do { 
81             merr = MPI_Test( &request, &flag, &status );
82         } while (merr == 0 && flag == 0);
83         err += CheckRecvErr( merr, &status, recvbuf, "Irecv/Test" );
84     }
85     else if (rank == size - 1) {
86         partner = 0;
87         for (i=0; i<10; i++) 
88             sendbuf[i] = 100 + i;
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,
93                       dupcomm, &status );
94         MPI_Wait( &request, &status );
95
96         MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, partner, 0,
97                       MPI_BOTTOM, 0, MPI_INT, partner, 0,
98                       dupcomm, &status );
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,
102                       dupcomm, &status );
103         MPI_Send( sendbuf, 10, MPI_INT, partner, 4, comm );
104     }
105     MPI_Comm_free( &dupcomm );
106
107     MPI_Allreduce( &err, &toterr, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
108     if (world_rank == 0) {
109         if (toterr == 0) 
110             printf( " No Errors\n" );
111         else
112             printf( "Found %d errors in Truncated Message test\n", toterr );
113     }
114     MPI_Finalize( );
115     return toterr;
116 }
117
118 int SetupRecvBuf( recvbuf )
119 int *recvbuf;
120 {
121     int i;
122     for (i=0; i<10; i++) 
123         recvbuf[i] = i+1;
124     return 0;
125 }
126
127 int CheckRecvErr( merr, status, recvbuf, msg )
128 int        merr, *recvbuf;
129 MPI_Status *status;
130 const char       *msg;
131 {
132     int  class;
133     int  err = 0, rlen;
134     char buf[MPI_MAX_ERROR_STRING];
135
136 /* Get the MPI Error class from merr */
137     MPI_Error_class( merr, &class );
138     switch (class) {
139     case MPI_ERR_TRUNCATE:
140         /* Check that data buf is ok */
141         if (recvbuf[1] != 2) {
142             err++;
143             fprintf( stderr, 
144                      "Receive buffer overwritten!  Found %d in 2nd pos.\n",
145                      recvbuf[1] );
146         }
147         break;
148
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) 
153             break; */
154         /* Else, fall through into default... */
155     default:
156         /* Wrong error; get message and print */
157         MPI_Error_string( merr, buf, &rlen );
158         fprintf( stderr, 
159                  "Got unexpected error message from %s: %s\n", msg, buf );
160         err++;
161     }
162     return err;
163 }