Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
remove few tests which may never finish, and change one that used too much stack...
[simgrid.git] / teshsuite / smpi / mpich-test / pt2pt / isndrcv.c
1 /* 
2  * Program to test all of the features of MPI_Send and MPI_Recv
3  *
4  * *** What is tested? ***
5  * 1. Sending and receiving all basic types and many sizes - check
6  * 2. Tag selectivity - check
7  * 3. Error return codes for
8  *    a. Invalid Communicator
9  *    b. Invalid destination or source
10  *    c. Count out of range
11  *    d. Invalid type
12  */
13
14 #include "test.h"
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include "mpi.h"
19
20 #ifdef HAVE_MPICHCONF_H
21 #include "mpichconf.h"
22 #endif
23
24 static int src = 1;
25 static int dest = 0;
26
27 static int verbose = 0;
28
29 #define MAX_TYPES 12
30 static MPI_Datatype BasicTypes[MAX_TYPES];
31 #if defined(HAVE_LONG_DOUBLE) && (!defined HAS_XDR)
32 static int ntypes = 12;
33 #else
34 static int ntypes = 11;
35 #endif
36
37 static int maxbufferlen = 10000;
38 static int stdbufferlen = 300;
39
40 /* Prototypes to keep compilers quiet */
41 void AllocateBuffers ( void **, MPI_Datatype *, int, int );
42 void FreeBuffers ( void **, int );
43 void FillBuffers ( void **, MPI_Datatype *, int, int );
44 int CheckBuffer ( void *, MPI_Datatype, int );
45 void SetupBasicTypes (void);
46 void SenderTest1 (void);
47 void ReceiverTest1 (void);
48 void SenderTest2 (void);
49 void ReceiverTest2 (void);
50 void SenderTest3 (void);
51 void ReceiverTest3 (void);
52
53 void 
54 AllocateBuffers(void **bufferspace, MPI_Datatype *buffertypes, int num_types, 
55                 int bufferlen)
56 {
57     int i;
58     for (i = 0; i < ntypes; i++) {
59         if (buffertypes[i] == MPI_CHAR)
60             bufferspace[i] = malloc(bufferlen * sizeof(char));
61         else if (buffertypes[i] == MPI_SHORT)
62             bufferspace[i] = malloc(bufferlen * sizeof(short));
63         else if (buffertypes[i] == MPI_INT)
64             bufferspace[i] = malloc(bufferlen * sizeof(int));
65         else if (buffertypes[i] == MPI_LONG)
66             bufferspace[i] = malloc(bufferlen * sizeof(long));
67         else if (buffertypes[i] == MPI_UNSIGNED_CHAR)
68             bufferspace[i] = malloc(bufferlen * sizeof(unsigned char));
69         else if (buffertypes[i] == MPI_UNSIGNED_SHORT)
70             bufferspace[i] = malloc(bufferlen * sizeof(unsigned short));
71         else if (buffertypes[i] == MPI_UNSIGNED)
72             bufferspace[i] = malloc(bufferlen * sizeof(unsigned int));
73         else if (buffertypes[i] == MPI_UNSIGNED_LONG)
74             bufferspace[i] = malloc(bufferlen * sizeof(unsigned long));
75         else if (buffertypes[i] == MPI_FLOAT)
76             bufferspace[i] = malloc(bufferlen * sizeof(float));
77         else if (buffertypes[i] == MPI_DOUBLE)
78             bufferspace[i] = malloc(bufferlen * sizeof(double));
79 #if defined(HAVE_LONG_DOUBLE)  && (!defined HAS_XDR)
80         else if (MPI_LONG_DOUBLE && buffertypes[i] == MPI_LONG_DOUBLE) {
81             int dlen;
82             MPI_Type_size( MPI_LONG_DOUBLE, &dlen );
83             bufferspace[i] = malloc(bufferlen * dlen);
84         }
85 #endif
86         else if (buffertypes[i] == MPI_BYTE)
87             bufferspace[i] = malloc(bufferlen * sizeof(unsigned char));
88     }
89 }
90
91 void 
92 FreeBuffers(void **buffers, int nbuffers)
93 {
94     int i;
95     for (i = 0; i < nbuffers; i++)
96         free(buffers[i]);
97 }
98
99 void 
100 FillBuffers(void **bufferspace, MPI_Datatype *buffertypes, int num_types, 
101             int bufferlen)
102 {
103     int i, j;
104     for (i = 0; i < ntypes; i++) {
105         for (j = 0; j < bufferlen; j++) {
106             if (buffertypes[i] == MPI_CHAR)
107                 ((char *)bufferspace[i])[j] = (char)(j & 0x7f);
108             else if (buffertypes[i] == MPI_SHORT)
109                 ((short *)bufferspace[i])[j] = (short)j;
110             else if (buffertypes[i] == MPI_INT)
111                 ((int *)bufferspace[i])[j] = (int)j;
112             else if (buffertypes[i] == MPI_LONG)
113                 ((long *)bufferspace[i])[j] = (long)j;
114             else if (buffertypes[i] == MPI_UNSIGNED_CHAR)
115                 ((unsigned char *)bufferspace[i])[j] = (unsigned char)j;
116             else if (buffertypes[i] == MPI_UNSIGNED_SHORT)
117                 ((unsigned short *)bufferspace[i])[j] = (unsigned short)j;
118             else if (buffertypes[i] == MPI_UNSIGNED)
119                 ((unsigned int *)bufferspace[i])[j] = (unsigned int)j;
120             else if (buffertypes[i] == MPI_UNSIGNED_LONG)
121                 ((unsigned long *)bufferspace[i])[j] = (unsigned long)j;
122             else if (buffertypes[i] == MPI_FLOAT)
123                 ((float *)bufferspace[i])[j] = (float)j;
124             else if (buffertypes[i] == MPI_DOUBLE)
125                 ((double *)bufferspace[i])[j] = (double)j;
126 #if defined(HAVE_LONG_DOUBLE)  && (!defined HAS_XDR)
127             else if (MPI_LONG_DOUBLE && buffertypes[i] == MPI_LONG_DOUBLE)
128                 ((long double *)bufferspace[i])[j] = (long double)j;
129 #endif
130             else if (buffertypes[i] == MPI_BYTE)
131                 ((unsigned char *)bufferspace[i])[j] = (unsigned char)j;
132         }
133     }
134 }
135
136 int
137 CheckBuffer(bufferspace, buffertype, bufferlen)
138 void *bufferspace; 
139 MPI_Datatype buffertype; 
140 int bufferlen;
141 {
142     int j;
143     for (j = 0; j < bufferlen; j++) {
144         if (buffertype == MPI_CHAR) {
145             if (((char *)bufferspace)[j] != (char)(j & 0x7f))
146                 return 1;
147         } else if (buffertype == MPI_SHORT) {
148             if (((short *)bufferspace)[j] != (short)j)
149                 return 1;
150         } else if (buffertype == MPI_INT) {
151             if (((int *)bufferspace)[j] != (int)j)
152                 return 1;
153         } else if (buffertype == MPI_LONG) {
154             if (((long *)bufferspace)[j] != (long)j)
155                 return 1;
156         } else if (buffertype == MPI_UNSIGNED_CHAR) {
157             if (((unsigned char *)bufferspace)[j] != (unsigned char)j)
158                 return 1;
159         } else if (buffertype == MPI_UNSIGNED_SHORT) {
160             if (((unsigned short *)bufferspace)[j] != (unsigned short)j)
161                 return 1;
162         } else if (buffertype == MPI_UNSIGNED) {
163             if (((unsigned int *)bufferspace)[j] != (unsigned int)j)
164                 return 1;
165         } else if (buffertype == MPI_UNSIGNED_LONG) {
166             if (((unsigned long *)bufferspace)[j] != (unsigned long)j)
167                 return 1;
168         } else if (buffertype == MPI_FLOAT) {
169             if (((float *)bufferspace)[j] != (float)j)
170                 return 1;
171         } else if (buffertype == MPI_DOUBLE) {
172             if (((double *)bufferspace)[j] != (double)j)
173                 return 1;
174 #if defined(HAVE_LONG_DOUBLE)  && (!defined HAS_XDR)
175         } else if (MPI_LONG_DOUBLE && buffertype == MPI_LONG_DOUBLE) {
176             if (((long double *)bufferspace)[j] != (long double)j)
177                 return 1;
178 #endif
179         } else if (buffertype == MPI_BYTE) {
180             if (((unsigned char *)bufferspace)[j] != (unsigned char)j)
181                 return 1;
182         }
183     }
184     return 0;
185 }
186
187 void SetupBasicTypes( void )
188 {
189     BasicTypes[0] = MPI_CHAR;
190     BasicTypes[1] = MPI_SHORT;
191     BasicTypes[2] = MPI_INT;
192     BasicTypes[3] = MPI_LONG;
193     BasicTypes[4] = MPI_UNSIGNED_CHAR;
194     BasicTypes[5] = MPI_UNSIGNED_SHORT;
195     BasicTypes[6] = MPI_UNSIGNED;
196     BasicTypes[7] = MPI_UNSIGNED_LONG;
197     BasicTypes[8] = MPI_FLOAT;
198     BasicTypes[9] = MPI_DOUBLE;
199
200     /* Define the last few elements as null just in case */
201     BasicTypes[11] = MPI_DATATYPE_NULL;
202 #if defined (HAVE_LONG_DOUBLE) && (!defined HAS_XDR)
203     if (MPI_LONG_DOUBLE) {
204         BasicTypes[10] = MPI_LONG_DOUBLE;
205         BasicTypes[11] = MPI_BYTE;
206         }
207     else {
208         ntypes = 11;
209         BasicTypes[10] = MPI_BYTE;
210         }
211 #else
212     BasicTypes[10] = MPI_BYTE;
213 #endif
214 }
215
216 void 
217 SenderTest1( void )
218 {
219     void *bufferspace[MAX_TYPES];
220     int i, j;
221     int act_send;
222     MPI_Request *requests = 
223         (MPI_Request *)malloc(sizeof(MPI_Request) * ntypes * 
224                               maxbufferlen/500);
225     MPI_Status *statuses = 
226         (MPI_Status *)malloc(sizeof(MPI_Status) * ntypes * 
227                              maxbufferlen/500);
228
229     AllocateBuffers(bufferspace, BasicTypes, ntypes, maxbufferlen);
230     FillBuffers(bufferspace, BasicTypes, ntypes, maxbufferlen);
231     act_send = 0;
232     for (i = 0; i < ntypes; i++) {
233         for (j = 0; j < maxbufferlen; j += 500) {
234             if (BasicTypes[i] == MPI_DATATYPE_NULL) continue;
235             MPI_Isend(bufferspace[i], j, BasicTypes[i], dest, 
236                       2000, MPI_COMM_WORLD, 
237                       &(requests[act_send++]));
238             }
239     }
240     MPI_Waitall( act_send, requests, statuses);
241     free(requests);
242     free(statuses);
243     FreeBuffers(bufferspace, ntypes);
244 }
245
246 void
247 ReceiverTest1( void )
248 {
249     void *bufferspace[MAX_TYPES];
250     int i, j;
251     char message[81];
252     MPI_Status Stat;
253     MPI_Request Req;
254     int dummy, passed;
255
256     AllocateBuffers(bufferspace, BasicTypes, ntypes, maxbufferlen);
257     for (i = 0; i < ntypes; i++) {
258         passed = 1;
259         /* Try different sized messages */
260         for (j = 0; j < maxbufferlen; j += 500) {
261             /* Skip null datatypes */
262             if (!BasicTypes[i]) continue;
263             MPI_Irecv(bufferspace[i], j, BasicTypes[i], src, 
264                      2000, MPI_COMM_WORLD, &Req);
265             sprintf(message, "Send-Receive Test, Type %d, Count %d",
266                     i, j);
267             MPI_Wait(&Req, &Stat);
268             if (Stat.MPI_SOURCE != src) {
269                 fprintf(stderr, "*** Incorrect Source returned. ***\n");
270                 Test_Failed(message);
271                 passed = 0;
272             } else if (Stat.MPI_TAG != 2000) {  
273                 fprintf(stderr, "*** Incorrect Tag returned. ***\n");       
274                 Test_Failed(message);
275                 passed = 0;
276             } else if (MPI_Get_count(&Stat, BasicTypes[i], &dummy) ||
277                        dummy != j) {
278                 fprintf(stderr, 
279                         "*** Incorrect Count returned, Count = %d. ***\n", 
280                         dummy);
281                 Test_Failed(message);
282                 passed = 0;
283             } else if(CheckBuffer(bufferspace[i], BasicTypes[i], j)) {
284                 fprintf(stderr, "*** Incorrect Message received. ***\n");
285                 Test_Failed(message);
286                 passed = 0;
287             } 
288         }
289         sprintf(message, "Send-Receive Test, Type %d",
290                 i);
291         if (passed) 
292             Test_Passed(message);
293         else 
294             Test_Failed(message);
295     }
296     FreeBuffers(bufferspace, ntypes);
297 }
298
299 /* Test Tag Selectivity */
300 void 
301 SenderTest2( void )
302 {
303     int *buffer;
304     int i;
305     MPI_Request requests[10];
306     MPI_Status statuses[10];
307
308     buffer = (int *)malloc(stdbufferlen * sizeof(int));
309
310     for (i = 0; i < stdbufferlen; i++)
311         buffer[i] = i;
312     
313     for (i = 1; i <= 10; i++)
314         MPI_Isend(buffer, stdbufferlen, MPI_INT, dest,
315                  2000+i, MPI_COMM_WORLD, &(requests[i-1]));
316     MPI_Waitall(10, requests, statuses);
317     free(buffer);
318     
319     return;
320 }
321
322 void
323 ReceiverTest2( void )
324 {
325     int *buffer;
326     int i, j;
327     char message[81];
328     MPI_Status Stat;
329     int dummy, passed;
330
331     MPI_Request Req;
332
333     buffer = (int *)malloc(stdbufferlen * sizeof(int));
334     passed = 1;
335
336     for (i = 2010; i >= 2001; i--) {
337         MPI_Irecv(buffer, stdbufferlen, MPI_INT, src, 
338                  i, MPI_COMM_WORLD, &Req);
339         sprintf(message, "Tag Selectivity Test, Tag %d",
340                 i);
341         MPI_Wait(&Req, &Stat);
342         if (Stat.MPI_SOURCE != src) {
343             fprintf(stderr, "*** Incorrect Source returned. ***\n");
344             Test_Failed(message);
345         } else if (Stat.MPI_TAG != i) { 
346             fprintf(stderr, "*** Incorrect Tag returned. ***\n");           
347             Test_Failed(message);
348         } else if (MPI_Get_count(&Stat, MPI_INT, &dummy) ||
349                    dummy != stdbufferlen) {
350             fprintf(stderr, 
351                     "*** Incorrect Count returned, Count = %d. ***\n", 
352                     dummy);
353             Test_Failed(message);
354         } else if(CheckBuffer( (void *)buffer, MPI_INT, stdbufferlen)) {
355             fprintf(stderr, "*** Incorrect Message received. ***\n");
356             Test_Failed(message);
357             passed = 0;
358         }
359         /* Clear out the buffer */
360         for (j = 0; j < stdbufferlen; j++)
361             buffer[j] = -1;
362     }
363     strncpy(message, "Tag Selectivity Test", 81);
364     if (passed)
365         Test_Passed(message);
366     else
367         Test_Failed(message);
368     free(buffer);
369     return;
370 }
371
372 void
373 SenderTest3( void )
374 {
375     return;
376 }
377
378 void
379 ReceiverTest3( void )
380 {
381     int buffer[20];
382     MPI_Datatype bogus_type = MPI_DATATYPE_NULL;
383     MPI_Request Req;
384 #if 0
385     MPI_Status Stat;
386     int err_code;
387 #endif
388     if (verbose)
389         MPI_Errhandler_set(MPI_COMM_WORLD, TEST_ERRORS_WARN);
390     else
391         MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
392
393     if (MPI_Isend(buffer, 20, MPI_INT, dest,
394                  1, MPI_COMM_NULL, &Req) == MPI_SUCCESS){
395         Test_Failed("NULL Communicator Test");
396     }
397     else {
398         Test_Passed("NULL Communicator Test");
399 #if 0
400         /* If test passed (i.e. send failed, try waiting on the
401            request... */
402         Test_Message("About to wait on failed request.");
403         if (MPI_Wait(&Req, &Stat) == MPI_SUCCESS) {;
404             Test_Failed("Wait on failed isend Test");
405         }
406         else 
407             Test_Passed("Wait on failed isend Test");
408         Test_Message("Done waiting on failed request.");
409 #endif
410     }
411 /*
412     if (MPI_Isend(NULL, 10, MPI_INT, dest,
413                  1, MPI_COMM_WORLD, &Req) == MPI_SUCCESS){
414         Test_Failed("Invalid Buffer Test");
415     }
416     else
417         Test_Passed("Invalid Buffer Test");
418 */
419    if (MPI_Isend(buffer, -1, MPI_INT, dest,
420                  1, MPI_COMM_WORLD, &Req) == MPI_SUCCESS){
421         Test_Failed("Invalid Count Test");
422     }
423     else
424         Test_Passed("Invalid Count Test");
425
426    if (MPI_Isend(buffer, 20, bogus_type, dest,
427                  1, MPI_COMM_WORLD, &Req) == MPI_SUCCESS){
428         Test_Failed("Invalid Type Test");
429     }
430     else
431         Test_Passed("Invalid Type Test");
432
433    if (MPI_Isend(buffer, 20, MPI_INT, dest, 
434                  -1000, MPI_COMM_WORLD, &Req) == MPI_SUCCESS) {
435         Test_Failed("Invalid Tag Test");
436     }
437     else
438         Test_Passed("Invalid Tag Test");
439
440    if (MPI_Isend(buffer, 20, MPI_INT, 300,
441                  1, MPI_COMM_WORLD, &Req) == MPI_SUCCESS) {
442         Test_Failed("Invalid Destination Test");
443     }
444     else
445         Test_Passed("Invalid Destination Test");
446     return;
447 }
448
449 int 
450 main( int argc, char **argv )
451 {
452     int myrank, mysize;
453
454     MPI_Init(&argc, &argv);
455     MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
456     MPI_Comm_size(MPI_COMM_WORLD, &mysize);
457
458     /* dest writes out the received stats; for the output to be
459        consistant (with the final check), it should be procees 0 */
460     if (argc > 1 && argv[1] && strcmp( "-alt", argv[1] ) == 0) {
461         dest = 1;
462         src  = 0;
463         }
464     else {
465         src  = 1;
466         dest = 0;
467         }
468
469     Test_Init("isndrcv", myrank);
470     SetupBasicTypes();
471
472     if (mysize != 2) {
473         fprintf(stderr, 
474                 "*** This test program requires exactly 2 processes.\n");
475         MPI_Abort( MPI_COMM_WORLD, 1 );
476     }
477     
478     /* Turn stdout's buffering to line buffered so it mixes right with
479        stderr in output files. (hopefully) */
480     setvbuf(stdout, NULL, _IOLBF, 0);
481
482     if (myrank == src) {
483         SenderTest1();
484         SenderTest2();
485         SenderTest3();  
486     } else if (myrank == dest) {
487         ReceiverTest1();
488         ReceiverTest2();
489         ReceiverTest3(); 
490     } else {
491         fprintf(stderr, "*** This program uses exactly 2 processes! ***\n");
492         exit(-1);
493     }
494     Test_Waitforall( );
495     if (myrank == dest) {
496         int rval;
497         rval = Summarize_Test_Results();
498         Test_Finalize();
499         MPI_Finalize();
500         return rval;
501     }
502     else {
503         Test_Finalize();
504         MPI_Finalize();
505         return 0;
506     }
507 }