Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Remove declarations for nonexistent functions or variables.
[simgrid.git] / teshsuite / smpi / mpich-test / pt2pt / overtake.c
1 /*
2  * Program to test that the "no overtaking messages" semantics
3  * of point to point communications in MPI is satisfied. 
4  * A long message is sent using MPI_Send and received using MPI_Recv,
5  * followed by lots of short messages sent the same way.
6  * Then Send -> Irecv, Bsend -> Recv, Bsend -> Irecv, 
7  * Isend -> Recv, and Isend -> Irecv are all tried in the
8  * same way.
9  *
10  *                              Patrick Bridges
11  *                              bridges@mcs.anl.gov
12  *                              patrick@CS.MsState.Edu
13  */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include "test.h"
18 #include "mpi.h"
19
20 #define SIZE 10000
21
22 static int src  = 0;
23 static int dest = 1;
24
25 /* Which tests to perform (not yet implemented) */
26 /* static int Do_Buffer = 1; */
27 /* static int Do_Standard = 1; */
28 /* In order to quiet noisy C compilers, we provide ANSI-style prototypes
29    where possible */
30 void Generate_Data ( double *, int );
31 void Normal_Test_Send ( double *, int );
32 void Normal_Test_Recv ( double *, int );
33 void Buffered_Test_Send ( double *, int );
34 /* void Buffered_Test_Recv ( double *, int ); */
35 void Async_Test_Send ( double *, int );
36 void Async_Test_Recv ( double *, int );
37 int Check_Data ( double *, int );
38 void Clear_Buffer ( double *, int );
39
40
41 void Generate_Data(buffer, buff_size)
42 double *buffer;
43 int buff_size;
44 {
45     int i;
46
47     for (i = 0; i < buff_size; i++)
48         buffer[i] = (double)i+1;
49 }
50
51 void Normal_Test_Send(buffer, buff_size)
52 double *buffer;
53 int buff_size;
54 {
55     int i, j;
56
57     for (j = 0; j < 2; j++) {
58         /* send a long message */
59         MPI_Send(buffer, (buff_size/2 - 10), MPI_DOUBLE, dest, 2000, 
60                  MPI_COMM_WORLD);
61         buffer += buff_size/2 - 10;
62         /* Followed by 10 short ones */
63         for (i = 0; i < 10; i++)
64             MPI_Send(buffer++, 1, MPI_DOUBLE, dest, 2000, MPI_COMM_WORLD);
65     }
66 }
67
68 void Normal_Test_Recv(buffer, buff_size)
69 double *buffer;
70 int buff_size;
71 {
72     int i, j;
73     MPI_Status Stat;
74
75     for (j = 0; j < 2; j++) {
76         /* Receive a long message */
77         MPI_Recv(buffer, (buff_size/2 - 10), MPI_DOUBLE, src, 
78                  2000, MPI_COMM_WORLD, &Stat);
79         buffer += buff_size/2 - 10;
80         /* Followed by 10 short ones */
81         for (i = 0; i < 10; i++)
82             MPI_Recv(buffer++, 1, MPI_DOUBLE, src, 2000, MPI_COMM_WORLD, &Stat);
83     }
84 }
85
86 void Buffered_Test_Send(buffer, buff_size)
87 double *buffer;
88 int buff_size;
89 {
90     int i, j;
91     void *bbuffer;
92     int size;
93
94     for (j = 0; j < 2; j++) {
95         /* send a long message */
96         MPI_Bsend(buffer, (buff_size/2 - 10), MPI_DOUBLE, dest, 2000, 
97                  MPI_COMM_WORLD);
98         buffer += buff_size/2 - 10;
99         /* Followed by 10 short ones */
100         for (i = 0; i < 10; i++)
101             MPI_Bsend(buffer++, 1, MPI_DOUBLE, 
102                       dest, 2000, MPI_COMM_WORLD);
103         /* Force this set of Bsends to complete */
104         MPI_Buffer_detach( &bbuffer, &size );
105         MPI_Buffer_attach( bbuffer, size );
106     }
107 }
108
109 void Async_Test_Send(buffer, buff_size)
110 double *buffer;
111 int buff_size;
112 {
113     int i, j, req = 0;
114     MPI_Status Stat[22];
115     MPI_Request Hand[22];
116
117     for (j = 0; j < 2; j++) {
118         /* send a long message */
119         MPI_Isend(buffer, (buff_size/2 - 10), MPI_DOUBLE, 
120                   dest, 2000, MPI_COMM_WORLD, &(Hand[req++]));
121         buffer += buff_size/2 - 10;
122         /* Followed by 10 short ones */
123         for (i = 0; i < 10; i++)
124             MPI_Isend(buffer++, 1, MPI_DOUBLE, dest, 2000, 
125                       MPI_COMM_WORLD, &(Hand[req++]));
126     }
127     MPI_Waitall(req, Hand, Stat);
128 }
129
130 void Async_Test_Recv(buffer, buff_size)
131 double *buffer;
132 int buff_size;
133 {
134     int i, j, req = 0;
135     MPI_Status Stat[22];
136     MPI_Request Hand[22];
137     
138     for (j = 0; j < 2; j++) {
139         /* Receive a long message */
140         MPI_Irecv(buffer, (buff_size/2 - 10), MPI_DOUBLE, src, 
141                  2000, MPI_COMM_WORLD, &(Hand[req++]));
142         buffer += buff_size/2 - 10;
143         /* Followed by 10 short ones */
144         for (i = 0; i < 10; i++)
145             MPI_Irecv(buffer++, 1, MPI_DOUBLE, src, 2000, 
146                       MPI_COMM_WORLD, &(Hand[req++]));
147     }
148     MPI_Waitall(req, Hand, Stat);
149 }
150
151 int Check_Data(buffer, buff_size)
152 double *buffer;
153 int buff_size;
154 {
155     int i;
156     int err = 0;
157
158     for (i = 0; i < buff_size; i++)
159         if (buffer[i] != (i + 1)) {
160             err++;
161             fprintf( stderr, "Value at %d is %f, should be %f\n", i, 
162                     buffer[i], (double)(i+1) );
163             if (err > 10) return 1;
164             }
165     return err;
166 }
167
168 void Clear_Buffer(buffer, buff_size)
169 double *buffer;
170 int buff_size;
171 {
172     int i;
173     for (i = 0; i < buff_size; i++)
174         buffer[i] = -1;
175 }
176
177
178 int main( int argc, char **argv )
179 {
180     int rank; /* My Rank (0 or 1) */
181     double buffer[SIZE], *tmpbuffer, *tmpbuf;
182     int tsize, bsize;
183     char *Current_Test = NULL;
184
185     MPI_Init(&argc, &argv);
186     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
187
188     if (rank == src) { 
189         Generate_Data(buffer, SIZE);
190         Normal_Test_Send(buffer, SIZE);
191         Normal_Test_Send(buffer, SIZE);
192 #if !defined(SIMPLE_SENDS) && !defined(NO_BUFFERED_SENDS)
193         MPI_Pack_size( SIZE, MPI_DOUBLE, MPI_COMM_WORLD, &bsize );
194         tmpbuffer = (double *) malloc( bsize + MPI_BSEND_OVERHEAD );
195         if (!tmpbuffer) {
196             fprintf( stderr, "Could not allocate bsend buffer of size %d\n",
197                      bsize );
198             MPI_Abort( MPI_COMM_WORLD, 1 );
199             }
200         MPI_Buffer_attach( tmpbuffer, bsize + MPI_BSEND_OVERHEAD );
201         Buffered_Test_Send(buffer, SIZE);
202         Buffered_Test_Send(buffer, SIZE);
203         MPI_Buffer_detach( &tmpbuf, &tsize );
204 #endif
205 #if !defined(SIMPLE_SENDS) && !defined(NO_ASYNC_SENDS)
206         Async_Test_Send(buffer, SIZE);
207         Async_Test_Send(buffer, SIZE);
208 #endif
209         Test_Waitforall( );
210
211     } else if (rank == dest) {
212         Test_Init("overtake", rank);
213         /* Test 1 */
214         Current_Test = (char*)"Overtaking Test (Normal Send   -> Normal Recieve)";
215         Normal_Test_Recv(buffer, SIZE);
216
217         if (Check_Data(buffer, SIZE))
218             Test_Failed(Current_Test);
219         else
220             Test_Passed(Current_Test);
221
222         /* Test 2 */
223         Clear_Buffer(buffer, SIZE);
224         Current_Test = (char*)"Overtaking Test (Normal Send   ->  Async Receive)";
225         Async_Test_Recv(buffer, SIZE);
226         if (Check_Data(buffer, SIZE))
227             Test_Failed(Current_Test);
228         else
229             Test_Passed(Current_Test);
230
231 #if !defined(SIMPLE_SENDS) && !defined(NO_BUFFERED_SENDS)
232         /* Test 3 */
233         Current_Test = (char*)"Overtaking Test (Buffered Send -> Normal Recieve)";
234         Clear_Buffer(buffer, SIZE);
235         Normal_Test_Recv(buffer, SIZE);
236
237         if (Check_Data(buffer, SIZE))
238             Test_Failed(Current_Test);
239         else
240             Test_Passed(Current_Test);
241
242         /* Test 4 */
243         Clear_Buffer(buffer, SIZE);
244         Current_Test = (char*)"Overtaking Test (Buffered Send ->  Async Receive)";
245         Async_Test_Recv(buffer, SIZE);
246         if (Check_Data(buffer, SIZE))
247             Test_Failed(Current_Test);
248         else
249             Test_Passed(Current_Test);
250 #endif
251
252 #if !defined(SIMPLE_SENDS) && !defined(NO_ASYNC_SENDS)
253         /* Test 5 */
254         Current_Test = (char*)"Overtaking Test (Async Send    -> Normal Receive)";
255         Clear_Buffer(buffer, SIZE);
256         Normal_Test_Recv(buffer, SIZE);
257         if (Check_Data(buffer, SIZE))
258             Test_Failed(Current_Test);
259         else
260             Test_Passed(Current_Test);
261
262             /* Test 6 */
263         Clear_Buffer(buffer, SIZE);
264         Current_Test = (char*)"Overtaking Test (Async Send    ->  Async Receive)";
265         Async_Test_Recv(buffer, SIZE);
266         if (Check_Data(buffer, SIZE))
267             Test_Failed(Current_Test);
268         else
269             Test_Passed(Current_Test);
270 #endif
271
272         Test_Waitforall( );
273         {
274             int rval = Summarize_Test_Results(); /* Returns number of tests;
275                                                     that failed */
276             Test_Finalize();
277             MPI_Finalize();
278             return rval;
279         }
280     } else {
281         fprintf(stderr, "*** This program uses exactly 2 processes! ***\n");
282         MPI_Abort( MPI_COMM_WORLD, 1 );
283     }
284
285     MPI_Finalize();
286     return 0;
287 }
288
289
290