1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
3 * (C) 2001 by Argonne National Laboratory.
4 * See COPYRIGHT in top-level directory.
7 #include "mpitestconf.h"
14 static int verbose = 0;
17 int builtin_float_test(void);
18 int vector_of_vectors_test(void);
19 int optimizable_vector_of_basics_test(void);
20 int indexed_of_basics_test(void);
21 int indexed_of_vectors_test(void);
22 int struct_of_basics_test(void);
24 /* helper functions */
25 char *combiner_to_string(int combiner);
26 int parse_args(int argc, char **argv);
28 int main(int argc, char **argv)
32 MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
33 parse_args(argc, argv);
35 /* To improve reporting of problems about operations, we
36 change the error handler to errors return */
37 MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
39 /* perform some tests */
40 err = builtin_float_test();
43 fprintf(stderr, "Found %d errors in builtin float test.\n", err);
46 err = vector_of_vectors_test();
49 fprintf(stderr, "Found %d errors in vector of vectors test.\n", err);
52 err = optimizable_vector_of_basics_test();
55 fprintf(stderr, "Found %d errors in vector of basics test.\n", err);
58 err = indexed_of_basics_test();
61 fprintf(stderr, "Found %d errors in indexed of basics test.\n", err);
64 err = indexed_of_vectors_test();
67 fprintf(stderr, "Found %d errors in indexed of vectors test.\n", err);
70 #ifdef HAVE_MPI_TYPE_CREATE_STRUCT
71 err = struct_of_basics_test();
75 /* print message and exit */
77 fprintf(stderr, "Found %d errors\n", errs);
80 printf(" No Errors\n");
86 /* builtin_float_test()
88 * Tests functionality of get_envelope() and get_contents() on a MPI_FLOAT.
90 * Returns the number of errors encountered.
92 int builtin_float_test(void)
94 int nints, nadds, ntypes, combiner;
96 int /* err, */ errs = 0;
98 /* err = */ MPI_Type_get_envelope(MPI_FLOAT,
104 if (combiner != MPI_COMBINER_NAMED) errs++;
105 if (verbose && combiner != MPI_COMBINER_NAMED)
106 fprintf(stderr, "combiner = %s; should be named\n",
107 combiner_to_string(combiner));
109 /* Note: it is erroneous to call MPI_Type_get_contents() on a basic. */
113 /* vector_of_vectors_test()
115 * Builds a vector of a vector of ints. Assuming an int array of size 9
116 * integers, and treating the array as a 3x3 2D array, this will grab the
119 * Returns the number of errors encountered.
121 int vector_of_vectors_test(void)
123 MPI_Datatype inner_vector, inner_vector_copy;
124 MPI_Datatype outer_vector;
126 int nints, nadds, ntypes, combiner, *ints;
127 MPI_Aint *adds = NULL;
133 err = MPI_Type_vector(2,
138 if (err != MPI_SUCCESS) {
139 if (verbose) fprintf(stderr,
140 "error in MPI call; aborting after %d errors\n",
145 err = MPI_Type_vector(2,
150 if (err != MPI_SUCCESS) {
151 if (verbose) fprintf(stderr,
152 "error in MPI call; aborting after %d errors\n",
157 /* decode outer vector (get envelope, then contents) */
158 err = MPI_Type_get_envelope(outer_vector,
163 if (err != MPI_SUCCESS) {
164 if (verbose) fprintf(stderr,
165 "error in MPI call; aborting after %d errors\n",
170 if (nints != 3) errs++;
171 if (nadds != 0) errs++;
172 if (ntypes != 1) errs++;
173 if (combiner != MPI_COMBINER_VECTOR) errs++;
176 if (nints != 3) fprintf(stderr,
177 "outer vector nints = %d; should be 3\n",
179 if (nadds != 0) fprintf(stderr,
180 "outer vector nadds = %d; should be 0\n",
182 if (ntypes != 1) fprintf(stderr,
183 "outer vector ntypes = %d; should be 1\n",
185 if (combiner != MPI_COMBINER_VECTOR)
186 fprintf(stderr, "outer vector combiner = %s; should be vector\n",
187 combiner_to_string(combiner));
190 if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
194 ints = malloc(nints * sizeof(*ints));
195 if (nadds) adds = malloc(nadds * sizeof(*adds));
196 types = malloc(ntypes * sizeof(*types));
198 /* get contents of outer vector */
199 err = MPI_Type_get_contents(outer_vector,
207 if (ints[0] != 2) errs++;
208 if (ints[1] != 1) errs++;
209 if (ints[2] != 2) errs++;
212 if (ints[0] != 2) fprintf(stderr,
213 "outer vector count = %d; should be 2\n",
215 if (ints[1] != 1) fprintf(stderr,
216 "outer vector blocklength = %d; should be 1\n",
218 if (ints[2] != 2) fprintf(stderr, "outer vector stride = %d; should be 2\n",
222 if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
226 inner_vector_copy = types[0];
228 if (nadds) free(adds);
231 /* decode inner vector */
232 err = MPI_Type_get_envelope(inner_vector_copy,
237 if (err != MPI_SUCCESS) {
238 if (verbose) fprintf(stderr,
239 "error in MPI call; aborting after %d errors\n",
244 if (nints != 3) errs++;
245 if (nadds != 0) errs++;
246 if (ntypes != 1) errs++;
247 if (combiner != MPI_COMBINER_VECTOR) errs++;
250 if (nints != 3) fprintf(stderr,
251 "inner vector nints = %d; should be 3\n",
253 if (nadds != 0) fprintf(stderr,
254 "inner vector nadds = %d; should be 0\n",
256 if (ntypes != 1) fprintf(stderr,
257 "inner vector ntypes = %d; should be 1\n",
259 if (combiner != MPI_COMBINER_VECTOR)
260 fprintf(stderr, "inner vector combiner = %s; should be vector\n",
261 combiner_to_string(combiner));
264 if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
268 ints = malloc(nints * sizeof(*ints));
269 if (nadds) adds = malloc(nadds * sizeof(*adds));
270 types = malloc(ntypes * sizeof(*types));
272 err = MPI_Type_get_contents(inner_vector_copy,
280 if (ints[0] != 2) errs++;
281 if (ints[1] != 1) errs++;
282 if (ints[2] != 2) errs++;
285 if (ints[0] != 2) fprintf(stderr,
286 "inner vector count = %d; should be 2\n",
288 if (ints[1] != 1) fprintf(stderr,
289 "inner vector blocklength = %d; should be 1\n",
291 if (ints[2] != 2) fprintf(stderr,
292 "inner vector stride = %d; should be 2\n",
296 if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
301 if (nadds) free(adds);
304 MPI_Type_free( &inner_vector_copy );
305 MPI_Type_free( &inner_vector );
306 MPI_Type_free( &outer_vector );
311 /* optimizable_vector_of_basics_test()
313 * Builds a vector of ints. Count is 10, blocksize is 2, stride is 2, so this
314 * is equivalent to a contig of 20. But remember...we should get back our
315 * suboptimal values under MPI-2.
317 * Returns the number of errors encountered.
319 int optimizable_vector_of_basics_test(void)
321 MPI_Datatype parent_type;
323 int nints, nadds, ntypes, combiner, *ints;
324 MPI_Aint *adds = NULL;
327 int /* err, */ errs = 0;
330 /* err = */ MPI_Type_vector(10,
337 /* err = */ MPI_Type_get_envelope(parent_type,
343 if (nints != 3) errs++;
344 if (nadds != 0) errs++;
345 if (ntypes != 1) errs++;
346 if (combiner != MPI_COMBINER_VECTOR) errs++;
349 if (nints != 3) fprintf(stderr, "nints = %d; should be 3\n", nints);
350 if (nadds != 0) fprintf(stderr, "nadds = %d; should be 0\n", nadds);
351 if (ntypes != 1) fprintf(stderr, "ntypes = %d; should be 1\n", ntypes);
352 if (combiner != MPI_COMBINER_VECTOR)
353 fprintf(stderr, "combiner = %s; should be vector\n",
354 combiner_to_string(combiner));
357 ints = malloc(nints * sizeof(*ints));
358 if (nadds) adds = malloc(nadds * sizeof(*adds));
359 types = malloc(ntypes *sizeof(*types));
361 /* err = */ MPI_Type_get_contents(parent_type,
369 if (ints[0] != 10) errs++;
370 if (ints[1] != 2) errs++;
371 if (ints[2] != 2) errs++;
372 if (types[0] != MPI_INT) errs++;
375 if (ints[0] != 10) fprintf(stderr, "count = %d; should be 10\n",
377 if (ints[1] != 2) fprintf(stderr, "blocklength = %d; should be 2\n",
379 if (ints[2] != 2) fprintf(stderr, "stride = %d; should be 2\n",
381 if (types[0] != MPI_INT) fprintf(stderr, "type is not MPI_INT\n");
385 if (nadds) free(adds);
388 MPI_Type_free( &parent_type );
394 /* indexed_of_basics_test(void)
396 * Simple indexed type.
398 * Returns number of errors encountered.
400 int indexed_of_basics_test(void)
402 MPI_Datatype parent_type;
403 int s_count = 3, s_blocklengths[3] = { 3, 2, 1 };
404 int s_displacements[3] = { 10, 20, 30 };
406 int nints, nadds, ntypes, combiner, *ints;
407 MPI_Aint *adds = NULL;
410 int /* err, */ errs = 0;
413 /* err = */ MPI_Type_indexed(s_count,
420 /* err = */ MPI_Type_get_envelope(parent_type,
426 if (nints != 7) errs++;
427 if (nadds != 0) errs++;
428 if (ntypes != 1) errs++;
429 if (combiner != MPI_COMBINER_INDEXED) errs++;
432 if (nints != 7) fprintf(stderr, "nints = %d; should be 7\n", nints);
433 if (nadds != 0) fprintf(stderr, "nadds = %d; should be 0\n", nadds);
434 if (ntypes != 1) fprintf(stderr, "ntypes = %d; should be 1\n", ntypes);
435 if (combiner != MPI_COMBINER_INDEXED)
436 fprintf(stderr, "combiner = %s; should be indexed\n",
437 combiner_to_string(combiner));
440 ints = malloc(nints * sizeof(*ints));
441 if (nadds) adds = malloc(nadds * sizeof(*adds));
442 types = malloc(ntypes *sizeof(*types));
444 /* err = */ MPI_Type_get_contents(parent_type,
452 if (ints[0] != s_count) errs++;
453 if (ints[1] != s_blocklengths[0]) errs++;
454 if (ints[2] != s_blocklengths[1]) errs++;
455 if (ints[3] != s_blocklengths[2]) errs++;
456 if (ints[4] != s_displacements[0]) errs++;
457 if (ints[5] != s_displacements[1]) errs++;
458 if (ints[6] != s_displacements[2]) errs++;
459 if (types[0] != MPI_INT) errs++;
462 if (ints[0] != s_count)
463 fprintf(stderr, "count = %d; should be %d\n", ints[0], s_count);
464 if (ints[1] != s_blocklengths[0])
465 fprintf(stderr, "blocklength[0] = %d; should be %d\n", ints[1], s_blocklengths[0]);
466 if (ints[2] != s_blocklengths[1])
467 fprintf(stderr, "blocklength[1] = %d; should be %d\n", ints[2], s_blocklengths[1]);
468 if (ints[3] != s_blocklengths[2])
469 fprintf(stderr, "blocklength[2] = %d; should be %d\n", ints[3], s_blocklengths[2]);
470 if (ints[4] != s_displacements[0])
471 fprintf(stderr, "displacement[0] = %d; should be %d\n", ints[4], s_displacements[0]);
472 if (ints[5] != s_displacements[1])
473 fprintf(stderr, "displacement[1] = %d; should be %d\n", ints[5], s_displacements[1]);
474 if (ints[6] != s_displacements[2])
475 fprintf(stderr, "displacement[2] = %d; should be %d\n", ints[6], s_displacements[2]);
476 if (types[0] != MPI_INT) fprintf(stderr, "type[0] does not match\n");
480 if (nadds) free(adds);
483 MPI_Type_free( &parent_type );
487 /* indexed_of_vectors_test()
489 * Builds an indexed type of vectors of ints.
491 * Returns the number of errors encountered.
493 int indexed_of_vectors_test(void)
495 MPI_Datatype inner_vector, inner_vector_copy;
496 MPI_Datatype outer_indexed;
498 int i_count = 3, i_blocklengths[3] = { 3, 2, 1 };
499 int i_displacements[3] = { 10, 20, 30 };
501 int nints, nadds, ntypes, combiner, *ints;
502 MPI_Aint *adds = NULL;
508 err = MPI_Type_vector(2,
513 if (err != MPI_SUCCESS) {
514 if (verbose) fprintf(stderr,
515 "error in MPI call; aborting after %d errors\n",
520 err = MPI_Type_indexed(i_count,
525 if (err != MPI_SUCCESS) {
526 if (verbose) fprintf(stderr,
527 "error in MPI call; aborting after %d errors\n",
532 /* decode outer vector (get envelope, then contents) */
533 err = MPI_Type_get_envelope(outer_indexed,
538 if (err != MPI_SUCCESS) {
539 if (verbose) fprintf(stderr,
540 "error in MPI call; aborting after %d errors\n",
545 if (nints != 7) errs++;
546 if (nadds != 0) errs++;
547 if (ntypes != 1) errs++;
548 if (combiner != MPI_COMBINER_INDEXED) errs++;
551 if (nints != 7) fprintf(stderr, "nints = %d; should be 7\n", nints);
552 if (nadds != 0) fprintf(stderr, "nadds = %d; should be 0\n", nadds);
553 if (ntypes != 1) fprintf(stderr, "ntypes = %d; should be 1\n", ntypes);
554 if (combiner != MPI_COMBINER_INDEXED)
555 fprintf(stderr, "combiner = %s; should be indexed\n",
556 combiner_to_string(combiner));
560 if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
564 ints = malloc(nints * sizeof(*ints));
565 if (nadds) adds = malloc(nadds * sizeof(*adds));
566 types = malloc(ntypes * sizeof(*types));
568 /* get contents of outer vector */
569 err = MPI_Type_get_contents(outer_indexed,
577 if (ints[0] != i_count) errs++;
578 if (ints[1] != i_blocklengths[0]) errs++;
579 if (ints[2] != i_blocklengths[1]) errs++;
580 if (ints[3] != i_blocklengths[2]) errs++;
581 if (ints[4] != i_displacements[0]) errs++;
582 if (ints[5] != i_displacements[1]) errs++;
583 if (ints[6] != i_displacements[2]) errs++;
586 if (ints[0] != i_count)
587 fprintf(stderr, "count = %d; should be %d\n", ints[0], i_count);
588 if (ints[1] != i_blocklengths[0])
589 fprintf(stderr, "blocklength[0] = %d; should be %d\n", ints[1], i_blocklengths[0]);
590 if (ints[2] != i_blocklengths[1])
591 fprintf(stderr, "blocklength[1] = %d; should be %d\n", ints[2], i_blocklengths[1]);
592 if (ints[3] != i_blocklengths[2])
593 fprintf(stderr, "blocklength[2] = %d; should be %d\n", ints[3], i_blocklengths[2]);
594 if (ints[4] != i_displacements[0])
595 fprintf(stderr, "displacement[0] = %d; should be %d\n", ints[4], i_displacements[0]);
596 if (ints[5] != i_displacements[1])
597 fprintf(stderr, "displacement[1] = %d; should be %d\n", ints[5], i_displacements[1]);
598 if (ints[6] != i_displacements[2])
599 fprintf(stderr, "displacement[2] = %d; should be %d\n", ints[6], i_displacements[2]);
603 if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
607 inner_vector_copy = types[0];
609 if (nadds) free(adds);
612 /* decode inner vector */
613 err = MPI_Type_get_envelope(inner_vector_copy,
618 if (err != MPI_SUCCESS) {
619 if (verbose) fprintf(stderr,
620 "error in MPI call; aborting after %d errors\n",
625 if (nints != 3) errs++;
626 if (nadds != 0) errs++;
627 if (ntypes != 1) errs++;
628 if (combiner != MPI_COMBINER_VECTOR) errs++;
631 if (nints != 3) fprintf(stderr,
632 "inner vector nints = %d; should be 3\n",
634 if (nadds != 0) fprintf(stderr,
635 "inner vector nadds = %d; should be 0\n",
637 if (ntypes != 1) fprintf(stderr,
638 "inner vector ntypes = %d; should be 1\n",
640 if (combiner != MPI_COMBINER_VECTOR)
641 fprintf(stderr, "inner vector combiner = %s; should be vector\n",
642 combiner_to_string(combiner));
645 if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
649 ints = malloc(nints * sizeof(*ints));
650 if (nadds) adds = malloc(nadds * sizeof(*adds));
651 types = malloc(ntypes * sizeof(*types));
653 err = MPI_Type_get_contents(inner_vector_copy,
661 if (ints[0] != 2) errs++;
662 if (ints[1] != 1) errs++;
663 if (ints[2] != 2) errs++;
666 if (ints[0] != 2) fprintf(stderr,
667 "inner vector count = %d; should be 2\n",
669 if (ints[1] != 1) fprintf(stderr,
670 "inner vector blocklength = %d; should be 1\n",
672 if (ints[2] != 2) fprintf(stderr,
673 "inner vector stride = %d; should be 2\n",
677 if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
682 if (nadds) free(adds);
685 MPI_Type_free( &inner_vector_copy );
686 MPI_Type_free( &inner_vector );
687 MPI_Type_free( &outer_indexed );
693 #ifdef HAVE_MPI_TYPE_CREATE_STRUCT
694 /* struct_of_basics_test(void)
696 * There's nothing simple about structs :). Although this is an easy one.
698 * Returns number of errors encountered.
702 int struct_of_basics_test(void)
704 MPI_Datatype parent_type;
705 int s_count = 3, s_blocklengths[3] = { 3, 2, 1 };
706 MPI_Aint s_displacements[3] = { 10, 20, 30 };
707 MPI_Datatype s_types[3] = { MPI_CHAR, MPI_INT, MPI_FLOAT };
709 int nints, nadds, ntypes, combiner, *ints;
710 MPI_Aint *adds = NULL;
716 err = MPI_Type_create_struct(s_count,
723 err = MPI_Type_get_envelope(parent_type,
729 if (nints != 4) errs++;
730 if (nadds != 3) errs++;
731 if (ntypes != 3) errs++;
732 if (combiner != MPI_COMBINER_STRUCT) errs++;
735 if (nints != 4) fprintf(stderr, "nints = %d; should be 3\n", nints);
736 if (nadds != 3) fprintf(stderr, "nadds = %d; should be 0\n", nadds);
737 if (ntypes != 3) fprintf(stderr, "ntypes = %d; should be 3\n", ntypes);
738 if (combiner != MPI_COMBINER_STRUCT)
739 fprintf(stderr, "combiner = %s; should be struct\n",
740 combiner_to_string(combiner));
743 ints = malloc(nints * sizeof(*ints));
744 adds = malloc(nadds * sizeof(*adds));
745 types = malloc(ntypes *sizeof(*types));
747 err = MPI_Type_get_contents(parent_type,
755 if (ints[0] != s_count) errs++;
756 if (ints[1] != s_blocklengths[0]) errs++;
757 if (ints[2] != s_blocklengths[1]) errs++;
758 if (ints[3] != s_blocklengths[2]) errs++;
759 if (adds[0] != s_displacements[0]) errs++;
760 if (adds[1] != s_displacements[1]) errs++;
761 if (adds[2] != s_displacements[2]) errs++;
762 if (types[0] != s_types[0]) errs++;
763 if (types[1] != s_types[1]) errs++;
764 if (types[2] != s_types[2]) errs++;
767 if (ints[0] != s_count)
768 fprintf(stderr, "count = %d; should be %d\n", ints[0], s_count);
769 if (ints[1] != s_blocklengths[0])
770 fprintf(stderr, "blocklength[0] = %d; should be %d\n", ints[1], s_blocklengths[0]);
771 if (ints[2] != s_blocklengths[1])
772 fprintf(stderr, "blocklength[1] = %d; should be %d\n", ints[2], s_blocklengths[1]);
773 if (ints[3] != s_blocklengths[2])
774 fprintf(stderr, "blocklength[2] = %d; should be %d\n", ints[3], s_blocklengths[2]);
775 if (adds[0] != s_displacements[0])
776 fprintf(stderr, "displacement[0] = %d; should be %d\n", adds[0], s_displacements[0]);
777 if (adds[1] != s_displacements[1])
778 fprintf(stderr, "displacement[1] = %d; should be %d\n", adds[1], s_displacements[1]);
779 if (adds[2] != s_displacements[2])
780 fprintf(stderr, "displacement[2] = %d; should be %d\n", adds[2], s_displacements[2]);
781 if (types[0] != s_types[0])
782 fprintf(stderr, "type[0] does not match\n");
783 if (types[1] != s_types[1])
784 fprintf(stderr, "type[1] does not match\n");
785 if (types[2] != s_types[2])
786 fprintf(stderr, "type[2] does not match\n");
793 MPI_Type_free( &parent_type );
799 /* combiner_to_string(combiner)
801 * Converts a numeric combiner into a pointer to a string used for printing.
803 char *combiner_to_string(int combiner)
805 static char c_named[] = "named";
806 static char c_contig[] = "contig";
807 static char c_vector[] = "vector";
808 static char c_hvector[] = "hvector";
809 static char c_indexed[] = "indexed";
810 static char c_hindexed[] = "hindexed";
811 static char c_struct[] = "struct";
812 #ifdef HAVE_MPI2_COMBINERS
813 static char c_dup[] = "dup";
814 static char c_hvector_integer[] = "hvector_integer";
815 static char c_hindexed_integer[] = "hindexed_integer";
816 static char c_indexed_block[] = "indexed_block";
817 static char c_struct_integer[] = "struct_integer";
818 static char c_subarray[] = "subarray";
819 static char c_darray[] = "darray";
820 static char c_f90_real[] = "f90_real";
821 static char c_f90_complex[] = "f90_complex";
822 static char c_f90_integer[] = "f90_integer";
823 static char c_resized[] = "resized";
826 if (combiner == MPI_COMBINER_NAMED) return c_named;
827 if (combiner == MPI_COMBINER_CONTIGUOUS) return c_contig;
828 if (combiner == MPI_COMBINER_VECTOR) return c_vector;
829 if (combiner == MPI_COMBINER_HVECTOR) return c_hvector;
830 if (combiner == MPI_COMBINER_INDEXED) return c_indexed;
831 if (combiner == MPI_COMBINER_HINDEXED) return c_hindexed;
832 if (combiner == MPI_COMBINER_STRUCT) return c_struct;
833 #ifdef HAVE_MPI2_COMBINERS
834 if (combiner == MPI_COMBINER_DUP) return c_dup;
835 if (combiner == MPI_COMBINER_HVECTOR_INTEGER) return c_hvector_integer;
836 if (combiner == MPI_COMBINER_HINDEXED_INTEGER) return c_hindexed_integer;
837 if (combiner == MPI_COMBINER_INDEXED_BLOCK) return c_indexed_block;
838 if (combiner == MPI_COMBINER_STRUCT_INTEGER) return c_struct_integer;
839 if (combiner == MPI_COMBINER_SUBARRAY) return c_subarray;
840 if (combiner == MPI_COMBINER_DARRAY) return c_darray;
841 if (combiner == MPI_COMBINER_F90_REAL) return c_f90_real;
842 if (combiner == MPI_COMBINER_F90_COMPLEX) return c_f90_complex;
843 if (combiner == MPI_COMBINER_F90_INTEGER) return c_f90_integer;
844 if (combiner == MPI_COMBINER_RESIZED) return c_resized;
850 int parse_args(int argc, char **argv)
855 while ((ret = getopt(argc, argv, "v")) >= 0)