2 * Program to test all of the features of MPI_Send and MPI_Recv
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
13 * Define VERBOSE to get noisier output
22 #ifdef HAVE_MPICHCONF_H
23 #include "mpichconf.h"
29 static int do_test1 = 1;
30 static int do_test2 = 1;
31 static int do_test3 = 1;
33 static int verbose = 0;
36 static int ntypes = 0;
37 static int nolongdouble = 0;
38 static MPI_Datatype BasicTypes[MAX_TYPES];
40 static int maxbufferlen = 10000;
41 static char *(BasicNames[MAX_TYPES]);
43 /* In order to quiet noisy C compilers, we provide ANSI-style prototypes
46 void AllocateBuffers ( void **, MPI_Datatype *, int, int );
47 void FreeBuffers ( void **, int );
48 void FillBuffers ( void **, MPI_Datatype *, int, int );
49 int CheckBuffer ( void *, MPI_Datatype, int );
50 void SetupBasicTypes (void);
51 void SenderTest1 (void);
52 void ReceiverTest1 (void);
53 void SenderTest2 (void);
54 void ReceiverTest2 (void);
55 void SenderTest3 (void);
56 void ReceiverTest3 (void);
59 AllocateBuffers(bufferspace, buffertypes, num_types, bufferlen)
61 MPI_Datatype *buffertypes;
66 for (i = 0; i < ntypes; i++) {
67 if (buffertypes[i] == MPI_CHAR)
68 bufferspace[i] = malloc(bufferlen * sizeof(char));
69 else if (buffertypes[i] == MPI_SHORT)
70 bufferspace[i] = malloc(bufferlen * sizeof(short));
71 else if (buffertypes[i] == MPI_INT)
72 bufferspace[i] = malloc(bufferlen * sizeof(int));
73 else if (buffertypes[i] == MPI_LONG)
74 bufferspace[i] = malloc(bufferlen * sizeof(long));
75 else if (buffertypes[i] == MPI_UNSIGNED_CHAR)
76 bufferspace[i] = malloc(bufferlen * sizeof(unsigned char));
77 else if (buffertypes[i] == MPI_UNSIGNED_SHORT)
78 bufferspace[i] = malloc(bufferlen * sizeof(unsigned short));
79 else if (buffertypes[i] == MPI_UNSIGNED)
80 bufferspace[i] = malloc(bufferlen * sizeof(unsigned int));
81 else if (buffertypes[i] == MPI_UNSIGNED_LONG)
82 bufferspace[i] = malloc(bufferlen * sizeof(unsigned long));
83 else if (buffertypes[i] == MPI_FLOAT)
84 bufferspace[i] = malloc(bufferlen * sizeof(float));
85 else if (buffertypes[i] == MPI_DOUBLE)
86 bufferspace[i] = malloc(bufferlen * sizeof(double));
87 #if defined(HAVE_LONG_DOUBLE) && !defined(HAS_XDR)
88 else if (buffertypes[i] == MPI_LONG_DOUBLE) {
90 MPI_Type_size( MPI_LONG_DOUBLE, &dlen );
91 bufferspace[i] = malloc(bufferlen * dlen);
94 #if defined(HAVE_LONG_LONG_INT) && !defined(HAS_XDR)
95 else if (buffertypes[i] == MPI_LONG_LONG_INT)
96 bufferspace[i] = malloc(bufferlen * sizeof(long long) );
98 else if (buffertypes[i] == MPI_BYTE)
99 bufferspace[i] = malloc(bufferlen * sizeof(unsigned char));
103 void FreeBuffers(void **buffers, int nbuffers)
106 for (i = 0; i < nbuffers; i++)
110 void FillBuffers(bufferspace, buffertypes, num_types, bufferlen)
112 MPI_Datatype *buffertypes;
117 for (i = 0; i < ntypes; i++) {
118 for (j = 0; j < bufferlen; j++) {
119 if (buffertypes[i] == MPI_CHAR)
120 ((char *)bufferspace[i])[j] = (char)(j & 0x7f);
121 else if (buffertypes[i] == MPI_SHORT)
122 ((short *)bufferspace[i])[j] = (short)j;
123 else if (buffertypes[i] == MPI_INT)
124 ((int *)bufferspace[i])[j] = (int)j;
125 else if (buffertypes[i] == MPI_LONG)
126 ((long *)bufferspace[i])[j] = (long)j;
127 else if (buffertypes[i] == MPI_UNSIGNED_CHAR)
128 ((unsigned char *)bufferspace[i])[j] = (unsigned char)j;
129 else if (buffertypes[i] == MPI_UNSIGNED_SHORT)
130 ((unsigned short *)bufferspace[i])[j] = (unsigned short)j;
131 else if (buffertypes[i] == MPI_UNSIGNED)
132 ((unsigned int *)bufferspace[i])[j] = (unsigned int)j;
133 else if (buffertypes[i] == MPI_UNSIGNED_LONG)
134 ((unsigned long *)bufferspace[i])[j] = (unsigned long)j;
135 else if (buffertypes[i] == MPI_FLOAT)
136 ((float *)bufferspace[i])[j] = (float)j;
137 else if (buffertypes[i] == MPI_DOUBLE)
138 ((double *)bufferspace[i])[j] = (double)j;
139 #if defined(HAVE_LONG_DOUBLE) && !defined(HAS_XDR)
140 else if (buffertypes[i] == MPI_LONG_DOUBLE)
141 ((long double *)bufferspace[i])[j] = (long double)j;
143 #if defined(HAVE_LONG_LONG_INT) && !defined(HAS_XDR)
144 else if (buffertypes[i] == MPI_LONG_LONG_INT)
145 ((long long *)bufferspace[i])[j] = (long long)j;
147 else if (buffertypes[i] == MPI_BYTE)
148 ((unsigned char *)bufferspace[i])[j] = (unsigned char)j;
154 CheckBuffer(bufferspace, buffertype, bufferlen)
156 MPI_Datatype buffertype;
162 for (j = 0; j < bufferlen; j++) {
163 if (buffertype == MPI_CHAR) {
164 if (((char *)bufferspace)[j] != (char)(j & 0x7f)) {
165 sprintf( valerr, "%x != %x",
166 ((char *)bufferspace)[j], (char)(j&0x7f) );
169 } else if (buffertype == MPI_SHORT) {
170 if (((short *)bufferspace)[j] != (short)j) {
171 sprintf( valerr, "%d != %d",
172 ((short *)bufferspace)[j], (short)j );
175 } else if (buffertype == MPI_INT) {
176 if (((int *)bufferspace)[j] != (int)j) {
177 sprintf( valerr, "%d != %d",
178 ((int *)bufferspace)[j], (int)j );
181 } else if (buffertype == MPI_LONG) {
182 if (((long *)bufferspace)[j] != (long)j) {
185 } else if (buffertype == MPI_UNSIGNED_CHAR) {
186 if (((unsigned char *)bufferspace)[j] != (unsigned char)j) {
189 } else if (buffertype == MPI_UNSIGNED_SHORT) {
190 if (((unsigned short *)bufferspace)[j] != (unsigned short)j) {
193 } else if (buffertype == MPI_UNSIGNED) {
194 if (((unsigned int *)bufferspace)[j] != (unsigned int)j) {
197 } else if (buffertype == MPI_UNSIGNED_LONG) {
198 if (((unsigned long *)bufferspace)[j] != (unsigned long)j) {
201 } else if (buffertype == MPI_FLOAT) {
202 if (((float *)bufferspace)[j] != (float)j) {
205 } else if (buffertype == MPI_DOUBLE) {
206 if (((double *)bufferspace)[j] != (double)j) {
209 #if defined(HAVE_LONG_DOUBLE) && !defined(HAS_XDR)
210 } else if (buffertype == MPI_LONG_DOUBLE) {
211 if (((long double *)bufferspace)[j] != (long double)j) {
215 #if defined(HAVE_LONG_LONG_INT) && !defined(HAS_XDR)
216 } else if (buffertype == MPI_LONG_LONG_INT) {
217 if (((long long *)bufferspace)[j] != (long long)j) {
221 } else if (buffertype == MPI_BYTE) {
222 if (((unsigned char *)bufferspace)[j] != (unsigned char)j) {
227 /* Return +1 so an error in the first location is > 0 */
229 if (valerr[0]) fprintf( stderr, "Different value[%d] = %s\n",
232 fprintf( stderr, "Different value[%d]\n", j );
241 BasicTypes[0] = MPI_CHAR; BasicNames[0] = (char*)"MPI_CHAR" ;
242 BasicTypes[1] = MPI_SHORT; BasicNames[1] = (char*)"MPI_SHORT";
243 BasicTypes[2] = MPI_INT; BasicNames[2] = (char*)"MPI_INT" ;
244 BasicTypes[3] = MPI_LONG; BasicNames[3] = (char*)"MPI_LONG" ;
245 BasicTypes[4] = MPI_UNSIGNED_CHAR; BasicNames[4] = (char*)"MPI_UNSIGNED_CHAR";
246 BasicTypes[5] = MPI_UNSIGNED_SHORT; BasicNames[5] = (char*)"MPI_UNSIGNED_SHORT";
247 BasicTypes[6] = MPI_UNSIGNED; BasicNames[6] = (char*)"MPI_UNSIGNED";
248 BasicTypes[7] = MPI_UNSIGNED_LONG; BasicNames[7] = (char*)"MPI_UNSIGNED_LONG";
249 BasicTypes[8] = MPI_FLOAT; BasicNames[8] = (char*)"MPI_FLOAT";
250 BasicTypes[9] = MPI_DOUBLE; BasicNames[9] = (char*)"MPI_DOUBLE";
251 BasicTypes[10] = MPI_BYTE; BasicNames[10] = (char*)"MPI_BYTE";
252 /* By making the BYTE type LAST, we make it easier to handle heterogeneous
253 systems that may not support all of the types */
255 #if defined (HAVE_LONG_DOUBLE) && !defined(HAS_XDR)
256 /* This test allows us to use MPI_LONG_DOUBLE, but rely on size > 0
257 for "actually implemented" */
260 MPI_Type_size( MPI_LONG_DOUBLE, &l );
262 BasicTypes[ntypes] = MPI_LONG_DOUBLE;
263 BasicNames[ntypes] = (char*)"MPI_LONG_DOUBLE";
268 #if defined(HAVE_LONG_LONG_INT) && !defined(HAS_XDR)
269 BasicTypes[ntypes] = MPI_LONG_LONG_INT;
270 BasicNames[ntypes] = (char*)"MPI_LONG_LONG_INT";
278 void *bufferspace[MAX_TYPES];
281 AllocateBuffers(bufferspace, BasicTypes, ntypes, maxbufferlen);
282 FillBuffers(bufferspace, BasicTypes, ntypes, maxbufferlen);
283 for (i = 0; i < ntypes; i++) {
284 MPI_Send( (void *)0, 0, BasicTypes[i], dest, 2000, MPI_COMM_WORLD );
285 for (j = 0; j < maxbufferlen; j += 500)
286 MPI_Send(bufferspace[i], j, BasicTypes[i], dest,
287 2000, MPI_COMM_WORLD);
289 FreeBuffers(bufferspace, ntypes);
295 void *bufferspace[MAX_TYPES];
301 AllocateBuffers(bufferspace, BasicTypes, ntypes, maxbufferlen);
302 for (i = 0; i < ntypes; i++) {
304 MPI_Recv( (void *)0, 0, BasicTypes[i], src,
305 2000, MPI_COMM_WORLD, &Stat);
306 if (Stat.MPI_SOURCE != src) {
307 fprintf(stderr, "*** Incorrect Source returned. ***\n");
308 Test_Failed(message);
310 } else if (Stat.MPI_TAG != 2000) {
311 fprintf(stderr, "*** Incorrect Tag returned. ***\n");
312 Test_Failed(message);
314 } else if (MPI_Get_count(&Stat, BasicTypes[i], &dummy) ||
317 "*** Incorrect Count returned, Count = %d. ***\n",
319 Test_Failed(message);
322 /* Try different sized messages */
323 for (j = 0; j < maxbufferlen; j += 500) {
324 MPI_Recv(bufferspace[i], j, BasicTypes[i], src,
325 2000, MPI_COMM_WORLD, &Stat);
326 sprintf(message, "Send-Receive Test, Type %d, Count %d",
328 if (Stat.MPI_SOURCE != src) {
329 fprintf(stderr, "*** Incorrect Source returned. ***\n");
330 Test_Failed(message);
332 } else if (Stat.MPI_TAG != 2000) {
333 fprintf(stderr, "*** Incorrect Tag returned. ***\n");
334 Test_Failed(message);
336 } else if (MPI_Get_count(&Stat, BasicTypes[i], &dummy) ||
339 "*** Incorrect Count returned, Count = %d (should be %d). ***\n",
341 Test_Failed(message);
343 } else if(CheckBuffer(bufferspace[i], BasicTypes[i], j)) {
345 "*** Incorrect Message received (type = %d (%s), count = %d). ***\n",
346 i, BasicNames[i], j );
347 Test_Failed(message);
353 "Message of count %d, type %d received correctly.\n",
358 sprintf(message, "Send-Receive Test, Type %d (%s)",
361 Test_Passed(message);
363 Test_Failed(message);
365 FreeBuffers(bufferspace, ntypes);
368 #define MAX_ORDER_TAG 2010
369 /* Test Tag Selectivity.
370 Note that we must use non-blocking sends here, since otherwise we could
371 deadlock waiting to receive/send the first message
381 buffer = (int *)malloc(maxbufferlen * sizeof(int));
382 for (i = 0; i < maxbufferlen; i++)
385 for (i = 2001; i <= MAX_ORDER_TAG; i++)
386 MPI_Isend(buffer, maxbufferlen, MPI_INT, dest,
387 i, MPI_COMM_WORLD, &r[i-2001] );
389 MPI_Waitall( MAX_ORDER_TAG-2001+1, r, s );
405 buffer = (int *)calloc(maxbufferlen,sizeof(int));
408 for (i = MAX_ORDER_TAG; i >= 2001; i--) {
409 MPI_Recv(buffer, maxbufferlen, MPI_INT, src,
410 i, MPI_COMM_WORLD, &Stat);
411 sprintf(message, "Tag Selectivity Test, Tag %d",
413 if (Stat.MPI_SOURCE != src) {
414 fprintf(stderr, "*** Incorrect Source returned. ***\n");
415 Test_Failed(message);
416 } else if (Stat.MPI_TAG != i) {
417 fprintf(stderr, "*** Incorrect Tag returned. ***\n");
418 Test_Failed(message);
419 } else if (MPI_Get_count(&Stat, MPI_INT, &dummy) ||
420 dummy != maxbufferlen) {
422 "*** Incorrect Count returned, Count = %d. ***\n",
424 Test_Failed(message);
426 CheckBuffer((void*)buffer, MPI_INT, maxbufferlen))) {
428 "*** Incorrect Message received at %d (tag=%d). ***\n",
430 Test_Failed(message);
433 /* Clear out the buffer */
434 for (j = 0; j < maxbufferlen; j++)
437 strncpy(message, "Tag Selectivity Test", 81);
439 Test_Passed(message);
441 Test_Failed(message);
451 /* A receive test might not fail until it is triggered... */
452 MPI_Send( ibuf, 10, MPI_INT, dest, 15, MPI_COMM_WORLD);
458 ReceiverTest3( void )
461 MPI_Datatype bogus_type = MPI_DATATYPE_NULL;
467 MPI_Errhandler_set(MPI_COMM_WORLD, TEST_ERRORS_WARN);
469 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN );
471 MPI_Comm_rank( MPI_COMM_WORLD, &myrank );
473 if (myrank == 0 && verbose) {
475 "There should be eight error messages about invalid communicator\n\
476 count argument, datatype argument, tag, rank, buffer send and buffer recv\n" );
478 if (MPI_Send(buffer, 20, MPI_INT, dest,
479 1, MPI_COMM_NULL) == MPI_SUCCESS){
480 Test_Failed("NULL Communicator Test");
483 Test_Passed("NULL Communicator Test");
485 if (MPI_Send(buffer, -1, MPI_INT, dest,
486 1, MPI_COMM_WORLD) == MPI_SUCCESS){
487 Test_Failed("Invalid Count Test");
490 Test_Passed("Invalid Count Test");
492 if (MPI_Send(buffer, 20, bogus_type, dest,
493 1, MPI_COMM_WORLD) == MPI_SUCCESS){
494 Test_Failed("Invalid Type Test");
497 Test_Passed("Invalid Type Test");
500 if (small_tag == MPI_ANY_TAG) small_tag = -2;
501 if (MPI_Send(buffer, 20, MPI_INT, dest,
502 small_tag, MPI_COMM_WORLD) == MPI_SUCCESS) {
503 Test_Failed("Invalid Tag Test");
506 Test_Passed("Invalid Tag Test");
508 /* Form a tag that is too large */
509 /*MPI_Attr_get( MPI_COMM_WORLD, MPI_TAG_UB, (void **)&tag_ubp, &flag );
510 if (!flag) Test_Failed("Could not get tag ub!" );
511 large_tag = *tag_ubp + 1;
512 if (large_tag > *tag_ubp) {
513 if (MPI_Send(buffer, 20, MPI_INT, dest,
514 large_tag, MPI_COMM_WORLD) == MPI_SUCCESS) {
515 Test_Failed("Invalid Tag Test");
518 Test_Passed("Invalid Tag Test");
521 if (MPI_Send(buffer, 20, MPI_INT, 300,
522 1, MPI_COMM_WORLD) == MPI_SUCCESS) {
523 Test_Failed("Invalid Destination Test");
526 Test_Passed("Invalid Destination Test");
528 if (MPI_Send((void *)0, 10, MPI_INT, dest,
529 1, MPI_COMM_WORLD) == MPI_SUCCESS){
530 Test_Failed("Invalid Buffer Test (send)");
533 Test_Passed("Invalid Buffer Test (send)");
535 /* A receive test might not fail until it is triggered... */
536 if (MPI_Recv((void *)0, 10, MPI_INT, src,
537 15, MPI_COMM_WORLD, &status) == MPI_SUCCESS){
538 Test_Failed("Invalid Buffer Test (recv)");
541 Test_Passed("Invalid Buffer Test (recv)");
543 /* Just to keep things happy, see if there is a message to receive */
544 { int flag, ibuf[10];
546 MPI_Iprobe( src, 15, MPI_COMM_WORLD, &flag, &status );
548 MPI_Recv( ibuf, 10, MPI_INT, src, 15, MPI_COMM_WORLD, &status );
550 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL );
554 /* Allow -nolongdouble to suppress long double testing */
555 int main( int argc, char **argv )
560 MPI_Init(&argc, &argv);
561 MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
562 MPI_Comm_size(MPI_COMM_WORLD, &mysize);
563 Test_Init("sendrecv", myrank);
568 "*** This test program requires exactly 2 processes.\n");
569 MPI_Abort( MPI_COMM_WORLD, 1 );
572 /* Get the min of the basic types */
574 MPI_Allreduce( &itemp, &ntypes, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD );
576 /* dest writes out the received stats; for the output to be
577 consistant (with the final check), it should be procees 0 */
578 for (i=1; i<argc; i++) {
579 if (argv[i] && strcmp( "-alt", argv[i] ) == 0) {
583 else if (argv[i] && strcmp( "-nolongdouble", argv[i] ) == 0) {
586 else if (argv[i] && strcmp( "-test1", argv[i] ) == 0) {
587 do_test2 = do_test3 = 0;
589 else if (argv[i] && strcmp( "-test2", argv[i] ) == 0) {
590 do_test1 = do_test3 = 0;
592 else if (argv[i] && strcmp( "-test3", argv[i] ) == 0) {
593 do_test2 = do_test1 = 0;
596 printf( "Unrecognized argument %s\n", argv[i] );
600 /* Turn stdout's buffering to line buffered so it mixes right with
601 stderr in output files. (hopefully) */
602 setvbuf(stdout, NULL, _IOLBF, 0);
603 setvbuf(stderr, NULL, _IOLBF, 0);
612 } else if (myrank == dest) {
620 fprintf(stderr, "*** This program uses exactly 2 processes! ***\n");
621 MPI_Abort( MPI_COMM_WORLD, 1 );
623 if (myrank == dest) {
624 rc = Summarize_Test_Results();