[mpich] MPICH primary repository branch, master, updated. v3.1-10-g9096ccd
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "MPICH primary repository". The branch, master has been updated via 9096ccd7490765a023dab13da6cfabee098b6b41 (commit) via d78c062c2ccc30308c9e89bb543edc2ae413d1fe (commit) via 9c932265fd5a7274fd2fb476afdeeb312247c26d (commit) via 3cbff4986af31e95678cb6814472fb93e7eef29c (commit) via 229f3126763c8275460dcf6ed916350634ad68c8 (commit) via 63a8f03f0523273d04ed067df4f9597b5fcee968 (commit) via 9bf0007b3c8fb023b3c412a59cffca3f84851a23 (commit) from 89ec5ecf2c5d7694ced255188fa10133f9c6a496 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- http://git.mpich.org/mpich.git/commitdiff/9096ccd7490765a023dab13da6cfabee09... commit 9096ccd7490765a023dab13da6cfabee098b6b41 Author: Rob Latham <[email protected]> Date: Mon Feb 3 13:16:54 2014 -0600 corrects old text in the introductory comments. These tests were adapted from the mpich-1 test suite but they are their own creatures now. Original-author: William Gropp <[email protected]> Signed-off-by: Rob Latham <[email protected]> diff --git a/test/mpi/datatype/sendrecvt2.c b/test/mpi/datatype/sendrecvt2.c index 48b1e72..36f25d0 100644 --- a/test/mpi/datatype/sendrecvt2.c +++ b/test/mpi/datatype/sendrecvt2.c @@ -9,9 +9,8 @@ #include "dtypes.h" /* - This program is from mpich/tsuite/pt2pt and should be changed there only. - It needs gcomm and dtype from mpich/tsuite, and can be run with - any number of processes > 1. + This program is derived from one in the MPICH-1 test suite. It + tests a wide variety of basic and derived datatypes. */ int main( int argc, char **argv) { diff --git a/test/mpi/datatype/sendrecvt4.c b/test/mpi/datatype/sendrecvt4.c index 1c98c9a..da8edee 100644 --- a/test/mpi/datatype/sendrecvt4.c +++ b/test/mpi/datatype/sendrecvt4.c @@ -10,20 +10,10 @@ /* - This program is from mpich/tsuite/pt2pt and should be changed there only. - It needs gcomm and dtype from mpich/tsuite, and can be run with - any number of processes > 1. + This program is derived from one in the MPICH-1 test suite This version sends and receives EVERYTHING from MPI_BOTTOM, by putting the data into a structure. - - This code isn't quite correct, since the MPI_Type_struct that is - created for the type may not have the correct extent. - One possible change is to make the struct type include the count, and - send/receive one instance of the data item. - - The GenerateData call should return extents; when the extent of the - created structure doesn't match, we can at least issue an error message. */ int main( int argc, char **argv ) { http://git.mpich.org/mpich.git/commitdiff/d78c062c2ccc30308c9e89bb543edc2ae4... commit d78c062c2ccc30308c9e89bb543edc2ae413d1fe Author: William Gropp <[email protected]> Date: Sun Feb 2 15:53:52 2014 -0600 Fix typo in comment in dataalign.c Signed-off-by: Rob Latham <[email protected]> diff --git a/test/mpi/datatype/dataalign.c b/test/mpi/datatype/dataalign.c index b1c8b31..b152c80 100644 --- a/test/mpi/datatype/dataalign.c +++ b/test/mpi/datatype/dataalign.c @@ -83,7 +83,7 @@ int main( int argc, char *argv[]) if ( s1[j].c != 'a' + j + status.MPI_SOURCE ) { errs++; /* If the character is not a printing character, - this can generate an file that diff, for example, + this can generate a file that diff, for example, believes is a binary file */ if (isprint( (int)(s1[j].c) )) { fprintf( stderr, "Got s[%d].c = %c; expected %c\n", http://git.mpich.org/mpich.git/commitdiff/9c932265fd5a7274fd2fb476afdeeb3122... commit 9c932265fd5a7274fd2fb476afdeeb312247c26d Author: William Gropp <[email protected]> Date: Sun Feb 2 22:34:37 2014 -0600 Fix bug in marking unbuilt tests as failed The xfail additions to the runtests code had an incorrect test on xfail that caused runtests to stop recording a test that could not be built as failed - thus, the test script would report success for all tests when some tests were not run. Signed-off-by: Rob Latham <[email protected]> diff --git a/test/mpi/runtests.in b/test/mpi/runtests.in index df6fd8b..aced005 100644 --- a/test/mpi/runtests.in +++ b/test/mpi/runtests.in @@ -544,7 +544,7 @@ sub RunList { $progEnv, $mpiexecArgs, $xfail ); } } - elsif ($xfail ne '') { + elsif ($xfail eq '') { # We expected to run this program, so failure to build # is an error $found_error = 1; http://git.mpich.org/mpich.git/commitdiff/3cbff4986af31e95678cb6814472fb93e7... commit 3cbff4986af31e95678cb6814472fb93e7eef29c Author: William Gropp <[email protected]> Date: Wed Jan 29 12:08:00 2014 -0600 Add some MPICH-1 tests to MPICH datatype tests This adds dataalign, sendrecvt2, and sendrecvt4 to the tests of MPI datatypes in the MPICH test suite. Signed-off-by: Rob Latham <[email protected]> diff --git a/test/mpi/datatype/Makefile.am b/test/mpi/datatype/Makefile.am index ef48b29..bd1de7b 100644 --- a/test/mpi/datatype/Makefile.am +++ b/test/mpi/datatype/Makefile.am @@ -24,6 +24,7 @@ noinst_PROGRAMS = \ contig-zero-count \ contigstruct \ cxx-types \ + dataalign \ darray-pack \ darray-cyclic \ gaddress \ @@ -43,6 +44,8 @@ noinst_PROGRAMS = \ lots-of-types \ pairtype-pack \ pairtype-size-extent \ + sendrecvt2 \ + sendrecvt4 \ simple-commit \ simple-pack \ simple-pack-external \ @@ -75,3 +78,10 @@ noinst_PROGRAMS = \ zeroblks \ zeroparms +# Some of the tests use a more comprehensive set of datatype tests. +# These must specify a different LDADD that includes the object file +# with these additional routines +LDADDDATA = $(top_builddir)/util/dtypes.$(OBJEXT) + +sendrecvt2_LDADD = $(LDADD) $(LDADDDATA) +sendrecvt4_LDADD = $(LDADD) $(LDADDDATA) diff --git a/test/mpi/datatype/testlist.in b/test/mpi/datatype/testlist.in index 967f546..6e9b5c2 100644 --- a/test/mpi/datatype/testlist.in +++ b/test/mpi/datatype/testlist.in @@ -14,6 +14,8 @@ zeroparms 1 getpartelm 2 tresized 2 tresized2 2 +sendrecvt2 2 +sendrecvt4 2 tmatchsize 1 tfree 2 typelb 1 @@ -48,6 +50,7 @@ get-elements 1 hindexed_block 1 mpiversion=3.0 hindexed_block_contents 1 mpiversion=3.0 longdouble 1 +dataalign 2 @largetest@large-count 1 mpiversion=3.0 xfail=ticket1767 cxx-types 1 mpiversion=3.0 @largetest@large_type 1 mpiversion=3.0 http://git.mpich.org/mpich.git/commitdiff/229f3126763c8275460dcf6ed916350634... commit 229f3126763c8275460dcf6ed916350634ad68c8 Author: William Gropp <[email protected]> Date: Wed Jan 29 12:04:51 2014 -0600 Add sendrecv2 and sendrecv4 test from MPICH-1 This test moves the sendrecv2 and sendrecv4 test from MPICH-1 to the new MPICH tests. It has been updated to use the MTest framework. This test uses the datatypes created by the dtypes.c file (also moved from MPICH-1). These tests involve creating a structure type with an explicit offset of a variety of types, and then communicated with MPI_BOTTOM as the buffer location. Several of these tests failed in a recent update to the Dataloop code for optimization of performance. Signed-off-by: Rob Latham <[email protected]> diff --git a/test/mpi/datatype/sendrecvt2.c b/test/mpi/datatype/sendrecvt2.c new file mode 100644 index 0000000..48b1e72 --- /dev/null +++ b/test/mpi/datatype/sendrecvt2.c @@ -0,0 +1,110 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include "mpi.h" +#include "mpitest.h" +#include <stdio.h> +#include "dtypes.h" + +/* + This program is from mpich/tsuite/pt2pt and should be changed there only. + It needs gcomm and dtype from mpich/tsuite, and can be run with + any number of processes > 1. + */ +int main( int argc, char **argv) +{ + MPI_Datatype *types; + void **inbufs, **outbufs; + int *counts, *bytesize, ntype; + MPI_Comm comm; + int ncomm = 20, rank, np, partner, tag, count; + int i, j, k, err, toterr, world_rank, errloc; + MPI_Status status; + char *obuf; + char myname[MPI_MAX_OBJECT_NAME]; + int mynamelen; + + MTest_Init( &argc, &argv ); + + /* + * Check for -basiconly to select only the simple datatypes + */ + for (i=1; i<argc; i++) { + if (!argv[i]) break; + if (strcmp( argv[i], "-basiconly" ) == 0) { + MTestDatatype2BasicOnly(); + } + } + + MTestDatatype2Allocate( &types, &inbufs, &outbufs, &counts, &bytesize, + &ntype ); + MTestDatatype2Generate( types, inbufs, outbufs, counts, bytesize, &ntype ); + + MPI_Comm_rank( MPI_COMM_WORLD, &world_rank ); + + /* Test over a wide range of datatypes and communicators */ + err = 0; + tag = 0; + while (MTestGetIntracomm( &comm, 2 )) { + if (comm == MPI_COMM_NULL) continue; + MPI_Comm_rank( comm, &rank ); + MPI_Comm_size( comm, &np ); + if (np < 2) continue; + if (world_rank == 0) + MTestPrintfMsg( 10, "Testing communicator number %s\n", + MTestGetIntracommName() ); + + tag++; + for (j=0; j<ntype; j++) { + MPI_Type_get_name( types[j], myname, &mynamelen ); + if (world_rank == 0) + MTestPrintfMsg( 10, "Testing type %s\n", myname ); + if (rank == 0) { + partner = np - 1; + MPI_Send( inbufs[j], counts[j], types[j], partner, tag, comm ); + } + else if (rank == np-1) { + partner = 0; + obuf = outbufs[j]; + for (k=0; k<bytesize[j]; k++) + obuf[k] = 0; + MPI_Recv( outbufs[j], counts[j], types[j], partner, tag, + comm, &status ); + /* Test correct */ + MPI_Get_count( &status, types[j], &count ); + if (count != counts[j]) { + fprintf( stderr, + "Error in counts (got %d expected %d) with type %s\n", + count, counts[j], myname ); + err++; + } + if (status.MPI_SOURCE != partner) { + fprintf( stderr, + "Error in source (got %d expected %d) with type %s\n", + status.MPI_SOURCE, partner, myname ); + err++; + } + if ((errloc = MTestDatatype2Check( inbufs[j], outbufs[j], + bytesize[j] ))) { + char *p1, *p2; + fprintf( stderr, + "Error in data with type %s (type %d on %d) at byte %d\n", + myname, j, world_rank, errloc - 1 ); + p1 = (char *)inbufs[j]; + p2 = (char *)outbufs[j]; + fprintf( stderr, + "Got %x expected %x\n", p1[errloc-1], p2[errloc-1] ); + err++; + } + } + } + MTestFreeComm( &comm ); + } + + MTestDatatype2Free( types, inbufs, outbufs, counts, bytesize, ntype ); + MTest_Finalize( err ); + MPI_Finalize(); + return MTestReturnValue( err ); +} diff --git a/test/mpi/datatype/sendrecvt4.c b/test/mpi/datatype/sendrecvt4.c new file mode 100644 index 0000000..1c98c9a --- /dev/null +++ b/test/mpi/datatype/sendrecvt4.c @@ -0,0 +1,163 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include "mpi.h" +#include "mpitest.h" +#include <stdio.h> +#include "dtypes.h" + + +/* + This program is from mpich/tsuite/pt2pt and should be changed there only. + It needs gcomm and dtype from mpich/tsuite, and can be run with + any number of processes > 1. + + This version sends and receives EVERYTHING from MPI_BOTTOM, by putting + the data into a structure. + + This code isn't quite correct, since the MPI_Type_struct that is + created for the type may not have the correct extent. + One possible change is to make the struct type include the count, and + send/receive one instance of the data item. + + The GenerateData call should return extents; when the extent of the + created structure doesn't match, we can at least issue an error message. + */ +int main( int argc, char **argv ) +{ + MPI_Datatype *types; + void **inbufs, **outbufs; + int *counts, *bytesize, ntype; + MPI_Comm comm; + int ncomm = 20, rank, np, partner, tag, count; + int j, k, err, toterr, world_rank, errloc; + MPI_Status status; + char *obuf; + MPI_Datatype offsettype; + int blen; + MPI_Aint displ, extent, natural_extent; + char myname[MPI_MAX_OBJECT_NAME]; + int mynamelen; + + MTest_Init( &argc, &argv ); + + MTestDatatype2Allocate( &types, &inbufs, &outbufs, &counts, &bytesize, + &ntype ); + MTestDatatype2Generate( types, inbufs, outbufs, counts, bytesize, &ntype ); + + MPI_Comm_rank( MPI_COMM_WORLD, &world_rank ); + + /* Test over a wide range of datatypes and communicators */ + err = 0; + tag = 0; + while (MTestGetIntracomm( &comm, 2 )) { + if (comm == MPI_COMM_NULL) continue; + MPI_Comm_rank( comm, &rank ); + MPI_Comm_size( comm, &np ); + if (np < 2) continue; + tag++; + for (j=0; j<ntype; j++) { + MPI_Type_get_name( types[j], myname, &mynamelen ); + if (world_rank == 0) + MTestPrintfMsg( 10, "Testing type %s\n", myname ); + if (rank == 0) { + MPI_Get_address( inbufs[j], &displ ); + blen = 1; + MPI_Type_create_struct( 1, &blen, &displ, types + j, + &offsettype ); + MPI_Type_commit( &offsettype ); + /* Warning: if the type has an explicit MPI_UB, then using a + simple shift of the offset won't work. For now, we skip + types whose extents are negative; the correct solution is + to add, where required, an explicit MPI_UB */ + MPI_Type_extent( offsettype, &extent ); + if (extent < 0) { + if (world_rank == 0) + MTestPrintfMsg( 10, + "... skipping (appears to have explicit MPI_UB\n" ); + MPI_Type_free( &offsettype ); + continue; + } + MPI_Type_extent( types[j], &natural_extent ); + if (natural_extent != extent) { + MPI_Type_free( &offsettype ); + continue; + } + partner = np - 1; + MPI_Send( MPI_BOTTOM, counts[j], offsettype, partner, tag, + comm ); + MPI_Type_free( &offsettype ); + } + else if (rank == np-1) { + partner = 0; + obuf = outbufs[j]; + for (k=0; k<bytesize[j]; k++) + obuf[k] = 0; + MPI_Get_address( outbufs[j], &displ ); + blen = 1; + MPI_Type_create_struct( 1, &blen, &displ, types + j, + &offsettype ); + MPI_Type_commit( &offsettype ); + /* Warning: if the type has an explicit MPI_UB, then using a + simple shift of the offset won't work. For now, we skip + types whose extents are negative; the correct solution is + to add, where required, an explicit MPI_UB */ + MPI_Type_extent( offsettype, &extent ); + if (extent < 0) { + MPI_Type_free( &offsettype ); + continue; + } + MPI_Type_extent( types[j], &natural_extent ); + if (natural_extent != extent) { + MPI_Type_free( &offsettype ); + continue; + } + MPI_Recv( MPI_BOTTOM, counts[j], offsettype, + partner, tag, comm, &status ); + /* Test for correctness */ + MPI_Get_count( &status, types[j], &count ); + if (count != counts[j]) { + fprintf( stderr, + "Error in counts (got %d expected %d) with type %s\n", + count, counts[j], myname ); + err++; + } + if (status.MPI_SOURCE != partner) { + fprintf( stderr, + "Error in source (got %d expected %d) with type %s\n", + status.MPI_SOURCE, partner, myname ); + err++; + } + if ((errloc = MTestDatatype2Check( inbufs[j], outbufs[j], + bytesize[j] ))) { + fprintf( stderr, + "Error in data with type %s (type %d on %d) at byte %d\n", + myname, j, world_rank, errloc - 1 ); + if (err < 10) { + /* Give details on only the first 10 errors */ + unsigned char *in_p = (unsigned char *)inbufs[j], + *out_p = (unsigned char *)outbufs[j]; + int jj; + jj = errloc - 1; + jj &= 0xfffffffc; /* lop off a few bits */ + in_p += jj; + out_p += jj; + fprintf( stderr, "%02x%02x%02x%02x should be %02x%02x%02x%02x\n", + out_p[0], out_p[1], out_p[2], out_p[3], + in_p[0], in_p[1], in_p[2], in_p[3] ); + } + err++; + } + MPI_Type_free( &offsettype ); + } + } + MTestFreeComm( &comm ); + } + + MTestDatatype2Free( types, inbufs, outbufs, counts, bytesize, ntype ); + MTest_Finalize( err ); + MPI_Finalize(); + return MTestReturnValue( err ); +} http://git.mpich.org/mpich.git/commitdiff/63a8f03f0523273d04ed067df4f9597b5f... commit 63a8f03f0523273d04ed067df4f9597b5fcee968 Author: William Gropp <[email protected]> Date: Wed Jan 29 12:02:36 2014 -0600 Add dataalign test from MPICH1 This commit add the dataalign test from MPICH1. It has been updated to use the MTest framework. This tests a specific struct datatype, and is a test that caused one recent dataloop optimization to fail. Signed-off-by: Rob Latham <[email protected]> diff --git a/test/mpi/datatype/dataalign.c b/test/mpi/datatype/dataalign.c new file mode 100644 index 0000000..b1c8b31 --- /dev/null +++ b/test/mpi/datatype/dataalign.c @@ -0,0 +1,105 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include "mpi.h" +#include <stdio.h> +/* The next is for isprint */ +#include <ctype.h> +#include "mpitest.h" + +int main( int argc, char *argv[]) +{ + struct a { int i; + char c; + } s[10], s1[10]; + int j; + int errs = 0; + int rank, size, tsize; + MPI_Aint text; + int blens[2]; + MPI_Aint disps[2]; + MPI_Datatype bases[2]; + MPI_Datatype str, con; + MPI_Status status; + + MTest_Init( &argc, &argv ); + + MPI_Comm_rank( MPI_COMM_WORLD, &rank ); + MPI_Comm_size( MPI_COMM_WORLD, &size ); + + for( j = 0; j < 10; j ++ ) { + s[j].i = j + rank; + s[j].c = j + rank + 'a'; + } + + blens[0] = blens[1] = 1; + disps[0] = 0; disps[1] = sizeof(int); + bases[0] = MPI_INT; bases[1] = MPI_CHAR; + MPI_Type_struct( 2, blens, disps, bases, &str ); + MPI_Type_commit( &str ); + MPI_Type_contiguous( 10, str, &con ); + MPI_Type_commit( &con ); + MPI_Type_size( con, &tsize ); + MPI_Type_extent( con, &text ); + + MTestPrintfMsg( 0, "Size of MPI array is %d, extent is %d\n", + tsize, text ); + + /* The following block of code is only for verbose-level output */ + { + void * p1, *p2; + p1 = s; + p2 = &(s[10].i); /* This statement may fail on some systems */ + MTestPrintfMsg( 0, + "C array starts at %p and ends at %p for a length of %d\n", + s, &(s[9].c), (char *)p2-(char *)p1 ); + } + + MPI_Type_extent( str, &text ); + MPI_Type_size( str, &tsize ); + MTestPrintfMsg( 0, "Size of MPI struct is %d, extent is %d\n", + tsize, (int)text ); + MTestPrintfMsg( 0, "Size of C struct is %d\n", sizeof(struct a) ); + if (text != sizeof(struct a)) { + fprintf( stderr, + "Extent of struct a (%d) does not match sizeof (%d)\n", + (int)text, (int)sizeof(struct a) ); + errs++; + } + + MPI_Send( s, 1, con, rank ^ 1, 0, MPI_COMM_WORLD ); + MPI_Recv( s1, 1, con, rank ^ 1, 0, MPI_COMM_WORLD, &status ); + + for( j = 0; j < 10; j++ ) { + MTestPrintfMsg( 0, "%d Sent: %d %c, Got: %d %c\n", rank, + s[j].i, s[j].c, s1[j].i, s1[j].c ); + if ( s1[j].i != j + status.MPI_SOURCE ) { + errs++; + fprintf( stderr, "Got s[%d].i = %d; expected %d\n", j, s1[j].i, + j + status.MPI_SOURCE ); + } + if ( s1[j].c != 'a' + j + status.MPI_SOURCE ) { + errs++; + /* If the character is not a printing character, + this can generate an file that diff, for example, + believes is a binary file */ + if (isprint( (int)(s1[j].c) )) { + fprintf( stderr, "Got s[%d].c = %c; expected %c\n", + j, s1[j].c, j + status.MPI_SOURCE + 'a'); + } + else { + fprintf( stderr, "Got s[%d].c = %x; expected %c\n", + j, (int)s1[j].c, j + status.MPI_SOURCE + 'a'); + } + } + } + + MPI_Type_free( &str ); + MPI_Type_free( &con ); + + MTest_Finalize( errs ); + MPI_Finalize(); + return 0; +} http://git.mpich.org/mpich.git/commitdiff/9bf0007b3c8fb023b3c412a59cffca3f84... commit 9bf0007b3c8fb023b3c412a59cffca3f84851a23 Author: William Gropp <[email protected]> Date: Wed Jan 29 11:59:57 2014 -0600 Add datatype test support from MPICH1 This adds the routines originally defined in the MPICH test suite that created a range of datatype tests, including the input and output data. This commit moves them to the new MPICH and puts them into the MTest framework, as an optional file. Signed-off-by: Rob Latham <[email protected]> diff --git a/test/mpi/include/dtypes.h b/test/mpi/include/dtypes.h new file mode 100644 index 0000000..3a3c888 --- /dev/null +++ b/test/mpi/include/dtypes.h @@ -0,0 +1,13 @@ +#ifndef MPITEST_DTYPES +#define MPITEST_DTYPES + +void MTestDatatype2Generate ( MPI_Datatype *, void **, void **, int *, int *, + int * ); +void MTestDatatype2Allocate ( MPI_Datatype **, void ***, void ***, + int **, int **, int * ); +int MTestDatatype2Check ( void *, void *, int ); +int MTestDatatype2CheckAndPrint ( void *, void *, int, char *, int ); +void MTestDatatype2Free ( MPI_Datatype *, void **, void **, + int *, int *, int ); +void MTestDatatype2BasicOnly( void ); +#endif diff --git a/test/mpi/util/Makefile.am b/test/mpi/util/Makefile.am index b4a6ce9..770c81f 100644 --- a/test/mpi/util/Makefile.am +++ b/test/mpi/util/Makefile.am @@ -2,8 +2,9 @@ AM_CPPFLAGS = -I${srcdir}/../include -I../include mtest.$(OBJEXT): mtest.c +dtypes.$(OBJEXT): dtypes.c nbc_pmpi_adapter.$(OBJEXT): nbc_pmpi_adapter.c -all-local: mtest.$(OBJEXT) nbc_pmpi_adapter.$(OBJEXT) +all-local: mtest.$(OBJEXT) dtypes.$(OBJEXT) nbc_pmpi_adapter.$(OBJEXT) EXTRA_PROGRAMS = mtestcheck mtestcheck_SOURCES = mtestcheck.c mtest.c diff --git a/test/mpi/util/dtypes.c b/test/mpi/util/dtypes.c new file mode 100644 index 0000000..616088c --- /dev/null +++ b/test/mpi/util/dtypes.c @@ -0,0 +1,388 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include "mpi.h" +#include "mpitestconf.h" +#include "mpitest.h" +#include "dtypes.h" +#if defined(HAVE_STDIO_H) || defined(STDC_HEADERS) +#include <stdio.h> +#endif +#if defined(HAVE_STDLIB_H) || defined(STDC_HEADERS) +#include <stdlib.h> +#endif +#if defined(HAVE_STRING_H) || defined(STDC_HEADERS) +#include <string.h> +#endif +#ifdef HAVE_STDARG_H +#include <stdarg.h> +#endif + +/* This file contains code to generate a variety of MPI datatypes for testing + the various MPI routines. + + To simplify the test code, this generates an array of datatypes, buffers with + data and buffers with no data (0 bits) for use in send and receive + routines of various types. + + In addition, this doesn't even test all of the possibilities. For example, + there is currently no test of sending more than one item defined with + MPI_Type_contiguous . + + Note also that this test assumes that the sending and receive types are + the same. MPI requires only that the type signatures match, which is + a weaker requirement. + + This code was drawn from the MPICH-1 test suite and modified to fit the + new MPICH test suite. It provides an alternative set of datatype tests + to the ones in mtest.c. + + */ + +/* Change this to test only the basic, predefined types */ +static int basic_only = 0; + +/* + Arrays types, inbufs, outbufs, and counts are allocated by the + CALLER. n on input is the maximum number; on output, it is the + number defined. + + See MTestDatatype2Allocate below for a routine to allocate these arrays. + + We may want to add a routine to call to check that the proper data + has been received. + */ + +/* + Add a predefined MPI type to the tests. _count instances of the + type will be sent. +*/ +#define SETUPBASICTYPE(_mpitype,_ctype,_count) { \ + int i; _ctype *a; \ + if (cnt > *n) {*n = cnt; return; } \ + types[cnt] = _mpitype; \ + inbufs[cnt] = (void *)calloc( _count,sizeof(_ctype) ); \ + outbufs[cnt] = (void *)malloc( sizeof(_ctype) * (_count) ); \ + a = (_ctype *)inbufs[cnt]; for (i=0; i<(_count); i++) a[i] = i; \ + a = (_ctype *)outbufs[cnt]; for (i=0; i<(_count); i++) a[i] = 0; \ + counts[cnt] = _count; bytesize[cnt] = sizeof(_ctype) * (_count); cnt++; } + +/* + Add a contiguous version of a predefined type. Send one instance of + the type which contains _count copies of the predefined type. + */ +#define SETUPCONTIGTYPE(_mpitype,_ctype,_count) { \ + int i; _ctype *a; char*myname; \ + char _basename[MPI_MAX_OBJECT_NAME]; int _basenamelen;\ + if (cnt > *n) {*n = cnt; return; }\ + MPI_Type_contiguous( _count, _mpitype, types + cnt );\ + MPI_Type_commit( types + cnt );\ + inbufs[cnt] = (void *)calloc( _count, sizeof(_ctype) ); \ + outbufs[cnt] = (void *)malloc( sizeof(_ctype) * (_count) ); \ + a = (_ctype *)inbufs[cnt]; for (i=0; i<(_count); i++) a[i] = i; \ + a = (_ctype *)outbufs[cnt]; for (i=0; i<(_count); i++) a[i] = 0; \ + myname = (char *)malloc(100);\ + MPI_Type_get_name( _mpitype, _basename, &_basenamelen ); \ + snprintf( myname, 100, "Contig type %s", _basename ); \ + MPI_Type_set_name( types[cnt], myname ); \ + free( myname ); \ + counts[cnt] = 1; bytesize[cnt] = sizeof(_ctype) * (_count); cnt++; } + +/* + Create a vector with _count elements, separated by stride _stride, + of _mpitype. Each block has a single element. + */ +#define SETUPVECTORTYPE(_mpitype,_ctype,_count,_stride,_name) { \ + int i; _ctype *a; char *myname; \ + char _basename[MPI_MAX_OBJECT_NAME]; int _basenamelen;\ + if (cnt > *n) {*n = cnt; return; }\ + MPI_Type_vector( _count, 1, _stride, _mpitype, types + cnt ); \ + MPI_Type_commit( types + cnt );\ + inbufs[cnt] = (void *)calloc( sizeof(_ctype) * (_count) * (_stride),1); \ + outbufs[cnt] = (void *)calloc( sizeof(_ctype) * (_count) * (_stride),1); \ + a = (_ctype *)inbufs[cnt]; for (i=0; i<(_count); i++) a[i*(_stride)] = i; \ + a = (_ctype *)outbufs[cnt]; for (i=0; i<(_count); i++) a[i*(_stride)] = 0; \ + myname = (char *)malloc(100);\ + MPI_Type_get_name( _mpitype, _basename, &_basenamelen ); \ + snprintf( myname, 100, "Vector type %s", _basename ); \ + MPI_Type_set_name( types[cnt], myname ); \ + free( myname ); \ + counts[cnt] = 1; bytesize[cnt] = sizeof(_ctype) * (_count) * (_stride) ;\ + cnt++; } + +/* This indexed type is setup like a contiguous type . + Note that systems may try to convert this to contiguous, so we'll + eventually need a test that has holes in it */ +#define SETUPINDEXTYPE(_mpitype,_ctype,_count,_name) { \ + int i; int *lens, *disp; _ctype *a; char *myname; \ + char _basename[MPI_MAX_OBJECT_NAME]; int _basenamelen;\ + if (cnt > *n) {*n = cnt; return; }\ + lens = (int *)malloc( (_count) * sizeof(int) ); \ + disp = (int *)malloc( (_count) * sizeof(int) ); \ + for (i=0; i<(_count); i++) { lens[i] = 1; disp[i] = i; } \ + MPI_Type_indexed( (_count), lens, disp, _mpitype, types + cnt );\ + free( lens ); free( disp ); \ + MPI_Type_commit( types + cnt );\ + inbufs[cnt] = (void *)calloc( (_count), sizeof(_ctype) ); \ + outbufs[cnt] = (void *)malloc( sizeof(_ctype) * (_count) ); \ + a = (_ctype *)inbufs[cnt]; for (i=0; i<(_count); i++) a[i] = i; \ + a = (_ctype *)outbufs[cnt]; for (i=0; i<(_count); i++) a[i] = 0; \ + myname = (char *)malloc(100);\ + MPI_Type_get_name( _mpitype, _basename, &_basenamelen ); \ + snprintf( myname, 100, "Index type %s", _basename ); \ + MPI_Type_set_name( types[cnt], myname ); \ + free( myname ); \ + counts[cnt] = 1; bytesize[cnt] = sizeof(_ctype) * (_count); cnt++; } + +/* This defines a structure of two basic members; by chosing things like + (char, double), various packing and alignment tests can be made */ +#define SETUPSTRUCT2TYPE(_mpitype1,_ctype1,_mpitype2,_ctype2,_count,_tname) { \ + int i; char *myname; \ + MPI_Datatype b[3]; int cnts[3]; \ + struct name { _ctype1 a1; _ctype2 a2; } *a, samp; \ + MPI_Aint disp[3]; \ + if (cnt > *n) {*n = cnt; return; } \ + b[0] = _mpitype1; b[1] = _mpitype2; b[2] = MPI_UB; \ + cnts[0] = 1; cnts[1] = 1; cnts[2] = 1; \ + MPI_Get_address( &(samp.a2), &disp[1] ); \ + MPI_Get_address( &(samp.a1), &disp[0] ); \ + MPI_Get_address( &(samp) + 1, &disp[2] ); \ + disp[1] = disp[1] - disp[0]; disp[2] = disp[2] - disp[0]; disp[0] = 0; \ + MPI_Type_create_struct( 3, cnts, disp, b, types + cnt ); \ + MPI_Type_commit( types + cnt ); \ + inbufs[cnt] = (void *)calloc( sizeof(struct name) * (_count),1); \ + outbufs[cnt] = (void *)calloc( sizeof(struct name) * (_count),1); \ + a = (struct name *)inbufs[cnt]; for (i=0; i<(_count); i++) { a[i].a1 = i; \ + a[i].a2 = i; } \ + a = (struct name *)outbufs[cnt]; for (i=0; i<(_count); i++) { a[i].a1 = 0; \ + a[i].a2 = 0; } \ + myname = (char *)malloc(100); \ + snprintf( myname, 100, "Struct type %s", _tname ); \ + MPI_Type_set_name( types[cnt], myname ); \ + free( myname ); \ + counts[cnt] = (_count); bytesize[cnt] = sizeof(struct name) * (_count);cnt++; } + +/* This accomplished the same effect as VECTOR, but allow a count of > 1 */ +#define SETUPSTRUCTTYPEUB(_mpitype,_ctype,_count,_stride) { \ + int i; _ctype *a; char *myname; \ + int blens[2]; MPI_Aint disps[2]; MPI_Datatype mtypes[2]; \ + char _basename[MPI_MAX_OBJECT_NAME]; int _basenamelen;\ + if (cnt > *n) {*n = cnt; return; } \ + blens[0] = 1; blens[1] = 1; disps[0] = 0; \ + disps[1] = (_stride) * sizeof(_ctype); \ + mtypes[0] = _mpitype; mtypes[1] = MPI_UB; \ + MPI_Type_create_struct( 2, blens, disps, mtypes, types + cnt ); \ + MPI_Type_commit( types + cnt ); \ + inbufs[cnt] = (void *)calloc( sizeof(_ctype) * (_count) * (_stride),1);\ + outbufs[cnt] = (void *)calloc( sizeof(_ctype) * (_count) * (_stride),1);\ + a = (_ctype *)inbufs[cnt]; for (i=0; i<(_count); i++) a[i*(_stride)] = i; \ + a = (_ctype *)outbufs[cnt]; for (i=0; i<(_count); i++) a[i*(_stride)] = 0; \ + myname = (char *)malloc(100); \ + MPI_Type_get_name( _mpitype, _basename, &_basenamelen ); \ + snprintf( myname, 100, "Struct (MPI_UB) type %s", _basename ); \ + MPI_Type_set_name( types[cnt], myname ); \ + free( myname ); \ + counts[cnt] = (_count); \ + bytesize[cnt] = sizeof(_ctype) * (_count) * (_stride);\ + cnt++; } + +/* + * Set whether only the basic types should be generated + */ +void MTestDatatype2BasicOnly( void ) +{ + basic_only = 1; +} + +static int nbasic_types = 0; +/* On input, n is the size of the various buffers. On output, + it is the number available types + */ +void MTestDatatype2Generate( MPI_Datatype *types, void **inbufs, void **outbufs, + int *counts, int *bytesize, int *n ) +{ + int cnt = 0; /* Number of defined types */ + int typecnt = 10; /* Number of instances to send in most cases */ + int stride = 9; /* Number of elements in vector to stride */ + + /* First, generate an element of each basic type */ + SETUPBASICTYPE(MPI_CHAR,char,typecnt); + SETUPBASICTYPE(MPI_SHORT,short,typecnt); + SETUPBASICTYPE(MPI_INT,int,typecnt); + SETUPBASICTYPE(MPI_LONG,long,typecnt); + SETUPBASICTYPE(MPI_UNSIGNED_CHAR,unsigned char,typecnt); + SETUPBASICTYPE(MPI_UNSIGNED_SHORT,unsigned short,typecnt); + SETUPBASICTYPE(MPI_UNSIGNED,unsigned,typecnt); + SETUPBASICTYPE(MPI_UNSIGNED_LONG,unsigned long,typecnt); + SETUPBASICTYPE(MPI_FLOAT,float,typecnt); + SETUPBASICTYPE(MPI_DOUBLE,double,typecnt); + SETUPBASICTYPE(MPI_BYTE,char,typecnt); +#ifdef HAVE_LONG_LONG_INT + SETUPBASICTYPE(MPI_LONG_LONG_INT,long long,typecnt); +#endif +#ifdef HAVE_LONG_DOUBLE + SETUPBASICTYPE(MPI_LONG_DOUBLE,long double,typecnt); +#endif + nbasic_types = cnt; + + if (basic_only) { + *n = cnt; + return; + } + /* Generate contiguous data items */ + SETUPCONTIGTYPE(MPI_CHAR,char,typecnt); + SETUPCONTIGTYPE(MPI_SHORT,short,typecnt); + SETUPCONTIGTYPE(MPI_INT,int,typecnt); + SETUPCONTIGTYPE(MPI_LONG,long,typecnt); + SETUPCONTIGTYPE(MPI_UNSIGNED_CHAR,unsigned char,typecnt); + SETUPCONTIGTYPE(MPI_UNSIGNED_SHORT,unsigned short,typecnt); + SETUPCONTIGTYPE(MPI_UNSIGNED,unsigned,typecnt); + SETUPCONTIGTYPE(MPI_UNSIGNED_LONG,unsigned long,typecnt); + SETUPCONTIGTYPE(MPI_FLOAT,float,typecnt); + SETUPCONTIGTYPE(MPI_DOUBLE,double,typecnt); + SETUPCONTIGTYPE(MPI_BYTE,char,typecnt); +#ifdef HAVE_LONG_LONG_INT + SETUPCONTIGTYPE(MPI_LONG_LONG_INT,long long,typecnt); +#endif +#ifdef HAVE_LONG_DOUBLE + SETUPCONTIGTYPE(MPI_LONG_DOUBLE,long double,typecnt); +#endif + + /* Generate vector items */ + SETUPVECTORTYPE(MPI_CHAR,char,typecnt,stride,"MPI_CHAR"); + SETUPVECTORTYPE(MPI_SHORT,short,typecnt,stride,"MPI_SHORT"); + SETUPVECTORTYPE(MPI_INT,int,typecnt,stride,"MPI_INT"); + SETUPVECTORTYPE(MPI_LONG,long,typecnt,stride,"MPI_LONG"); + SETUPVECTORTYPE(MPI_UNSIGNED_CHAR,unsigned char,typecnt,stride,"MPI_UNSIGNED_CHAR"); + SETUPVECTORTYPE(MPI_UNSIGNED_SHORT,unsigned short,typecnt,stride,"MPI_UNSIGNED_SHORT"); + SETUPVECTORTYPE(MPI_UNSIGNED,unsigned,typecnt,stride,"MPI_UNSIGNED"); + SETUPVECTORTYPE(MPI_UNSIGNED_LONG,unsigned long,typecnt,stride,"MPI_UNSIGNED_LONG"); + SETUPVECTORTYPE(MPI_FLOAT,float,typecnt,stride,"MPI_FLOAT"); + SETUPVECTORTYPE(MPI_DOUBLE,double,typecnt,stride,"MPI_DOUBLE"); + SETUPVECTORTYPE(MPI_BYTE,char,typecnt,stride,"MPI_BYTE"); +#ifdef HAVE_LONG_LONG_INT + SETUPVECTORTYPE(MPI_LONG_LONG_INT,long long,typecnt,stride,"MPI_LONG_LONG_INT"); +#endif +#ifdef HAVE_LONG_DOUBLE + SETUPVECTORTYPE(MPI_LONG_DOUBLE,long double,typecnt,stride,"MPI_LONG_DOUBLE"); +#endif + + /* Generate indexed items */ + SETUPINDEXTYPE(MPI_CHAR,char,typecnt,"MPI_CHAR"); + SETUPINDEXTYPE(MPI_SHORT,short,typecnt,"MPI_SHORT"); + SETUPINDEXTYPE(MPI_INT,int,typecnt,"MPI_INT"); + SETUPINDEXTYPE(MPI_LONG,long,typecnt,"MPI_LONG"); + SETUPINDEXTYPE(MPI_UNSIGNED_CHAR,unsigned char,typecnt,"MPI_UNSIGNED_CHAR"); + SETUPINDEXTYPE(MPI_UNSIGNED_SHORT,unsigned short,typecnt,"MPI_UNSIGNED_SHORT"); + SETUPINDEXTYPE(MPI_UNSIGNED,unsigned,typecnt,"MPI_UNSIGNED"); + SETUPINDEXTYPE(MPI_UNSIGNED_LONG,unsigned long,typecnt,"MPI_UNSIGNED_LONG"); + SETUPINDEXTYPE(MPI_FLOAT,float,typecnt,"MPI_FLOAT"); + SETUPINDEXTYPE(MPI_DOUBLE,double,typecnt,"MPI_DOUBLE"); + SETUPINDEXTYPE(MPI_BYTE,char,typecnt,"MPI_BYTE"); +#ifdef HAVE_LONG_LONG_INT + SETUPINDEXTYPE(MPI_LONG_LONG_INT,long long,typecnt,"MPI_LONG_LONG_INT"); +#endif +#ifdef HAVE_LONG_DOUBLE + SETUPINDEXTYPE(MPI_LONG_DOUBLE,long double,typecnt,"MPI_LONG_DOUBLE"); +#endif + + /* Generate struct items */ + SETUPSTRUCT2TYPE(MPI_CHAR,char,MPI_DOUBLE,double,typecnt,"char-double"); + SETUPSTRUCT2TYPE(MPI_DOUBLE,double,MPI_CHAR,char,typecnt,"double-char"); + SETUPSTRUCT2TYPE(MPI_UNSIGNED,unsigned,MPI_DOUBLE,double,typecnt,"unsigned-double"); + SETUPSTRUCT2TYPE(MPI_FLOAT,float,MPI_LONG,long,typecnt,"float-long"); + SETUPSTRUCT2TYPE(MPI_UNSIGNED_CHAR,unsigned char,MPI_CHAR,char,typecnt, + "unsigned char-char"); + SETUPSTRUCT2TYPE(MPI_UNSIGNED_SHORT,unsigned short,MPI_DOUBLE,double, + typecnt,"unsigned short-double"); + + /* Generate struct using MPI_UB */ + SETUPSTRUCTTYPEUB(MPI_CHAR,char,typecnt,stride); + SETUPSTRUCTTYPEUB(MPI_SHORT,short,typecnt,stride); + SETUPSTRUCTTYPEUB(MPI_INT,int,typecnt,stride); + SETUPSTRUCTTYPEUB(MPI_LONG,long,typecnt,stride); + SETUPSTRUCTTYPEUB(MPI_UNSIGNED_CHAR,unsigned char,typecnt,stride); + SETUPSTRUCTTYPEUB(MPI_UNSIGNED_SHORT,unsigned short,typecnt,stride); + SETUPSTRUCTTYPEUB(MPI_UNSIGNED,unsigned,typecnt,stride); + SETUPSTRUCTTYPEUB(MPI_UNSIGNED_LONG,unsigned long,typecnt,stride); + SETUPSTRUCTTYPEUB(MPI_FLOAT,float,typecnt,stride); + SETUPSTRUCTTYPEUB(MPI_DOUBLE,double,typecnt,stride); + SETUPSTRUCTTYPEUB(MPI_BYTE,char,typecnt,stride); + + /* 60 different entries to this point + 4 for long long and + 4 for long double */ + *n = cnt; +} + +/* + MAX_TEST should be 1 + actual max (allows us to check that it was, + indeed, large enough) + */ +#define MAX_TEST 70 +void MTestDatatype2Allocate( MPI_Datatype **types, void ***inbufs, + void ***outbufs, + int **counts, int **bytesize, int *n ) +{ + *types = (MPI_Datatype *)malloc( MAX_TEST * sizeof(MPI_Datatype) ); + *inbufs = (void **) malloc( MAX_TEST * sizeof(void *) ); + *outbufs = (void **) malloc( MAX_TEST * sizeof(void *) ); + *counts = (int *) malloc( MAX_TEST * sizeof(int) ); + *bytesize = (int *) malloc( MAX_TEST * sizeof(int) ); + *n = MAX_TEST; +} + +int MTestDatatype2Check( void *inbuf, void *outbuf, int size_bytes ) +{ + char *in = (char *)inbuf, *out = (char *)outbuf; + int i; + for (i=0; i<size_bytes; i++) { + if (in[i] != out[i]) { + return i + 1; + } + } + return 0; +} + +/* + * This is a version of CheckData that prints error messages + */ +int MtestDatatype2CheckAndPrint( void *inbuf, void *outbuf, int size_bytes, + char *typename, int typenum ) +{ + int errloc, world_rank; + + if ((errloc = MTestDatatype2Check( inbuf, outbuf, size_bytes ))) { + char *p1, *p2; + MPI_Comm_rank( MPI_COMM_WORLD, &world_rank ); + fprintf( stderr, + "Error in data with type %s (type %d on %d) at byte %d of %d\n", + typename, typenum, world_rank, errloc - 1, size_bytes ); + p1 = (char *)inbuf; + p2 = (char *)outbuf; + fprintf( stderr, + "Got %x expected %x\n", p2[errloc-1], p1[errloc-1] ); + } + return errloc; +} + +void MTestDatatype2Free( MPI_Datatype *types, void **inbufs, void **outbufs, + int *counts, int *bytesize, int n ) +{ + int i; + for (i=0; i<n; i++) { + if (inbufs[i]) + free( inbufs[i] ); + if (outbufs[i]) + free( outbufs[i] ); + /* Only if not basic ... */ + if (i >= nbasic_types) + MPI_Type_free( types + i ); + } + free( inbufs ); + free( outbufs ); + free( counts ); + free( bytesize ); +} ----------------------------------------------------------------------- Summary of changes: test/mpi/datatype/Makefile.am | 10 + test/mpi/datatype/dataalign.c | 105 +++++++++++ test/mpi/datatype/sendrecvt2.c | 109 +++++++++++ test/mpi/datatype/sendrecvt4.c | 153 ++++++++++++++++ test/mpi/datatype/testlist.in | 3 + test/mpi/include/dtypes.h | 13 ++ test/mpi/runtests.in | 2 +- test/mpi/util/Makefile.am | 3 +- test/mpi/util/dtypes.c | 388 ++++++++++++++++++++++++++++++++++++++++ 9 files changed, 784 insertions(+), 2 deletions(-) create mode 100644 test/mpi/datatype/dataalign.c create mode 100644 test/mpi/datatype/sendrecvt2.c create mode 100644 test/mpi/datatype/sendrecvt4.c create mode 100644 test/mpi/include/dtypes.h create mode 100644 test/mpi/util/dtypes.c hooks/post-receive -- MPICH primary repository
participants (1)
-
noreply@mpich.org