set(txt_files
${txt_files}
${CMAKE_CURRENT_SOURCE_DIR}/README
- ${CMAKE_CURRENT_SOURCE_DIR}/runtest
+ ${CMAKE_CURRENT_SOURCE_DIR}/runtests
${CMAKE_CURRENT_SOURCE_DIR}/testlist
- ${CMAKE_CURRENT_SOURCE_DIR}/checktest
+ ${CMAKE_CURRENT_SOURCE_DIR}/checktests
+ ${CMAKE_CURRENT_SOURCE_DIR}/util/mtest.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/mpitestconf.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/mpitest.h
PARENT_SCOPE)
)
set(txt_files
${txt_files}
- ${CMAKE_CURRENT_SOURCE_DIR}/runtests
${CMAKE_CURRENT_SOURCE_DIR}/testlist
PARENT_SCOPE
)
)
set(txt_files
${txt_files}
- ${CMAKE_CURRENT_SOURCE_DIR}/runtests
${CMAKE_CURRENT_SOURCE_DIR}/testlist
PARENT_SCOPE
)
include_directories("${CMAKE_CURRENT_BINARY_DIR}/../include/")
- add_executable(cmake_install cmake_install.cmake ../util/mtest.c)
add_executable(cmfree cmfree.c ../util/mtest.c)
add_executable(cmsplit2 cmsplit2.c ../util/mtest.c)
add_executable(cmsplit cmsplit.c ../util/mtest.c)
add_executable(icsplit icsplit.c ../util/mtest.c)
add_executable(probe-intercomm probe-intercomm.c ../util/mtest.c)
-
-
- target_link_libraries(cmake_install simgrid)
target_link_libraries(cmfree simgrid)
target_link_libraries(cmsplit2 simgrid)
target_link_libraries(cmsplit simgrid)
target_link_libraries(icsplit simgrid)
target_link_libraries(probe-intercomm simgrid)
-
-
- set_target_properties(cmake_install PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
set_target_properties(cmfree PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
set_target_properties(cmsplit2 PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
set_target_properties(cmsplit PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
)
set(examples_src
${examples_src}
- ${CMAKE_CURRENT_SOURCE_DIR}/cmake_install.cmake
${CMAKE_CURRENT_SOURCE_DIR}/cmfree.c
${CMAKE_CURRENT_SOURCE_DIR}/cmsplit2.c
${CMAKE_CURRENT_SOURCE_DIR}/cmsplit.c
)
set(txt_files
${txt_files}
- ${CMAKE_CURRENT_SOURCE_DIR}/runtests
${CMAKE_CURRENT_SOURCE_DIR}/testlist
PARENT_SCOPE
)
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+
+if(enable_smpi)
+ if(WIN32)
+ set(CMAKE_C_FLAGS "-include ${CMAKE_HOME_DIRECTORY}/include/smpi/smpi_main.h")
+ else()
+ set(CMAKE_C_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpicc")
+ set(CMAKE_Fortran_COMPILER "${CMAKE_BINARY_DIR}/smpi_script/bin/smpiff")
+ endif()
+
+ set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
+ set(MPICH_FLAGS "-DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DUSE_STDARG=1 -DHAVE_LONG_DOUBLE=1 -DHAVE_PROTOTYPES=1 -DHAVE_SIGNAL_H=1 -DHAVE_SIGACTION=1 -DHAVE_SLEEP=1 -DHAVE_SYSCONF=1 -Wno-error=unused-variable")
+ include_directories("${CMAKE_HOME_DIRECTORY}/include/smpi")
+ include_directories("${CMAKE_CURRENT_BINARY_DIR}/../include/")
+
+
+ add_executable(blockindexed-misc blockindexed-misc.c ../util/mtest.c)
+ add_executable(blockindexed-zero-count blockindexed-zero-count.c ../util/mtest.c)
+ add_executable(contents contents.c ../util/mtest.c)
+ add_executable(contigstruct contigstruct.c ../util/mtest.c)
+ add_executable(contig-zero-count contig-zero-count.c ../util/mtest.c)
+ add_executable(cxx-types cxx-types.c ../util/mtest.c)
+ add_executable(darray-cyclic darray-cyclic.c ../util/mtest.c)
+ add_executable(darray-pack darray-pack.c ../util/mtest.c)
+ add_executable(gaddress gaddress.c ../util/mtest.c)
+ add_executable(get-elements get-elements.c ../util/mtest.c)
+ add_executable(get-elements-pairtype get-elements-pairtype.c ../util/mtest.c)
+ add_executable(getpartelm getpartelm.c ../util/mtest.c)
+ add_executable(hindexed_block hindexed_block.c ../util/mtest.c)
+ add_executable(hindexed_block_contents hindexed_block_contents.c ../util/mtest.c)
+ add_executable(hindexed-zeros hindexed-zeros.c ../util/mtest.c)
+ add_executable(indexed-misc indexed-misc.c ../util/mtest.c)
+ add_executable(large-count large-count.c ../util/mtest.c)
+ add_executable(lbub lbub.c ../util/mtest.c)
+ add_executable(localpack localpack.c ../util/mtest.c)
+ add_executable(longdouble longdouble.c ../util/mtest.c)
+ add_executable(lots-of-types lots-of-types.c ../util/mtest.c)
+ add_executable(pairtype-pack pairtype-pack.c ../util/mtest.c)
+ add_executable(pairtype-size-extent pairtype-size-extent.c ../util/mtest.c)
+ add_executable(simple-commit simple-commit.c ../util/mtest.c)
+ add_executable(simple-pack simple-pack.c ../util/mtest.c)
+ add_executable(simple-pack-external simple-pack-external.c ../util/mtest.c)
+ add_executable(simple-resized simple-resized.c ../util/mtest.c)
+ add_executable(simple-size-extent simple-size-extent.c ../util/mtest.c)
+ add_executable(sizedtypes sizedtypes.c ../util/mtest.c)
+ add_executable(slice-pack slice-pack.c ../util/mtest.c)
+ add_executable(slice-pack-external slice-pack-external.c ../util/mtest.c)
+ add_executable(struct-derived-zeros struct-derived-zeros.c ../util/mtest.c)
+ add_executable(struct-empty-el struct-empty-el.c ../util/mtest.c)
+ add_executable(struct-ezhov struct-ezhov.c ../util/mtest.c)
+ add_executable(struct-no-real-types struct-no-real-types.c ../util/mtest.c)
+ add_executable(struct-pack struct-pack.c ../util/mtest.c)
+ add_executable(struct-verydeep struct-verydeep.c ../util/mtest.c)
+ add_executable(struct-zero-count struct-zero-count.c ../util/mtest.c)
+ add_executable(subarray subarray.c ../util/mtest.c)
+ add_executable(subarray-pack subarray-pack.c ../util/mtest.c)
+ add_executable(tfree tfree.c ../util/mtest.c)
+ add_executable(tmatchsize tmatchsize.c ../util/mtest.c)
+ add_executable(transpose-pack transpose-pack.c ../util/mtest.c)
+ add_executable(tresized2 tresized2.c ../util/mtest.c)
+ add_executable(tresized tresized.c ../util/mtest.c)
+ add_executable(triangular-pack triangular-pack.c ../util/mtest.c)
+ add_executable(typecommit typecommit.c ../util/mtest.c)
+ add_executable(typefree typefree.c ../util/mtest.c)
+ add_executable(typelb typelb.c ../util/mtest.c)
+ add_executable(typename typename.c ../util/mtest.c)
+ add_executable(unpack unpack.c ../util/mtest.c)
+ add_executable(unusual-noncontigs unusual-noncontigs.c ../util/mtest.c)
+ add_executable(zero-blklen-vector zero-blklen-vector.c ../util/mtest.c)
+ add_executable(zeroblks zeroblks.c ../util/mtest.c)
+ add_executable(zeroparms zeroparms.c ../util/mtest.c)
+
+
+
+ target_link_libraries(blockindexed-misc simgrid)
+ target_link_libraries(blockindexed-zero-count simgrid)
+ target_link_libraries(contents simgrid)
+ target_link_libraries(contigstruct simgrid)
+ target_link_libraries(contig-zero-count simgrid)
+ target_link_libraries(cxx-types simgrid)
+ target_link_libraries(darray-cyclic simgrid)
+ target_link_libraries(darray-pack simgrid)
+ target_link_libraries(gaddress simgrid)
+ target_link_libraries(get-elements simgrid)
+ target_link_libraries(get-elements-pairtype simgrid)
+ target_link_libraries(getpartelm simgrid)
+ target_link_libraries(hindexed_block simgrid)
+ target_link_libraries(hindexed_block_contents simgrid)
+ target_link_libraries(hindexed-zeros simgrid)
+ target_link_libraries(indexed-misc simgrid)
+ target_link_libraries(large-count simgrid)
+ target_link_libraries(lbub simgrid)
+ target_link_libraries(localpack simgrid)
+ target_link_libraries(longdouble simgrid)
+ target_link_libraries(lots-of-types simgrid)
+ target_link_libraries(pairtype-pack simgrid)
+ target_link_libraries(pairtype-size-extent simgrid)
+ target_link_libraries(simple-commit simgrid)
+ target_link_libraries(simple-pack simgrid)
+ target_link_libraries(simple-pack-external simgrid)
+ target_link_libraries(simple-resized simgrid)
+ target_link_libraries(simple-size-extent simgrid)
+ target_link_libraries(sizedtypes simgrid)
+ target_link_libraries(slice-pack simgrid)
+ target_link_libraries(slice-pack-external simgrid)
+ target_link_libraries(struct-derived-zeros simgrid)
+ target_link_libraries(struct-empty-el simgrid)
+ target_link_libraries(struct-ezhov simgrid)
+ target_link_libraries(struct-no-real-types simgrid)
+ target_link_libraries(struct-pack simgrid)
+ target_link_libraries(struct-verydeep simgrid)
+ target_link_libraries(struct-zero-count simgrid)
+ target_link_libraries(subarray simgrid)
+ target_link_libraries(subarray-pack simgrid)
+ target_link_libraries(tfree simgrid)
+ target_link_libraries(tmatchsize simgrid)
+ target_link_libraries(transpose-pack simgrid)
+ target_link_libraries(tresized2 simgrid)
+ target_link_libraries(tresized simgrid)
+ target_link_libraries(triangular-pack simgrid)
+ target_link_libraries(typecommit simgrid)
+ target_link_libraries(typefree simgrid)
+ target_link_libraries(typelb simgrid)
+ target_link_libraries(typename simgrid)
+ target_link_libraries(unpack simgrid)
+ target_link_libraries(unusual-noncontigs simgrid)
+ target_link_libraries(zero-blklen-vector simgrid)
+ target_link_libraries(zeroblks simgrid)
+ target_link_libraries(zeroparms simgrid)
+
+
+
+ set_target_properties(blockindexed-misc PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(blockindexed-zero-count PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(contents PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(contigstruct PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(contig-zero-count PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(cxx-types PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(darray-cyclic PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(darray-pack PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(gaddress PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(get-elements PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(get-elements-pairtype PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(getpartelm PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(hindexed_block PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(hindexed_block_contents PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(hindexed-zeros PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(indexed-misc PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(large-count PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS} -Wno-error=implicit-function-declaration")
+ set_target_properties(lbub PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(localpack PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(longdouble PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(lots-of-types PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(pairtype-pack PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(pairtype-size-extent PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(simple-commit PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(simple-pack PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(simple-pack-external PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(simple-resized PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(simple-size-extent PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(sizedtypes PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(slice-pack PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(slice-pack-external PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(struct-derived-zeros PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(struct-empty-el PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(struct-ezhov PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(struct-no-real-types PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(struct-pack PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(struct-verydeep PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(struct-zero-count PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(subarray PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(subarray-pack PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(tfree PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(tmatchsize PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(transpose-pack PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(tresized2 PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(tresized PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(triangular-pack PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(typecommit PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(typefree PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(typelb PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(typename PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(unpack PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(unusual-noncontigs PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(zero-blklen-vector PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(zeroblks PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+ set_target_properties(zeroparms PROPERTIES COMPILE_FLAGS "${MPICH_FLAGS}")
+
+endif()
+
+set(tesh_files
+ ${tesh_files}
+ PARENT_SCOPE
+ )
+set(xml_files
+ ${xml_files}
+ PARENT_SCOPE
+ )
+set(examples_src
+ ${examples_src}
+ ${CMAKE_CURRENT_SOURCE_DIR}/blockindexed-misc.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/blockindexed-zero-count.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/contents.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/contigstruct.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/contig-zero-count.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/cxx-types.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/darray-cyclic.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/darray-pack.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/gaddress.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/get-elements.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/get-elements-pairtype.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/getpartelm.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hindexed_block.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hindexed_block_contents.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hindexed-zeros.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/indexed-misc.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/large-count.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/lbub.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/localpack.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/longdouble.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/lots-of-types.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/pairtype-pack.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/pairtype-size-extent.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/simple-commit.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/simple-pack.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/simple-pack-external.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/simple-resized.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/simple-size-extent.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/sizedtypes.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/slice-pack.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/slice-pack-external.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/struct-derived-zeros.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/struct-empty-el.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/struct-ezhov.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/struct-no-real-types.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/struct-pack.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/struct-verydeep.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/struct-zero-count.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/subarray.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/subarray-pack.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/tfree.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/tmatchsize.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/transpose-pack.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/tresized2.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/tresized.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/triangular-pack.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/typecommit.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/typefree.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/typelb.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/typename.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/unpack.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/unusual-noncontigs.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/zero-blklen-vector.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/zeroblks.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/zeroparms.c
+ PARENT_SCOPE
+ )
+set(bin_files
+ ${bin_files}
+ PARENT_SCOPE
+ )
+set(txt_files
+ ${txt_files}
+ ${CMAKE_CURRENT_SOURCE_DIR}/testlist
+ PARENT_SCOPE
+ )
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 0;
+
+/* tests */
+int blockindexed_contig_test(void);
+int blockindexed_vector_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+static int pack_and_unpack(char *typebuf,
+ int count,
+ MPI_Datatype datatype,
+ int typebufsz);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = blockindexed_contig_test();
+ if (err && verbose) fprintf(stderr, "%d errors in blockindexed test.\n",
+ err);
+ errs += err;
+
+ err = blockindexed_vector_test();
+ if (err && verbose) fprintf(stderr, "%d errors in blockindexed vector test.\n",
+ err);
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+/* blockindexed_contig_test()
+ *
+ * Tests behavior with a blockindexed that can be converted to a
+ * contig easily. This is specifically for coverage.
+ *
+ * Returns the number of errors encountered.
+ */
+int blockindexed_contig_test(void)
+{
+ int buf[4] = {7, -1, -2, -3};
+ int err, errs = 0;
+
+ int i, count = 1;
+ int disp = 0;
+ MPI_Datatype newtype;
+
+ int size, int_size;
+ MPI_Aint extent;
+
+ err = MPI_Type_create_indexed_block(count,
+ 1,
+ &disp,
+ MPI_INT,
+ &newtype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating struct type in blockindexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_size(MPI_INT, &int_size);
+
+ err = MPI_Type_size(newtype, &size);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type size in blockindexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ if (size != int_size) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: size != int_size in blockindexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ err = MPI_Type_extent(newtype, &extent);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type extent in blockindexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ if (extent != int_size) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: extent != int_size in blockindexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_commit(&newtype);
+
+ err = pack_and_unpack((char *) buf, 1, newtype, 4 * sizeof(int));
+ if (err != 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "error packing/unpacking in blockindexed_contig_test()\n");
+ }
+ errs += err;
+ }
+
+ for (i=0; i < 4; i++) {
+ int goodval;
+
+ switch(i) {
+ case 0:
+ goodval = 7;
+ break;
+ default:
+ goodval = 0; /* pack_and_unpack() zeros before unpack */
+ break;
+ }
+ if (buf[i] != goodval) {
+ errs++;
+ if (verbose) fprintf(stderr, "buf[%d] = %d; should be %d\n",
+ i, buf[i], goodval);
+ }
+ }
+
+ MPI_Type_free( &newtype );
+
+ return errs;
+}
+
+/* blockindexed_vector_test()
+ *
+ * Tests behavior with a blockindexed of some vector types;
+ * this shouldn't be easily convertable into anything else.
+ *
+ * Returns the number of errors encountered.
+ */
+int blockindexed_vector_test(void)
+{
+#define NELT (18)
+ int buf[NELT] = { -1, -1, -1,
+ 1, -2, 2,
+ -3, -3, -3,
+ -4, -4, -4,
+ 3, -5, 4,
+ 5, -6, 6 };
+ int expected[NELT] = {
+ 0, 0, 0,
+ 1, 0, 2,
+ 0, 0, 0,
+ 0, 0, 0,
+ 3, 0, 4,
+ 5, 0, 6 };
+ int err, errs = 0;
+
+ int i, count = 3;
+ int disp[] = {1, 4, 5};
+ MPI_Datatype vectype, newtype;
+
+ int size, int_size;
+
+ /* create a vector type of 2 ints, skipping one in between */
+ err = MPI_Type_vector(2, 1, 2, MPI_INT, &vectype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating vector type in blockindexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ err = MPI_Type_create_indexed_block(count,
+ 1,
+ disp,
+ vectype,
+ &newtype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating blockindexed type in blockindexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_size(MPI_INT, &int_size);
+
+ err = MPI_Type_size(newtype, &size);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type size in blockindexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ if (size != 6 * int_size) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: size != 6 * int_size in blockindexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_commit(&newtype);
+
+ err = pack_and_unpack((char *) buf, 1, newtype, NELT * sizeof(int));
+ if (err != 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "error packing/unpacking in blockindexed_vector_test()\n");
+ }
+ errs += err;
+ }
+
+ for (i=0; i < NELT; i++) {
+ if (buf[i] != expected[i]) {
+ errs++;
+ if (verbose) fprintf(stderr, "buf[%d] = %d; should be %d\n",
+ i, buf[i], expected[i]);
+ }
+ }
+
+ MPI_Type_free( &vectype );
+ MPI_Type_free( &newtype );
+ return errs;
+}
+
+
+/* pack_and_unpack()
+ *
+ * Perform packing and unpacking of a buffer for the purposes of checking
+ * to see if we are processing a type correctly. Zeros the buffer between
+ * these two operations, so the data described by the type should be in
+ * place upon return but all other regions of the buffer should be zero.
+ *
+ * Parameters:
+ * typebuf - pointer to buffer described by datatype and count that
+ * will be packed and then unpacked into
+ * count, datatype - description of typebuf
+ * typebufsz - size of typebuf; used specifically to zero the buffer
+ * between the pack and unpack steps
+ *
+ */
+static int pack_and_unpack(char *typebuf,
+ int count,
+ MPI_Datatype datatype,
+ int typebufsz)
+{
+ char *packbuf;
+ int err, errs = 0, pack_size, type_size, position;
+
+ err = MPI_Type_size(datatype, &type_size);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Type_size call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+
+ type_size *= count;
+
+ err = MPI_Pack_size(count, datatype, MPI_COMM_SELF, &pack_size);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Pack_size call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+ packbuf = (char *) malloc(pack_size);
+ if (packbuf == NULL) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in malloc call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+
+ position = 0;
+ err = MPI_Pack(typebuf,
+ count,
+ datatype,
+ packbuf,
+ type_size,
+ &position,
+ MPI_COMM_SELF);
+
+ if (position != type_size) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (pack)\n",
+ position, type_size);
+ }
+
+ memset(typebuf, 0, typebufsz);
+ position = 0;
+ err = MPI_Unpack(packbuf,
+ type_size,
+ &position,
+ typebuf,
+ count,
+ datatype,
+ MPI_COMM_SELF);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Unpack call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+ free(packbuf);
+
+ if (position != type_size) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (unpack)\n",
+ position, type_size);
+ }
+
+ return errs;
+}
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 0;
+
+/* tests */
+int blockindexed_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = blockindexed_test();
+ if (err && verbose) fprintf(stderr, "%d errors in blockindexed test.\n",
+ err);
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+/* blockindexed_test()
+ *
+ * Tests behavior with a zero-count blockindexed.
+ *
+ * Returns the number of errors encountered.
+ */
+int blockindexed_test(void)
+{
+ int err, errs = 0;
+
+ int count = 0;
+ MPI_Datatype newtype;
+
+ int size;
+ MPI_Aint extent;
+
+ err = MPI_Type_create_indexed_block(count,
+ 0,
+ (int *) 0,
+ MPI_INT,
+ &newtype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating struct type in blockindexed_test()\n");
+ }
+ errs++;
+ }
+
+ err = MPI_Type_size(newtype, &size);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type size in blockindexed_test()\n");
+ }
+ errs++;
+ }
+
+ if (size != 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: size != 0 in blockindexed_test()\n");
+ }
+ errs++;
+ }
+
+ err = MPI_Type_extent(newtype, &extent);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type extent in blockindexed_test()\n");
+ }
+ errs++;
+ }
+
+ if (extent != 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: extent != 0 in blockindexed_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_free( &newtype );
+
+ return errs;
+}
+
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include "mpitestconf.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+
+static int verbose = 0;
+
+/* tests */
+int builtin_float_test(void);
+int vector_of_vectors_test(void);
+int optimizable_vector_of_basics_test(void);
+int indexed_of_basics_test(void);
+int indexed_of_vectors_test(void);
+int struct_of_basics_test(void);
+
+/* helper functions */
+char *combiner_to_string(int combiner);
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = builtin_float_test();
+ errs += err;
+ if (err) {
+ fprintf(stderr, "Found %d errors in builtin float test.\n", err);
+ }
+
+ err = vector_of_vectors_test();
+ errs += err;
+ if (err) {
+ fprintf(stderr, "Found %d errors in vector of vectors test.\n", err);
+ }
+
+ err = optimizable_vector_of_basics_test();
+ errs += err;
+ if (err) {
+ fprintf(stderr, "Found %d errors in vector of basics test.\n", err);
+ }
+
+ err = indexed_of_basics_test();
+ errs += err;
+ if (err) {
+ fprintf(stderr, "Found %d errors in indexed of basics test.\n", err);
+ }
+
+ err = indexed_of_vectors_test();
+ errs += err;
+ if (err) {
+ fprintf(stderr, "Found %d errors in indexed of vectors test.\n", err);
+ }
+
+#ifdef HAVE_MPI_TYPE_CREATE_STRUCT
+ err = struct_of_basics_test();
+ errs += err;
+#endif
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+/* builtin_float_test()
+ *
+ * Tests functionality of get_envelope() and get_contents() on a MPI_FLOAT.
+ *
+ * Returns the number of errors encountered.
+ */
+int builtin_float_test(void)
+{
+ int nints, nadds, ntypes, combiner;
+
+ int err, errs = 0;
+
+ err = MPI_Type_get_envelope(MPI_FLOAT,
+ &nints,
+ &nadds,
+ &ntypes,
+ &combiner);
+
+ if (combiner != MPI_COMBINER_NAMED) errs++;
+ if (verbose && combiner != MPI_COMBINER_NAMED)
+ fprintf(stderr, "combiner = %s; should be named\n",
+ combiner_to_string(combiner));
+
+ /* Note: it is erroneous to call MPI_Type_get_contents() on a basic. */
+ return errs;
+}
+
+/* vector_of_vectors_test()
+ *
+ * Builds a vector of a vector of ints. Assuming an int array of size 9
+ * integers, and treating the array as a 3x3 2D array, this will grab the
+ * corners.
+ *
+ * Returns the number of errors encountered.
+ */
+int vector_of_vectors_test(void)
+{
+ MPI_Datatype inner_vector, inner_vector_copy;
+ MPI_Datatype outer_vector;
+
+ int nints, nadds, ntypes, combiner, *ints;
+ MPI_Aint *adds = NULL;
+ MPI_Datatype *types;
+
+ int err, errs = 0;
+
+ /* set up type */
+ err = MPI_Type_vector(2,
+ 1,
+ 2,
+ MPI_INT,
+ &inner_vector);
+ if (err != MPI_SUCCESS) {
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs+1;
+ }
+
+ err = MPI_Type_vector(2,
+ 1,
+ 2,
+ inner_vector,
+ &outer_vector);
+ if (err != MPI_SUCCESS) {
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs+1;
+ }
+
+ /* decode outer vector (get envelope, then contents) */
+ err = MPI_Type_get_envelope(outer_vector,
+ &nints,
+ &nadds,
+ &ntypes,
+ &combiner);
+ if (err != MPI_SUCCESS) {
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs+1;
+ }
+
+ if (nints != 3) errs++;
+ if (nadds != 0) errs++;
+ if (ntypes != 1) errs++;
+ if (combiner != MPI_COMBINER_VECTOR) errs++;
+
+ if (verbose) {
+ if (nints != 3) fprintf(stderr,
+ "outer vector nints = %d; should be 3\n",
+ nints);
+ if (nadds != 0) fprintf(stderr,
+ "outer vector nadds = %d; should be 0\n",
+ nadds);
+ if (ntypes != 1) fprintf(stderr,
+ "outer vector ntypes = %d; should be 1\n",
+ ntypes);
+ if (combiner != MPI_COMBINER_VECTOR)
+ fprintf(stderr, "outer vector combiner = %s; should be vector\n",
+ combiner_to_string(combiner));
+ }
+ if (errs) {
+ if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
+ return errs;
+ }
+
+ ints = malloc(nints * sizeof(*ints));
+ if (nadds) adds = malloc(nadds * sizeof(*adds));
+ types = malloc(ntypes * sizeof(*types));
+
+ /* get contents of outer vector */
+ err = MPI_Type_get_contents(outer_vector,
+ nints,
+ nadds,
+ ntypes,
+ ints,
+ adds,
+ types);
+
+ if (ints[0] != 2) errs++;
+ if (ints[1] != 1) errs++;
+ if (ints[2] != 2) errs++;
+
+ if (verbose) {
+ if (ints[0] != 2) fprintf(stderr,
+ "outer vector count = %d; should be 2\n",
+ ints[0]);
+ if (ints[1] != 1) fprintf(stderr,
+ "outer vector blocklength = %d; should be 1\n",
+ ints[1]);
+ if (ints[2] != 2) fprintf(stderr, "outer vector stride = %d; should be 2\n",
+ ints[2]);
+ }
+ if (errs) {
+ if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
+ return errs;
+ }
+
+ inner_vector_copy = types[0];
+ free(ints);
+ if (nadds) free(adds);
+ free(types);
+
+ /* decode inner vector */
+ err = MPI_Type_get_envelope(inner_vector_copy,
+ &nints,
+ &nadds,
+ &ntypes,
+ &combiner);
+ if (err != MPI_SUCCESS) {
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs+1;
+ }
+
+ if (nints != 3) errs++;
+ if (nadds != 0) errs++;
+ if (ntypes != 1) errs++;
+ if (combiner != MPI_COMBINER_VECTOR) errs++;
+
+ if (verbose) {
+ if (nints != 3) fprintf(stderr,
+ "inner vector nints = %d; should be 3\n",
+ nints);
+ if (nadds != 0) fprintf(stderr,
+ "inner vector nadds = %d; should be 0\n",
+ nadds);
+ if (ntypes != 1) fprintf(stderr,
+ "inner vector ntypes = %d; should be 1\n",
+ ntypes);
+ if (combiner != MPI_COMBINER_VECTOR)
+ fprintf(stderr, "inner vector combiner = %s; should be vector\n",
+ combiner_to_string(combiner));
+ }
+ if (errs) {
+ if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
+ return errs;
+ }
+
+ ints = malloc(nints * sizeof(*ints));
+ if (nadds) adds = malloc(nadds * sizeof(*adds));
+ types = malloc(ntypes * sizeof(*types));
+
+ err = MPI_Type_get_contents(inner_vector_copy,
+ nints,
+ nadds,
+ ntypes,
+ ints,
+ adds,
+ types);
+
+ if (ints[0] != 2) errs++;
+ if (ints[1] != 1) errs++;
+ if (ints[2] != 2) errs++;
+
+ if (verbose) {
+ if (ints[0] != 2) fprintf(stderr,
+ "inner vector count = %d; should be 2\n",
+ ints[0]);
+ if (ints[1] != 1) fprintf(stderr,
+ "inner vector blocklength = %d; should be 1\n",
+ ints[1]);
+ if (ints[2] != 2) fprintf(stderr,
+ "inner vector stride = %d; should be 2\n",
+ ints[2]);
+ }
+ if (errs) {
+ if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
+ return errs;
+ }
+
+ free(ints);
+ if (nadds) free(adds);
+ free(types);
+
+ MPI_Type_free( &inner_vector_copy );
+ MPI_Type_free( &inner_vector );
+ MPI_Type_free( &outer_vector );
+
+ return 0;
+}
+
+/* optimizable_vector_of_basics_test()
+ *
+ * Builds a vector of ints. Count is 10, blocksize is 2, stride is 2, so this
+ * is equivalent to a contig of 20. But remember...we should get back our
+ * suboptimal values under MPI-2.
+ *
+ * Returns the number of errors encountered.
+ */
+int optimizable_vector_of_basics_test(void)
+{
+ MPI_Datatype parent_type;
+
+ int nints, nadds, ntypes, combiner, *ints;
+ MPI_Aint *adds = NULL;
+ MPI_Datatype *types;
+
+ int err, errs = 0;
+
+ /* set up type */
+ err = MPI_Type_vector(10,
+ 2,
+ 2,
+ MPI_INT,
+ &parent_type);
+
+ /* decode */
+ err = MPI_Type_get_envelope(parent_type,
+ &nints,
+ &nadds,
+ &ntypes,
+ &combiner);
+
+ if (nints != 3) errs++;
+ if (nadds != 0) errs++;
+ if (ntypes != 1) errs++;
+ if (combiner != MPI_COMBINER_VECTOR) errs++;
+
+ if (verbose) {
+ if (nints != 3) fprintf(stderr, "nints = %d; should be 3\n", nints);
+ if (nadds != 0) fprintf(stderr, "nadds = %d; should be 0\n", nadds);
+ if (ntypes != 1) fprintf(stderr, "ntypes = %d; should be 1\n", ntypes);
+ if (combiner != MPI_COMBINER_VECTOR)
+ fprintf(stderr, "combiner = %s; should be vector\n",
+ combiner_to_string(combiner));
+ }
+
+ ints = malloc(nints * sizeof(*ints));
+ if (nadds) adds = malloc(nadds * sizeof(*adds));
+ types = malloc(ntypes *sizeof(*types));
+
+ err = MPI_Type_get_contents(parent_type,
+ nints,
+ nadds,
+ ntypes,
+ ints,
+ adds,
+ types);
+
+ if (ints[0] != 10) errs++;
+ if (ints[1] != 2) errs++;
+ if (ints[2] != 2) errs++;
+ if (types[0] != MPI_INT) errs++;
+
+ if (verbose) {
+ if (ints[0] != 10) fprintf(stderr, "count = %d; should be 10\n",
+ ints[0]);
+ if (ints[1] != 2) fprintf(stderr, "blocklength = %d; should be 2\n",
+ ints[1]);
+ if (ints[2] != 2) fprintf(stderr, "stride = %d; should be 2\n",
+ ints[2]);
+ if (types[0] != MPI_INT) fprintf(stderr, "type is not MPI_INT\n");
+ }
+
+ free(ints);
+ if (nadds) free(adds);
+ free(types);
+
+ MPI_Type_free( &parent_type );
+
+ return errs;
+}
+
+
+/* indexed_of_basics_test(void)
+ *
+ * Simple indexed type.
+ *
+ * Returns number of errors encountered.
+ */
+int indexed_of_basics_test(void)
+{
+ MPI_Datatype parent_type;
+ int s_count = 3, s_blocklengths[3] = { 3, 2, 1 };
+ int s_displacements[3] = { 10, 20, 30 };
+
+ int nints, nadds, ntypes, combiner, *ints;
+ MPI_Aint *adds = NULL;
+ MPI_Datatype *types;
+
+ int err, errs = 0;
+
+ /* set up type */
+ err = MPI_Type_indexed(s_count,
+ s_blocklengths,
+ s_displacements,
+ MPI_INT,
+ &parent_type);
+
+ /* decode */
+ err = MPI_Type_get_envelope(parent_type,
+ &nints,
+ &nadds,
+ &ntypes,
+ &combiner);
+
+ if (nints != 7) errs++;
+ if (nadds != 0) errs++;
+ if (ntypes != 1) errs++;
+ if (combiner != MPI_COMBINER_INDEXED) errs++;
+
+ if (verbose) {
+ if (nints != 7) fprintf(stderr, "nints = %d; should be 7\n", nints);
+ if (nadds != 0) fprintf(stderr, "nadds = %d; should be 0\n", nadds);
+ if (ntypes != 1) fprintf(stderr, "ntypes = %d; should be 1\n", ntypes);
+ if (combiner != MPI_COMBINER_INDEXED)
+ fprintf(stderr, "combiner = %s; should be indexed\n",
+ combiner_to_string(combiner));
+ }
+
+ ints = malloc(nints * sizeof(*ints));
+ if (nadds) adds = malloc(nadds * sizeof(*adds));
+ types = malloc(ntypes *sizeof(*types));
+
+ err = MPI_Type_get_contents(parent_type,
+ nints,
+ nadds,
+ ntypes,
+ ints,
+ adds,
+ types);
+
+ if (ints[0] != s_count) errs++;
+ if (ints[1] != s_blocklengths[0]) errs++;
+ if (ints[2] != s_blocklengths[1]) errs++;
+ if (ints[3] != s_blocklengths[2]) errs++;
+ if (ints[4] != s_displacements[0]) errs++;
+ if (ints[5] != s_displacements[1]) errs++;
+ if (ints[6] != s_displacements[2]) errs++;
+ if (types[0] != MPI_INT) errs++;
+
+ if (verbose) {
+ if (ints[0] != s_count)
+ fprintf(stderr, "count = %d; should be %d\n", ints[0], s_count);
+ if (ints[1] != s_blocklengths[0])
+ fprintf(stderr, "blocklength[0] = %d; should be %d\n", ints[1], s_blocklengths[0]);
+ if (ints[2] != s_blocklengths[1])
+ fprintf(stderr, "blocklength[1] = %d; should be %d\n", ints[2], s_blocklengths[1]);
+ if (ints[3] != s_blocklengths[2])
+ fprintf(stderr, "blocklength[2] = %d; should be %d\n", ints[3], s_blocklengths[2]);
+ if (ints[4] != s_displacements[0])
+ fprintf(stderr, "displacement[0] = %d; should be %d\n", ints[4], s_displacements[0]);
+ if (ints[5] != s_displacements[1])
+ fprintf(stderr, "displacement[1] = %d; should be %d\n", ints[5], s_displacements[1]);
+ if (ints[6] != s_displacements[2])
+ fprintf(stderr, "displacement[2] = %d; should be %d\n", ints[6], s_displacements[2]);
+ if (types[0] != MPI_INT) fprintf(stderr, "type[0] does not match\n");
+ }
+
+ free(ints);
+ if (nadds) free(adds);
+ free(types);
+
+ MPI_Type_free( &parent_type );
+ return errs;
+}
+
+/* indexed_of_vectors_test()
+ *
+ * Builds an indexed type of vectors of ints.
+ *
+ * Returns the number of errors encountered.
+ */
+int indexed_of_vectors_test(void)
+{
+ MPI_Datatype inner_vector, inner_vector_copy;
+ MPI_Datatype outer_indexed;
+
+ int i_count = 3, i_blocklengths[3] = { 3, 2, 1 };
+ int i_displacements[3] = { 10, 20, 30 };
+
+ int nints, nadds, ntypes, combiner, *ints;
+ MPI_Aint *adds = NULL;
+ MPI_Datatype *types;
+
+ int err, errs = 0;
+
+ /* set up type */
+ err = MPI_Type_vector(2,
+ 1,
+ 2,
+ MPI_INT,
+ &inner_vector);
+ if (err != MPI_SUCCESS) {
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs+1;
+ }
+
+ err = MPI_Type_indexed(i_count,
+ i_blocklengths,
+ i_displacements,
+ inner_vector,
+ &outer_indexed);
+ if (err != MPI_SUCCESS) {
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs+1;
+ }
+
+ /* decode outer vector (get envelope, then contents) */
+ err = MPI_Type_get_envelope(outer_indexed,
+ &nints,
+ &nadds,
+ &ntypes,
+ &combiner);
+ if (err != MPI_SUCCESS) {
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs+1;
+ }
+
+ if (nints != 7) errs++;
+ if (nadds != 0) errs++;
+ if (ntypes != 1) errs++;
+ if (combiner != MPI_COMBINER_INDEXED) errs++;
+
+ if (verbose) {
+ if (nints != 7) fprintf(stderr, "nints = %d; should be 7\n", nints);
+ if (nadds != 0) fprintf(stderr, "nadds = %d; should be 0\n", nadds);
+ if (ntypes != 1) fprintf(stderr, "ntypes = %d; should be 1\n", ntypes);
+ if (combiner != MPI_COMBINER_INDEXED)
+ fprintf(stderr, "combiner = %s; should be indexed\n",
+ combiner_to_string(combiner));
+ }
+
+ if (errs) {
+ if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
+ return errs;
+ }
+
+ ints = malloc(nints * sizeof(*ints));
+ if (nadds) adds = malloc(nadds * sizeof(*adds));
+ types = malloc(ntypes * sizeof(*types));
+
+ /* get contents of outer vector */
+ err = MPI_Type_get_contents(outer_indexed,
+ nints,
+ nadds,
+ ntypes,
+ ints,
+ adds,
+ types);
+
+ if (ints[0] != i_count) errs++;
+ if (ints[1] != i_blocklengths[0]) errs++;
+ if (ints[2] != i_blocklengths[1]) errs++;
+ if (ints[3] != i_blocklengths[2]) errs++;
+ if (ints[4] != i_displacements[0]) errs++;
+ if (ints[5] != i_displacements[1]) errs++;
+ if (ints[6] != i_displacements[2]) errs++;
+
+ if (verbose) {
+ if (ints[0] != i_count)
+ fprintf(stderr, "count = %d; should be %d\n", ints[0], i_count);
+ if (ints[1] != i_blocklengths[0])
+ fprintf(stderr, "blocklength[0] = %d; should be %d\n", ints[1], i_blocklengths[0]);
+ if (ints[2] != i_blocklengths[1])
+ fprintf(stderr, "blocklength[1] = %d; should be %d\n", ints[2], i_blocklengths[1]);
+ if (ints[3] != i_blocklengths[2])
+ fprintf(stderr, "blocklength[2] = %d; should be %d\n", ints[3], i_blocklengths[2]);
+ if (ints[4] != i_displacements[0])
+ fprintf(stderr, "displacement[0] = %d; should be %d\n", ints[4], i_displacements[0]);
+ if (ints[5] != i_displacements[1])
+ fprintf(stderr, "displacement[1] = %d; should be %d\n", ints[5], i_displacements[1]);
+ if (ints[6] != i_displacements[2])
+ fprintf(stderr, "displacement[2] = %d; should be %d\n", ints[6], i_displacements[2]);
+ }
+
+ if (errs) {
+ if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
+ return errs;
+ }
+
+ inner_vector_copy = types[0];
+ free(ints);
+ if (nadds) free(adds);
+ free(types);
+
+ /* decode inner vector */
+ err = MPI_Type_get_envelope(inner_vector_copy,
+ &nints,
+ &nadds,
+ &ntypes,
+ &combiner);
+ if (err != MPI_SUCCESS) {
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs+1;
+ }
+
+ if (nints != 3) errs++;
+ if (nadds != 0) errs++;
+ if (ntypes != 1) errs++;
+ if (combiner != MPI_COMBINER_VECTOR) errs++;
+
+ if (verbose) {
+ if (nints != 3) fprintf(stderr,
+ "inner vector nints = %d; should be 3\n",
+ nints);
+ if (nadds != 0) fprintf(stderr,
+ "inner vector nadds = %d; should be 0\n",
+ nadds);
+ if (ntypes != 1) fprintf(stderr,
+ "inner vector ntypes = %d; should be 1\n",
+ ntypes);
+ if (combiner != MPI_COMBINER_VECTOR)
+ fprintf(stderr, "inner vector combiner = %s; should be vector\n",
+ combiner_to_string(combiner));
+ }
+ if (errs) {
+ if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
+ return errs;
+ }
+
+ ints = malloc(nints * sizeof(*ints));
+ if (nadds) adds = malloc(nadds * sizeof(*adds));
+ types = malloc(ntypes * sizeof(*types));
+
+ err = MPI_Type_get_contents(inner_vector_copy,
+ nints,
+ nadds,
+ ntypes,
+ ints,
+ adds,
+ types);
+
+ if (ints[0] != 2) errs++;
+ if (ints[1] != 1) errs++;
+ if (ints[2] != 2) errs++;
+
+ if (verbose) {
+ if (ints[0] != 2) fprintf(stderr,
+ "inner vector count = %d; should be 2\n",
+ ints[0]);
+ if (ints[1] != 1) fprintf(stderr,
+ "inner vector blocklength = %d; should be 1\n",
+ ints[1]);
+ if (ints[2] != 2) fprintf(stderr,
+ "inner vector stride = %d; should be 2\n",
+ ints[2]);
+ }
+ if (errs) {
+ if (verbose) fprintf(stderr, "aborting after %d errors\n", errs);
+ return errs;
+ }
+
+ free(ints);
+ if (nadds) free(adds);
+ free(types);
+
+ MPI_Type_free( &inner_vector_copy );
+ MPI_Type_free( &inner_vector );
+ MPI_Type_free( &outer_indexed );
+
+ return 0;
+}
+
+
+#ifdef HAVE_MPI_TYPE_CREATE_STRUCT
+/* struct_of_basics_test(void)
+ *
+ * There's nothing simple about structs :). Although this is an easy one.
+ *
+ * Returns number of errors encountered.
+ *
+ * NOT TESTED.
+ */
+int struct_of_basics_test(void)
+{
+ MPI_Datatype parent_type;
+ int s_count = 3, s_blocklengths[3] = { 3, 2, 1 };
+ MPI_Aint s_displacements[3] = { 10, 20, 30 };
+ MPI_Datatype s_types[3] = { MPI_CHAR, MPI_INT, MPI_FLOAT };
+
+ int nints, nadds, ntypes, combiner, *ints;
+ MPI_Aint *adds = NULL;
+ MPI_Datatype *types;
+
+ int err, errs = 0;
+
+ /* set up type */
+ err = MPI_Type_create_struct(s_count,
+ s_blocklengths,
+ s_displacements,
+ s_types,
+ &parent_type);
+
+ /* decode */
+ err = MPI_Type_get_envelope(parent_type,
+ &nints,
+ &nadds,
+ &ntypes,
+ &combiner);
+
+ if (nints != 4) errs++;
+ if (nadds != 3) errs++;
+ if (ntypes != 3) errs++;
+ if (combiner != MPI_COMBINER_STRUCT) errs++;
+
+ if (verbose) {
+ if (nints != 4) fprintf(stderr, "nints = %d; should be 3\n", nints);
+ if (nadds != 3) fprintf(stderr, "nadds = %d; should be 0\n", nadds);
+ if (ntypes != 3) fprintf(stderr, "ntypes = %d; should be 3\n", ntypes);
+ if (combiner != MPI_COMBINER_STRUCT)
+ fprintf(stderr, "combiner = %s; should be struct\n",
+ combiner_to_string(combiner));
+ }
+
+ ints = malloc(nints * sizeof(*ints));
+ adds = malloc(nadds * sizeof(*adds));
+ types = malloc(ntypes *sizeof(*types));
+
+ err = MPI_Type_get_contents(parent_type,
+ nints,
+ nadds,
+ ntypes,
+ ints,
+ adds,
+ types);
+
+ if (ints[0] != s_count) errs++;
+ if (ints[1] != s_blocklengths[0]) errs++;
+ if (ints[2] != s_blocklengths[1]) errs++;
+ if (ints[3] != s_blocklengths[2]) errs++;
+ if (adds[0] != s_displacements[0]) errs++;
+ if (adds[1] != s_displacements[1]) errs++;
+ if (adds[2] != s_displacements[2]) errs++;
+ if (types[0] != s_types[0]) errs++;
+ if (types[1] != s_types[1]) errs++;
+ if (types[2] != s_types[2]) errs++;
+
+ if (verbose) {
+ if (ints[0] != s_count)
+ fprintf(stderr, "count = %d; should be %d\n", ints[0], s_count);
+ if (ints[1] != s_blocklengths[0])
+ fprintf(stderr, "blocklength[0] = %d; should be %d\n", ints[1], s_blocklengths[0]);
+ if (ints[2] != s_blocklengths[1])
+ fprintf(stderr, "blocklength[1] = %d; should be %d\n", ints[2], s_blocklengths[1]);
+ if (ints[3] != s_blocklengths[2])
+ fprintf(stderr, "blocklength[2] = %d; should be %d\n", ints[3], s_blocklengths[2]);
+ if (adds[0] != s_displacements[0])
+ fprintf(stderr, "displacement[0] = %d; should be %d\n", adds[0], s_displacements[0]);
+ if (adds[1] != s_displacements[1])
+ fprintf(stderr, "displacement[1] = %d; should be %d\n", adds[1], s_displacements[1]);
+ if (adds[2] != s_displacements[2])
+ fprintf(stderr, "displacement[2] = %d; should be %d\n", adds[2], s_displacements[2]);
+ if (types[0] != s_types[0])
+ fprintf(stderr, "type[0] does not match\n");
+ if (types[1] != s_types[1])
+ fprintf(stderr, "type[1] does not match\n");
+ if (types[2] != s_types[2])
+ fprintf(stderr, "type[2] does not match\n");
+ }
+
+ free(ints);
+ free(adds);
+ free(types);
+
+ MPI_Type_free( &parent_type );
+
+ return errs;
+}
+#endif
+
+/* combiner_to_string(combiner)
+ *
+ * Converts a numeric combiner into a pointer to a string used for printing.
+ */
+char *combiner_to_string(int combiner)
+{
+ static char c_named[] = "named";
+ static char c_contig[] = "contig";
+ static char c_vector[] = "vector";
+ static char c_hvector[] = "hvector";
+ static char c_indexed[] = "indexed";
+ static char c_hindexed[] = "hindexed";
+ static char c_struct[] = "struct";
+#ifdef HAVE_MPI2_COMBINERS
+ static char c_dup[] = "dup";
+ static char c_hvector_integer[] = "hvector_integer";
+ static char c_hindexed_integer[] = "hindexed_integer";
+ static char c_indexed_block[] = "indexed_block";
+ static char c_struct_integer[] = "struct_integer";
+ static char c_subarray[] = "subarray";
+ static char c_darray[] = "darray";
+ static char c_f90_real[] = "f90_real";
+ static char c_f90_complex[] = "f90_complex";
+ static char c_f90_integer[] = "f90_integer";
+ static char c_resized[] = "resized";
+#endif
+
+ if (combiner == MPI_COMBINER_NAMED) return c_named;
+ if (combiner == MPI_COMBINER_CONTIGUOUS) return c_contig;
+ if (combiner == MPI_COMBINER_VECTOR) return c_vector;
+ if (combiner == MPI_COMBINER_HVECTOR) return c_hvector;
+ if (combiner == MPI_COMBINER_INDEXED) return c_indexed;
+ if (combiner == MPI_COMBINER_HINDEXED) return c_hindexed;
+ if (combiner == MPI_COMBINER_STRUCT) return c_struct;
+#ifdef HAVE_MPI2_COMBINERS
+ if (combiner == MPI_COMBINER_DUP) return c_dup;
+ if (combiner == MPI_COMBINER_HVECTOR_INTEGER) return c_hvector_integer;
+ if (combiner == MPI_COMBINER_HINDEXED_INTEGER) return c_hindexed_integer;
+ if (combiner == MPI_COMBINER_INDEXED_BLOCK) return c_indexed_block;
+ if (combiner == MPI_COMBINER_STRUCT_INTEGER) return c_struct_integer;
+ if (combiner == MPI_COMBINER_SUBARRAY) return c_subarray;
+ if (combiner == MPI_COMBINER_DARRAY) return c_darray;
+ if (combiner == MPI_COMBINER_F90_REAL) return c_f90_real;
+ if (combiner == MPI_COMBINER_F90_COMPLEX) return c_f90_complex;
+ if (combiner == MPI_COMBINER_F90_INTEGER) return c_f90_integer;
+ if (combiner == MPI_COMBINER_RESIZED) return c_resized;
+#endif
+
+ return NULL;
+}
+
+int parse_args(int argc, char **argv)
+{
+#ifdef HAVE_GET_OPT
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+#else
+#endif
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 0;
+
+/* tests */
+int contig_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = contig_test();
+ if (err && verbose) fprintf(stderr, "%d errors in contig test.\n",
+ err);
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+/* contig_test()
+ *
+ * Tests behavior with a zero-count contig.
+ *
+ * Returns the number of errors encountered.
+ */
+int contig_test(void)
+{
+ int err, errs = 0;
+
+ int count = 0;
+ MPI_Datatype newtype;
+
+ int size;
+ MPI_Aint extent;
+
+ err = MPI_Type_contiguous(count,
+ MPI_INT,
+ &newtype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating type in contig_test()\n");
+ }
+ errs++;
+ }
+
+ err = MPI_Type_size(newtype, &size);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type size in contig_test()\n");
+ }
+ errs++;
+ }
+
+ if (size != 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: size != 0 in contig_test()\n");
+ }
+ errs++;
+ }
+
+ err = MPI_Type_extent(newtype, &extent);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type extent in contig_test()\n");
+ }
+ errs++;
+ }
+
+ if (extent != 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: extent != 0 in contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_free( &newtype );
+
+ return errs;
+}
+
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ *
+ * (C) 2003 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+
+/*
+ * This test checks to see if we can create a simple datatype
+ * made from many contiguous copies of a single struct. The
+ * struct is built with monotone decreasing displacements to
+ * avoid any struct->contig optimizations.
+ */
+
+int main( int argc, char **argv )
+{
+ int blocklens[8], psize, i, rank;
+ MPI_Aint displs[8];
+ MPI_Datatype oldtypes[8];
+ MPI_Datatype ntype1, ntype2;
+
+ MPI_Init( &argc, &argv );
+ MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+
+ for (i=0; i<8; i++) {
+ blocklens[i] = 1;
+ displs[i] = (7-i) * sizeof(long);
+ oldtypes[i] = MPI_LONG;
+ }
+ MPI_Type_struct( 8, blocklens, displs, oldtypes, &ntype1 );
+ MPI_Type_contiguous( 65536, ntype1, &ntype2 );
+ MPI_Type_commit( &ntype2 );
+
+ MPI_Pack_size( 2, ntype2, MPI_COMM_WORLD, &psize );
+
+ MPI_Type_free( &ntype2 );
+ MPI_Type_free( &ntype1 );
+
+ /* The only failure mode has been SEGV or aborts within the datatype
+ routines */
+ if (rank == 0) {
+ printf( " No Errors\n" );
+ }
+
+ MPI_Finalize();
+ return 0;
+}
--- /dev/null
+/* -*- Mode: c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2012 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+
+/* This test checks for the existence of four new C++ named predefined datatypes
+ * that should be accessible from C (and Fortran, not tested here). */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+
+/* assert-like macro that bumps the err count and emits a message */
+#define check(x_) \
+ do { \
+ if (!(x_)) { \
+ ++errs; \
+ if (errs < 10) { \
+ fprintf(stderr, "check failed: (%s), line %d\n", #x_, __LINE__); \
+ } \
+ } \
+ } while (0)
+
+int main(int argc, char *argv[])
+{
+ int errs = 0;
+ int wrank, wsize;
+ int size;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
+ MPI_Comm_size(MPI_COMM_WORLD, &wsize);
+
+ /* perhaps the MPI library has no CXX support, in which case let's assume
+ * that these constants exist and were set to MPI_DATATYPE_NULL (standard
+ * MPICH behavior). */
+#define check_type(type_) \
+ do { \
+ size = -1; \
+ if (type_ != MPI_DATATYPE_NULL) { \
+ MPI_Type_size(type_, &size); \
+ check(size > 0); \
+ } \
+ } while (0)
+
+ check_type(MPI_CXX_BOOL);
+ check_type(MPI_CXX_FLOAT_COMPLEX);
+ check_type(MPI_CXX_DOUBLE_COMPLEX);
+ check_type(MPI_CXX_LONG_DOUBLE_COMPLEX);
+
+ MPI_Reduce((wrank == 0 ? MPI_IN_PLACE : &errs), &errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (wrank == 0) {
+ if (errs) {
+ printf("found %d errors\n", errs);
+ }
+ else {
+ printf(" No errors\n");
+ }
+ }
+
+ MPI_Finalize();
+
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ * (C) 2012 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+int AllocateGrid( int nx, int ny, int **srcArray, int **destArray );
+int PackUnpack( MPI_Datatype, const int [], int[], int );
+
+int main( int argc, char *argv[] )
+{
+ int errs = 0;
+ int wrank, wsize;
+ int gsizes[3], distribs[3], dargs[3], psizes[3];
+ int px, py, nx, ny, rx, ry, bx, by;
+ int *srcArray=NULL, *destArray=NULL;
+ int i, j, ii, jj, loc;
+ MPI_Datatype darraytype;
+
+ MTest_Init( 0, 0 );
+ MPI_Comm_rank( MPI_COMM_WORLD, &wrank );
+ MPI_Comm_size( MPI_COMM_WORLD, &wsize );
+
+ /* Test 1: Simple, 1-D cyclic decomposition */
+ if (AllocateGrid( 1, 3*wsize, &srcArray, &destArray ) ) {
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+
+ /* Simple cyclic with 1-dim global array */
+ gsizes[0] = 3*wsize;
+ distribs[0] = MPI_DISTRIBUTE_CYCLIC;
+ dargs[0] = 1;
+ psizes[0] = wsize;
+ MPI_Type_create_darray( wsize, wrank, 1,
+ gsizes, distribs, dargs, psizes,
+ MPI_ORDER_C, MPI_INT, &darraytype );
+
+ /* Check the created datatype. Because cyclic, should represent
+ a strided type */
+ if (PackUnpack( darraytype, srcArray, destArray, 3 )) {
+ fprintf( stderr, "Error in pack/unpack check\n" );
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+ /* Now, check for correct data */
+ for (i=0; i<3; i++) {
+ if (destArray[i] != wrank + i * wsize) {
+ fprintf( stderr, "1D: %d: Expected %d but saw %d\n",
+ i, wrank + i * wsize, destArray[i] );
+ errs++;
+ }
+ }
+
+ free( destArray );
+ free( srcArray );
+ MPI_Type_free( &darraytype );
+
+ /* Test 2: Simple, 1-D cyclic decomposition, with block size=2 */
+ if (AllocateGrid( 1, 4*wsize, &srcArray, &destArray ) ) {
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+
+ /* Simple cyclic with 1-dim global array */
+ gsizes[0] = 4*wsize;
+ distribs[0] = MPI_DISTRIBUTE_CYCLIC;
+ dargs[0] = 2;
+ psizes[0] = wsize;
+ MPI_Type_create_darray( wsize, wrank, 1,
+ gsizes, distribs, dargs, psizes,
+ MPI_ORDER_C, MPI_INT, &darraytype );
+
+ /* Check the created datatype. Because cyclic, should represent
+ a strided type */
+ if (PackUnpack( darraytype, srcArray, destArray, 4 )) {
+ fprintf( stderr, "Error in pack/unpack check\n" );
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+ loc = 0;
+ /* for each cyclic element */
+ for (i=0; i<2; i++) {
+ /* For each element in block */
+ for (j=0; j<2; j++) {
+ if (destArray[loc] != 2*wrank + i * 2*wsize + j) {
+ fprintf( stderr, "1D(2): %d: Expected %d but saw %d\n",
+ i, 2*wrank + i * 2*wsize+j, destArray[loc] );
+ errs++;
+ }
+ loc++;
+ }
+ }
+
+ free( destArray );
+ free( srcArray );
+ MPI_Type_free( &darraytype );
+
+ /* 2D: Create some 2-D decompositions */
+ px = wsize/2;
+ py = 2;
+ rx = wrank % px;
+ ry = wrank / px;
+
+ if (px * py != wsize) {
+ fprintf( stderr, "An even number of processes is required\n" );
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+
+ /* Cyclic/Cyclic */
+ if (AllocateGrid( 5*px, 7*py, &srcArray, &destArray )) {
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+
+ /* Simple cyclic/cyclic. Note in C order, the [1] index varies most
+ rapidly */
+ gsizes[0] = ny = 7*py;
+ gsizes[1] = nx = 5*px;
+ distribs[0] = MPI_DISTRIBUTE_CYCLIC;
+ distribs[1] = MPI_DISTRIBUTE_CYCLIC;
+ dargs[0] = 1;
+ dargs[1] = 1;
+ psizes[0] = py;
+ psizes[1] = px;
+ MPI_Type_create_darray( wsize, wrank, 2,
+ gsizes, distribs, dargs, psizes,
+ MPI_ORDER_C, MPI_INT, &darraytype );
+
+ /* Check the created datatype. Because cyclic, should represent
+ a strided type */
+ if (PackUnpack( darraytype, srcArray, destArray, 5*7 )) {
+ fprintf( stderr, "Error in pack/unpack check\n" );
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+
+ loc = 0;
+ for (j=0; j<7; j++) {
+ for (i=0; i<5; i++) {
+ int expected = rx + ry * nx + i * px + j * nx * py;
+ if (destArray[loc] != expected) {
+ errs++;
+ fprintf( stderr, "2D(cc): [%d,%d] = %d, expected %d\n",
+ i, j, destArray[loc], expected );
+ }
+ loc++;
+ }
+ }
+
+ free( srcArray );
+ free( destArray );
+ MPI_Type_free( &darraytype );
+
+ /* Cyclic(2)/Cyclic(3) */
+ if (AllocateGrid( 6*px, 4*py, &srcArray, &destArray )) {
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+
+ /* Block cyclic/cyclic. Note in C order, the [1] index varies most
+ rapidly */
+ gsizes[0] = ny = 4*py;
+ gsizes[1] = nx = 6*px;
+ distribs[0] = MPI_DISTRIBUTE_CYCLIC;
+ distribs[1] = MPI_DISTRIBUTE_CYCLIC;
+ dargs[0] = by = 2;
+ dargs[1] = bx = 3;
+ psizes[0] = py;
+ psizes[1] = px;
+ MPI_Type_create_darray( wsize, wrank, 2,
+ gsizes, distribs, dargs, psizes,
+ MPI_ORDER_C, MPI_INT, &darraytype );
+
+ /* Check the created datatype. Because cyclic, should represent
+ a strided type */
+ if (PackUnpack( darraytype, srcArray, destArray, 4*6 )) {
+ fprintf( stderr, "Error in pack/unpack check\n" );
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+
+ loc = 0;
+ for (j=0; j<4/by; j++) {
+ for (jj=0; jj<by; jj++) {
+ for (i=0; i<6/bx; i++) {
+ for (ii=0; ii<bx; ii++) {
+ int expected = rx * bx + ry * by * nx + i * bx * px + ii +
+ (j * by * py + jj) * nx;
+ if (destArray[loc] != expected) {
+ errs++;
+ fprintf( stderr, "2D(c(2)c(3)): [%d,%d] = %d, expected %d\n",
+ i*bx+ii, j*by+jj, destArray[loc], expected );
+ }
+ loc++;
+ }
+ }
+ }
+ }
+
+ free( srcArray );
+ free( destArray );
+ MPI_Type_free( &darraytype );
+
+ MTest_Finalize( errs );
+ MPI_Finalize();
+
+ return 0;
+}
+
+int AllocateGrid( int nx, int ny, int **srcArray, int **destArray )
+{
+ int *src, *dest;
+ int i, j;
+ src = (int *)malloc( nx*ny*sizeof(int) );
+ dest = (int *)malloc( nx*ny*sizeof(int) );
+ if (!src || !dest) {
+ fprintf( stderr, "Unable to allocate test arrays of size (%d x %d)\n",
+ nx, ny );
+ return 1;
+ }
+ for (i=0; i<nx*ny; i++) {
+ src[i] = i;
+ dest[i] = -i-1;
+ }
+ *srcArray = src;
+ *destArray = dest;
+ return 0;
+}
+
+/* Extract the source array into the dest array using the DARRAY datatype.
+ "count" integers are returned in destArray */
+int PackUnpack( MPI_Datatype darraytype, const int srcArray[], int destArray[],
+ int count )
+{
+ int packsize, position;
+ int *packArray;
+
+ MPI_Type_commit( &darraytype );
+ MPI_Pack_size( 1, darraytype, MPI_COMM_SELF, &packsize );
+ packArray = (int *)malloc( packsize );
+ if (!packArray) {
+ fprintf( stderr, "Unable to allocate pack array of size %d\n",
+ packsize );
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+ position = 0;
+ MPI_Pack( (int*)srcArray, 1, darraytype, packArray, packsize, &position,
+ MPI_COMM_SELF );
+ packsize = position;
+ position = 0;
+ MPI_Unpack( packArray, packsize, &position, destArray, count, MPI_INT,
+ MPI_COMM_SELF );
+ free( packArray );
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpitest.h"
+
+/*
+ The default behavior of the test routines should be to briefly indicate
+ the cause of any errors - in this test, that means that verbose needs
+ to be set. Verbose should turn on output that is independent of error
+ levels.
+*/
+static int verbose = 1;
+
+/* tests */
+int darray_2d_c_test1(void);
+int darray_4d_c_test1(void);
+
+/* helper functions */
+static int parse_args(int argc, char **argv);
+static int pack_and_unpack(char *typebuf,
+ int count,
+ MPI_Datatype datatype,
+ int typebufsz);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MTest_Init( &argc, &argv );
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = darray_2d_c_test1();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in 2d darray c test 1.\n", err);
+ errs += err;
+
+ err = darray_4d_c_test1();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in 4d darray c test 1.\n", err);
+ errs += err;
+
+ /* print message and exit */
+ /* Allow the use of more than one process - some MPI implementations
+ (including IBM's) check that the number of processes given to
+ Type_create_darray is no larger than MPI_COMM_WORLD */
+
+ MTest_Finalize( errs );
+ MPI_Finalize();
+ return 0;
+}
+
+/* darray_2d_test1()
+ *
+ * Performs a sequence of tests building darrays with single-element
+ * blocks, running through all the various positions that the element might
+ * come from.
+ *
+ * Returns the number of errors encountered.
+ */
+int darray_2d_c_test1(void)
+{
+ MPI_Datatype darray;
+ int array[9]; /* initialized below */
+ int array_size[2] = {3, 3};
+ int array_distrib[2] = {MPI_DISTRIBUTE_BLOCK, MPI_DISTRIBUTE_BLOCK};
+ int array_dargs[2] = {MPI_DISTRIBUTE_DFLT_DARG, MPI_DISTRIBUTE_DFLT_DARG};
+ int array_psizes[2] = {3, 3};
+
+ int i, rank, err, errs = 0, sizeoftype;
+
+ /* pretend we are each rank, one at a time */
+ for (rank=0; rank < 9; rank++) {
+ /* set up buffer */
+ for (i=0; i < 9; i++) {
+ array[i] = i;
+ }
+
+ /* set up type */
+ err = MPI_Type_create_darray(9, /* size */
+ rank,
+ 2, /* dims */
+ array_size,
+ array_distrib,
+ array_dargs,
+ array_psizes,
+ MPI_ORDER_C,
+ MPI_INT,
+ &darray);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Type_create_darray call; aborting after %d errors\n",
+ errs);
+ }
+ MTestPrintError( err );
+ return errs;
+ }
+
+ MPI_Type_commit(&darray);
+
+ MPI_Type_size(darray, &sizeoftype);
+ if (sizeoftype != sizeof(int)) {
+ errs++;
+ if (verbose) fprintf(stderr, "size of type = %d; should be %d\n",
+ sizeoftype, (int) sizeof(int));
+ return errs;
+ }
+
+ err = pack_and_unpack((char *) array, 1, darray, 9*sizeof(int));
+
+ for (i=0; i < 9; i++) {
+
+ if ((i == rank) && (array[i] != rank)) {
+ errs++;
+ if (verbose) fprintf(stderr, "array[%d] = %d; should be %d\n",
+ i, array[i], rank);
+ }
+ else if ((i != rank) && (array[i] != 0)) {
+ errs++;
+ if (verbose) fprintf(stderr, "array[%d] = %d; should be %d\n",
+ i, array[i], 0);
+ }
+ }
+ MPI_Type_free(&darray);
+ }
+
+ return errs;
+}
+
+/* darray_4d_c_test1()
+ *
+ * Returns the number of errors encountered.
+ */
+int darray_4d_c_test1(void)
+{
+ MPI_Datatype darray;
+ int array[72];
+ int array_size[4] = {6, 3, 2, 2};
+ int array_distrib[4] = { MPI_DISTRIBUTE_BLOCK,
+ MPI_DISTRIBUTE_BLOCK,
+ MPI_DISTRIBUTE_NONE,
+ MPI_DISTRIBUTE_NONE };
+ int array_dargs[4] = { MPI_DISTRIBUTE_DFLT_DARG,
+ MPI_DISTRIBUTE_DFLT_DARG,
+ MPI_DISTRIBUTE_DFLT_DARG,
+ MPI_DISTRIBUTE_DFLT_DARG };
+ int array_psizes[4] = {6, 3, 1, 1};
+
+ int i, rank, err, errs = 0, sizeoftype;
+
+ for (rank=0; rank < 18; rank++) {
+ /* set up array */
+ for (i=0; i < 72; i++) {
+ array[i] = i;
+ }
+
+ /* set up type */
+ err = MPI_Type_create_darray(18, /* size */
+ rank,
+ 4, /* dims */
+ array_size,
+ array_distrib,
+ array_dargs,
+ array_psizes,
+ MPI_ORDER_C,
+ MPI_INT,
+ &darray);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Type_create_darray call; aborting after %d errors\n",
+ errs);
+ }
+ MTestPrintError( err );
+ return errs;
+ }
+
+ MPI_Type_commit(&darray);
+
+ /* verify the size of the type */
+ MPI_Type_size(darray, &sizeoftype);
+ if (sizeoftype != 4*sizeof(int)) {
+ errs++;
+ if (verbose) fprintf(stderr, "size of type = %d; should be %d\n",
+ sizeoftype, (int) (4*sizeof(int)));
+ return errs;
+ }
+
+ /* pack and unpack the type, zero'ing out all other values */
+ err = pack_and_unpack((char *) array, 1, darray, 72*sizeof(int));
+
+ for (i=0; i < 4*rank; i++) {
+ if (array[i] != 0) {
+ errs++;
+ if (verbose) fprintf(stderr, "array[%d] = %d; should be %d\n",
+ i, array[i], 0);
+ }
+ }
+
+ for (i=4*rank; i < 4*rank + 4; i++) {
+ if (array[i] != i) {
+ errs++;
+ if (verbose) fprintf(stderr, "array[%d] = %d; should be %d\n",
+ i, array[i], i);
+ }
+ }
+ for (i=4*rank+4; i < 72; i++) {
+ if (array[i] != 0) {
+ errs++;
+ if (verbose) fprintf(stderr, "array[%d] = %d; should be %d\n",
+ i, array[i], 0);
+ }
+ }
+
+ MPI_Type_free(&darray);
+ }
+ return errs;
+}
+
+/******************************************************************/
+
+/* pack_and_unpack()
+ *
+ * Perform packing and unpacking of a buffer for the purposes of checking
+ * to see if we are processing a type correctly. Zeros the buffer between
+ * these two operations, so the data described by the type should be in
+ * place upon return but all other regions of the buffer should be zero.
+ *
+ * Parameters:
+ * typebuf - pointer to buffer described by datatype and count that
+ * will be packed and then unpacked into
+ * count, datatype - description of typebuf
+ * typebufsz - size of typebuf; used specifically to zero the buffer
+ * between the pack and unpack steps
+ *
+ */
+static int pack_and_unpack(char *typebuf,
+ int count,
+ MPI_Datatype datatype,
+ int typebufsz)
+{
+ char *packbuf;
+ int err, errs = 0, pack_size, type_size, position;
+
+ err = MPI_Type_size(datatype, &type_size);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Type_size call; aborting after %d errors\n",
+ errs);
+ }
+ MTestPrintError( err );
+ return errs;
+ }
+
+ type_size *= count;
+
+ err = MPI_Pack_size(count, datatype, MPI_COMM_SELF, &pack_size);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Pack_size call; aborting after %d errors\n",
+ errs);
+ }
+ MTestPrintError( err );
+ return errs;
+ }
+ packbuf = (char *) malloc(pack_size);
+ if (packbuf == NULL) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in malloc call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+
+ /* FIXME: the pack size returned need not be the type_size - this will
+ only be true if the pack routine simply moves the bytes but does
+ no other transformations of the data */
+ position = 0;
+ err = MPI_Pack(typebuf,
+ count,
+ datatype,
+ packbuf,
+ type_size,
+ &position,
+ MPI_COMM_SELF);
+
+ if (position != type_size) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (pack)\n",
+ position, type_size);
+ }
+
+ memset(typebuf, 0, typebufsz);
+ position = 0;
+ err = MPI_Unpack(packbuf,
+ type_size,
+ &position,
+ typebuf,
+ count,
+ datatype,
+ MPI_COMM_SELF);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Unpack call; aborting after %d errors\n",
+ errs);
+ }
+ MTestPrintError( err );
+ return errs;
+ }
+ free(packbuf);
+
+ if (position != type_size) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (unpack)\n",
+ position, type_size);
+ }
+
+ return errs;
+}
+
+static int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ *
+ * (C) 2003 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+/*
+static char MTEST_Descrip[] = "";
+*/
+
+int main( int argc, char *argv[] )
+{
+ int errs = 0;
+ int buf[10];
+ MPI_Aint a1, a2;
+
+ MTest_Init( &argc, &argv );
+
+ MPI_Get_address( &buf[0], &a1 );
+ MPI_Get_address( &buf[1], &a2 );
+
+ if ((int)(a2-a1) != sizeof(int)) {
+ errs++;
+ printf( "Get address of two address did not return values the correct distance apart\n" );
+ }
+
+ MTest_Finalize( errs );
+ MPI_Finalize();
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int verbose = 0;
+
+/* tests */
+int double_int_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = double_int_test();
+ if (err && verbose) fprintf(stderr, "%d errors in double_int test.\n",
+ err);
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+/* send a { double, int, double} tuple and receive as a pair of
+ * MPI_DOUBLE_INTs. this should (a) be valid, and (b) result in an
+ * element count of 3.
+ */
+int double_int_test(void)
+{
+ int err, errs = 0, count;
+
+ struct { double a; int b; double c; } foo;
+ struct { double a; int b; double c; int d; } bar;
+
+ int blks[3] = { 1, 1, 1 };
+ MPI_Aint disps[3] = { 0, 0, 0 };
+ MPI_Datatype types[3] = { MPI_DOUBLE, MPI_INT, MPI_DOUBLE };
+ MPI_Datatype stype;
+
+ MPI_Status recvstatus;
+
+ /* fill in disps[1..2] with appropriate offset */
+ disps[1] = (MPI_Aint) ((char *) &foo.b - (char *) &foo.a);
+ disps[2] = (MPI_Aint) ((char *) &foo.c - (char *) &foo.a);
+
+ MPI_Type_create_struct(3, blks, disps, types, &stype);
+ MPI_Type_commit(&stype);
+
+ err = MPI_Sendrecv(&foo, 1, stype, 0, 0,
+ &bar, 2, MPI_DOUBLE_INT, 0, 0,
+ MPI_COMM_SELF, &recvstatus);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, "MPI_Sendrecv returned error (%d)\n",
+ err);
+ return errs;
+ }
+
+ err = MPI_Get_elements(&recvstatus, MPI_DOUBLE_INT, &count);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, "MPI_Get_elements returned error (%d)\n",
+ err);
+ }
+
+ if (count != 3) {
+ errs++;
+ if (verbose) fprintf(stderr,
+ "MPI_Get_elements returned count of %d, should be 3\n",
+ count);
+ }
+
+ MPI_Type_free( &stype );
+
+ return errs;
+}
+
+int parse_args(int argc, char **argv)
+{
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2011 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+
+#include "mpi.h"
+#include <stdio.h>
+#include <stddef.h>
+#include <assert.h>
+
+/* Tests MPI_Get_elements with a contiguous datatype that triggered a bug in
+ * past versions of MPICH. See ticket #1467 for more info. */
+
+struct test_struct {
+ char a;
+ short b;
+ int c;
+};
+
+int main(int argc, char **argv)
+{
+ int rank, count;
+ struct test_struct sendbuf, recvbuf;
+ int blens[3];
+ MPI_Aint displs[3];
+ MPI_Datatype types[3];
+ MPI_Datatype struct_type, contig;
+ MPI_Status status;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ /* We use a contig of a struct in order to satisfy two properties:
+ * (A) a type that contains more than one element type (the struct portion)
+ * (B) a type that has an odd number of ints in its "type contents" (1 in
+ * this case)
+ * This triggers a specific bug in some versions of MPICH. */
+ blens[0] = 1;
+ displs[0] = offsetof(struct test_struct, a);
+ types[0] = MPI_CHAR;
+ blens[1] = 1;
+ displs[1] = offsetof(struct test_struct, b);
+ types[1] = MPI_SHORT;
+ blens[2] = 1;
+ displs[2] = offsetof(struct test_struct, c);
+ types[2] = MPI_INT;
+ MPI_Type_create_struct(3, blens, displs, types, &struct_type);
+ MPI_Type_contiguous(1, struct_type, &contig);
+ MPI_Type_commit(&struct_type);
+ MPI_Type_commit(&contig);
+
+ sendbuf.a = 20;
+ sendbuf.b = 30;
+ sendbuf.c = 40;
+ recvbuf.a = -1;
+ recvbuf.b = -1;
+ recvbuf.c = -1;
+
+ /* send to ourself */
+ MPI_Sendrecv(&sendbuf, 1, contig, 0, 0,
+ &recvbuf, 1, contig, 0, 0,
+ MPI_COMM_SELF, &status);
+
+ /* sanity */
+ assert(sendbuf.a == recvbuf.a);
+ assert(sendbuf.b == recvbuf.b);
+ assert(sendbuf.c == recvbuf.c);
+
+ /* now check that MPI_Get_elements returns the correct answer and that the
+ * library doesn't explode in the process */
+ count = 0xdeadbeef;
+ MPI_Get_elements(&status, contig, &count);
+ MPI_Type_free(&struct_type);
+ MPI_Type_free(&contig);
+
+ if (count != 3) {
+ printf("unexpected value for count, expected 3, got %d\n", count);
+ }
+ else {
+ if (rank == 0) {
+ printf(" No Errors\n");
+ }
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ *
+ * (C) 2003 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+/*
+static char MTest_descrip[] = "Receive partial datatypes and check that\
+MPI_Getelements gives the correct version";
+*/
+
+int main( int argc, char *argv[] )
+{
+ int errs = 0;
+ MPI_Datatype outtype, oldtypes[2];
+ MPI_Aint offsets[2];
+ int blklens[2];
+ MPI_Comm comm;
+ int size, rank, src, dest, tag;
+
+ MTest_Init( &argc, &argv );
+
+ comm = MPI_COMM_WORLD;
+
+ MPI_Comm_rank( comm, &rank );
+ MPI_Comm_size( comm, &size );
+
+ if (size < 2) {
+ errs++;
+ printf( "This test requires at least 2 processes\n" );
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+
+ src = 0;
+ dest = 1;
+
+ if (rank == src) {
+ int buf[128], position, cnt;
+ /* sender */
+
+ /* Create a datatype and send it (multiple of sizeof(int)) */
+ /* Create a send struct type */
+ oldtypes[0] = MPI_INT;
+ oldtypes[1] = MPI_CHAR;
+ blklens[0] = 1;
+ blklens[1] = 4*sizeof(int);
+ offsets[0] = 0;
+ offsets[1] = sizeof(int);
+ MPI_Type_struct( 2, blklens, offsets, oldtypes, &outtype );
+ MPI_Type_commit( &outtype );
+
+ buf[0] = 4*sizeof(int);
+ /* printf( "About to send to %d\n", dest ); */
+ MPI_Send( buf, 1, outtype, dest, 0, comm );
+ MPI_Type_free( &outtype );
+
+ /* Create a datatype and send it (not a multiple of sizeof(int)) */
+ /* Create a send struct type */
+ oldtypes[0] = MPI_INT;
+ oldtypes[1] = MPI_CHAR;
+ blklens[0] = 1;
+ blklens[1] = 4*sizeof(int)+1;
+ offsets[0] = 0;
+ offsets[1] = sizeof(int);
+ MPI_Type_struct( 2, blklens, offsets, oldtypes, &outtype );
+ MPI_Type_commit( &outtype );
+
+ buf[0] = 4*sizeof(int) + 1;
+ MPI_Send( buf, 1, outtype, dest, 1, comm );
+ MPI_Type_free( &outtype );
+
+ /* Pack data and send as packed */
+ position = 0;
+ cnt = 7;
+ MPI_Pack( &cnt, 1, MPI_INT,
+ buf, 128*sizeof(int), &position, comm );
+ MPI_Pack( (void*)"message", 7, MPI_CHAR,
+ buf, 128*sizeof(int), &position, comm );
+ MPI_Send( buf, position, MPI_PACKED, dest, 2, comm );
+ }
+ else if (rank == dest) {
+ MPI_Status status;
+ int buf[128], i, elms, count;
+
+ /* Receiver */
+ /* Create a receive struct type */
+ oldtypes[0] = MPI_INT;
+ oldtypes[1] = MPI_CHAR;
+ blklens[0] = 1;
+ blklens[1] = 256;
+ offsets[0] = 0;
+ offsets[1] = sizeof(int);
+ MPI_Type_struct( 2, blklens, offsets, oldtypes, &outtype );
+ MPI_Type_commit( &outtype );
+
+ for (i=0; i<3; i++) {
+ tag = i;
+ /* printf( "about to receive tag %d from %d\n", i, src ); */
+ MPI_Recv( buf, 1, outtype, src, tag, comm, &status );
+ MPI_Get_elements( &status, outtype, &elms );
+ if (elms != buf[0] + 1) {
+ errs++;
+ printf( "For test %d, Get elements gave %d but should be %d\n",
+ i, elms, buf[0] + 1 );
+ }
+ MPI_Get_count( &status, outtype, &count );
+ if (count != MPI_UNDEFINED) {
+ errs++;
+ printf( "For partial send, Get_count did not return MPI_UNDEFINED\n" );
+ }
+ }
+ MPI_Type_free( &outtype );
+ }
+
+ MTest_Finalize( errs );
+ MPI_Finalize();
+ return 0;
+
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpi.h"
+
+static int verbose = 0;
+
+int main(int argc, char *argv[]);
+int parse_args(int argc, char **argv);
+int hindexed_zerotype_test(void);
+int hindexed_sparsetype_test(void);
+
+struct test_struct_1 {
+ int a,b,c,d;
+};
+
+int main(int argc, char *argv[])
+{
+ int err, errs = 0;
+
+ /* Initialize MPI */
+ MPI_Init(&argc, &argv);
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ err = hindexed_zerotype_test();
+ if (verbose && err) fprintf(stderr, "error in hindexed_zerotype_test\n");
+ errs += err;
+
+ err = hindexed_sparsetype_test();
+ if (verbose && err) fprintf(stderr, "error in hindexed_sparsetype_test\n");
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+/* tests with an hindexed type with all zero length blocks */
+int hindexed_zerotype_test(void)
+{
+ int err, errs = 0;
+ int count, elements;
+ MPI_Datatype mytype;
+ MPI_Request request;
+ MPI_Status status;
+
+ int blks[] = { 0, 0, 0 };
+ MPI_Aint disps[] = { 0, 4, 16 };
+
+ err = MPI_Type_hindexed(3, blks, disps, MPI_INT, &mytype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_hindexed returned error\n");
+ }
+ }
+
+ MPI_Type_commit(&mytype);
+
+ err = MPI_Irecv(NULL, 2, mytype, 0, 0, MPI_COMM_SELF, &request);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Irecv returned error\n");
+ }
+ }
+
+ err = MPI_Send(NULL, 1, mytype, 0, 0, MPI_COMM_SELF);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Send returned error\n");
+ }
+ }
+
+ err = MPI_Wait(&request, &status);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Wait returned error\n");
+ }
+ }
+
+ /* verify count and elements */
+ err = MPI_Get_count(&status, mytype, &count);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Get_count returned error\n");
+ }
+ }
+ if (count != 0) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "count = %d; should be 0\n", count);
+ }
+ }
+
+ err = MPI_Get_elements(&status, mytype, &elements);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Get_elements returned error\n");
+ }
+ }
+ if (elements != 0) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "elements = %d; should be 0\n", elements);
+ }
+ }
+
+ // MPI_Type_free(&mytype);
+
+ return errs;
+}
+
+/* tests a short receive into a sparse hindexed type with a zero
+ * length block in it. sort of eccentric, but we've got the basic
+ * stuff covered with other tests.
+ */
+int hindexed_sparsetype_test(void)
+{
+ int err, errs = 0;
+ int i, count, elements;
+ MPI_Datatype mytype;
+ MPI_Request request;
+ MPI_Status status;
+
+ int sendbuf[6] = { 1, 2, 3, 4, 5, 6 };
+ int recvbuf[16];
+ int correct[16] = { 1, -2, 4, -4, 2, 3, 5, -8, -9, -10, 6,
+ -12, -13, -14, -15, -16 };
+
+ int blks[] = { 1, 0, 2, 1 };
+ MPI_Aint disps[] = { 0, 1*sizeof(int), 4*sizeof(int), 2*sizeof(int) };
+
+ err = MPI_Type_hindexed(4, blks, disps, MPI_INT, &mytype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_hindexed returned error\n");
+ }
+ }
+
+ MPI_Type_commit(&mytype);
+
+ for (i=0; i < 16; i++) recvbuf[i] = -(i+1);
+
+ err = MPI_Irecv(recvbuf, 2, mytype, 0, 0, MPI_COMM_SELF, &request);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Irecv returned error\n");
+ }
+ }
+
+ err = MPI_Send(sendbuf, 6, MPI_INT, 0, 0, MPI_COMM_SELF);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Send returned error\n");
+ }
+ }
+
+ err = MPI_Wait(&request, &status);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Wait returned error\n");
+ }
+ }
+
+ /* verify data */
+ for (i=0; i < 16; i++) {
+ if (recvbuf[i] != correct[i]) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "recvbuf[%d] = %d; should be %d\n",
+ i, recvbuf[i], correct[i]);
+ }
+ }
+ }
+
+ /* verify count and elements */
+ err = MPI_Get_count(&status, mytype, &count);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Get_count returned error\n");
+ }
+ }
+ if (count != MPI_UNDEFINED) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "count = %d; should be MPI_UNDEFINED (%d)\n",
+ count, MPI_UNDEFINED);
+ }
+ }
+
+ err = MPI_Get_elements(&status, mytype, &elements);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Get_elements returned error\n");
+ }
+ }
+ if (elements != 6) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "elements = %d; should be 6\n", elements);
+ }
+ }
+
+// MPI_Type_free(&mytype);
+
+ return errs;
+}
+
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#if !defined(USE_STRICT_MPI) && defined(MPICH)
+#define TEST_HINDEXED_BLOCK 1
+#endif
+
+static int verbose = 0;
+
+/* tests */
+int hindexed_block_contig_test(void);
+int hindexed_block_vector_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+static int pack_and_unpack(char *typebuf, int count, MPI_Datatype datatype, int typebufsz);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+ int rank;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+#if defined(TEST_HINDEXED_BLOCK)
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ * change the error handler to errors return */
+ MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
+
+ /* perform some tests */
+ err = hindexed_block_contig_test();
+ if (err && verbose)
+ fprintf(stderr, "%d errors in hindexed_block test.\n", err);
+ errs += err;
+
+ err = hindexed_block_vector_test();
+ if (err && verbose)
+ fprintf(stderr, "%d errors in hindexed_block vector test.\n", err);
+ errs += err;
+#endif /*defined(TEST_HINDEXED_BLOCK)*/
+
+ /* print message and exit */
+ if (rank == 0) {
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+#if defined(TEST_HINDEXED_BLOCK)
+
+/* hindexed_block_contig_test()
+ *
+ * Tests behavior with a hindexed_block that can be converted to a
+ * contig easily. This is specifically for coverage.
+ *
+ * Returns the number of errors encountered.
+ */
+int hindexed_block_contig_test(void)
+{
+ int buf[4] = { 7, -1, -2, -3 };
+ int err, errs = 0;
+
+ int i, count = 1;
+ MPI_Aint disp = 0;
+ MPI_Datatype newtype;
+
+ int size, int_size;
+ MPI_Aint extent;
+
+ err = MPI_Type_create_hindexed_block(count, 1, &disp, MPI_INT, &newtype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "error creating struct type in hindexed_block_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_size(MPI_INT, &int_size);
+
+ err = MPI_Type_size(newtype, &size);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "error obtaining type size in hindexed_block_contig_test()\n");
+ }
+ errs++;
+ }
+
+ if (size != int_size) {
+ if (verbose) {
+ fprintf(stderr, "error: size != int_size in hindexed_block_contig_test()\n");
+ }
+ errs++;
+ }
+
+ err = MPI_Type_extent(newtype, &extent);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "error obtaining type extent in hindexed_block_contig_test()\n");
+ }
+ errs++;
+ }
+
+ if (extent != int_size) {
+ if (verbose) {
+ fprintf(stderr, "error: extent != int_size in hindexed_block_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_commit(&newtype);
+
+ err = pack_and_unpack((char *) buf, 1, newtype, 4 * sizeof(int));
+ if (err != 0) {
+ if (verbose) {
+ fprintf(stderr, "error packing/unpacking in hindexed_block_contig_test()\n");
+ }
+ errs += err;
+ }
+
+ for (i = 0; i < 4; i++) {
+ int goodval;
+
+ switch (i) {
+ case 0:
+ goodval = 7;
+ break;
+ default:
+ goodval = 0; /* pack_and_unpack() zeros before unpack */
+ break;
+ }
+ if (buf[i] != goodval) {
+ errs++;
+ if (verbose)
+ fprintf(stderr, "buf[%d] = %d; should be %d\n", i, buf[i], goodval);
+ }
+ }
+
+ MPI_Type_free(&newtype);
+
+ return errs;
+}
+
+/* hindexed_block_vector_test()
+ *
+ * Tests behavior with a hindexed_block of some vector types;
+ * this shouldn't be easily convertable into anything else.
+ *
+ * Returns the number of errors encountered.
+ */
+int hindexed_block_vector_test(void)
+{
+#define NELT (18)
+ int buf[NELT] = {
+ -1, -1, -1,
+ 1, -2, 2,
+ -3, -3, -3,
+ -4, -4, -4,
+ 3, -5, 4,
+ 5, -6, 6
+ };
+ int expected[NELT] = {
+ 0, 0, 0,
+ 1, 0, 2,
+ 0, 0, 0,
+ 0, 0, 0,
+ 3, 0, 4,
+ 5, 0, 6
+ };
+ int err, errs = 0;
+
+ int i, count = 3;
+ MPI_Aint disp[] = { 1, 4, 5 };
+ MPI_Datatype vectype, newtype;
+
+ int size, int_size;
+ MPI_Aint extent;
+
+ /* create a vector type of 2 ints, skipping one in between */
+ err = MPI_Type_vector(2, 1, 2, MPI_INT, &vectype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "error creating vector type in hindexed_block_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_commit(&vectype);
+
+ MPI_Type_extent(vectype, &extent);
+ for (i = 0; i < count; i++)
+ disp[i] *= extent;
+
+ err = MPI_Type_create_hindexed_block(count, 1, disp, vectype, &newtype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating hindexed_block type in hindexed_block_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_commit(&newtype);
+
+ err = MPI_Type_size(newtype, &size);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "error obtaining type size in hindexed_block_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_size(MPI_INT, &int_size);
+
+ if (size != 6 * int_size) {
+ if (verbose) {
+ fprintf(stderr, "error: size != 6 * int_size in hindexed_block_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_extent(newtype, &extent);
+
+ err = pack_and_unpack((char *) buf, 1, newtype, NELT * sizeof(int));
+ if (err != 0) {
+ if (verbose) {
+ fprintf(stderr, "error packing/unpacking in hindexed_block_vector_test()\n");
+ }
+ errs += err;
+ }
+
+ for (i = 0; i < NELT; i++) {
+ if (buf[i] != expected[i]) {
+ errs++;
+ if (verbose)
+ fprintf(stderr, "buf[%d] = %d; should be %d\n", i, buf[i], expected[i]);
+ }
+ }
+
+ MPI_Type_free(&vectype);
+ MPI_Type_free(&newtype);
+ return errs;
+}
+
+
+/* pack_and_unpack()
+ *
+ * Perform packing and unpacking of a buffer for the purposes of checking
+ * to see if we are processing a type correctly. Zeros the buffer between
+ * these two operations, so the data described by the type should be in
+ * place upon return but all other regions of the buffer should be zero.
+ *
+ * Parameters:
+ * typebuf - pointer to buffer described by datatype and count that
+ * will be packed and then unpacked into
+ * count, datatype - description of typebuf
+ * typebufsz - size of typebuf; used specifically to zero the buffer
+ * between the pack and unpack steps
+ *
+ */
+static int pack_and_unpack(char *typebuf, int count, MPI_Datatype datatype, int typebufsz)
+{
+ char *packbuf;
+ int err, errs = 0, pack_size, type_size, position;
+
+ err = MPI_Type_size(datatype, &type_size);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "error in MPI_Type_size call; aborting after %d errors\n", errs);
+ }
+ return errs;
+ }
+
+ type_size *= count;
+
+ err = MPI_Pack_size(count, datatype, MPI_COMM_SELF, &pack_size);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "error in MPI_Pack_size call; aborting after %d errors\n", errs);
+ }
+ return errs;
+ }
+ packbuf = (char *) malloc(pack_size);
+ if (packbuf == NULL) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "error in malloc call; aborting after %d errors\n", errs);
+ }
+ return errs;
+ }
+
+ position = 0;
+ err = MPI_Pack(typebuf, count, datatype, packbuf, type_size, &position, MPI_COMM_SELF);
+
+ if (position != type_size) {
+ errs++;
+ if (verbose)
+ fprintf(stderr, "position = %d; should be %d (pack)\n", position, type_size);
+ }
+
+ memset(typebuf, 0, typebufsz);
+ position = 0;
+ err = MPI_Unpack(packbuf, type_size, &position, typebuf, count, datatype, MPI_COMM_SELF);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "error in MPI_Unpack call; aborting after %d errors\n", errs);
+ }
+ return errs;
+ }
+ free(packbuf);
+
+ if (position != type_size) {
+ errs++;
+ if (verbose)
+ fprintf(stderr, "position = %d; should be %d (unpack)\n", position, type_size);
+ }
+
+ return errs;
+}
+
+int parse_args(int argc, char **argv)
+{
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
+#endif /*defined(TEST_HINDEXED_BLOCK)*/
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2012 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+
+/* test based on a bug report from Lisandro Dalcin:
+ * http://lists.mcs.anl.gov/pipermail/mpich-dev/2012-October/000978.html */
+
+#include <mpi.h>
+#include <stdlib.h>
+#include <stdio.h>
+/* USE_STRICT_MPI may be defined in mpitestconf.h */
+#include "mpitestconf.h"
+
+/* assert-like macro that bumps the err count and emits a message */
+#define check(x_) \
+ do { \
+ if (!(x_)) { \
+ ++errs; \
+ if (errs < 10) { \
+ fprintf(stderr, "check failed: (%s), line %d\n", #x_, __LINE__); \
+ } \
+ } \
+ } while (0)
+
+int main(int argc, char **argv)
+{
+ int errs = 0;
+ int rank;
+ MPI_Datatype t;
+ int count = 4;
+ int blocklength = 2;
+ MPI_Aint displacements[] = {0, 8, 16, 24};
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (!rank) {
+ MPI_Type_create_hindexed_block(count, blocklength,
+ displacements, MPI_INT,
+ &t);
+ MPI_Type_commit(&t);
+ {
+ int ni, na, nd, combiner;
+ int i[1024];
+ MPI_Aint a[1024];
+ MPI_Datatype d[1024];
+ int k;
+ MPI_Type_get_envelope(t, &ni, &na, &nd, &combiner);
+ MPI_Type_get_contents(t, ni, na, nd, i, a, d);
+
+ check(ni == 2);
+ check(i[0] == 4);
+ check(i[1] == 2);
+
+ check(na == 4);
+ for (k=0; k < na; k++)
+ check(a[k] == (k * 8));
+
+ check(nd == 1);
+ check(d[0] == MPI_INT);
+ }
+
+ MPI_Type_free(&t);
+ }
+
+ if (rank == 0) {
+ if (errs) {
+ printf("found %d errors\n", errs);
+ }
+ else {
+ printf(" No errors\n");
+ }
+ }
+ MPI_Finalize();
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <assert.h>
+#include <limits.h>
+
+static int verbose = 1;
+
+#define check(cond_) \
+ do { \
+ if (!(cond_)) { \
+ if (verbose) { \
+ fprintf(stderr, "condition '%s' does not hold, at line %d\n", #cond_, __LINE__); \
+ } \
+ errs += 1; \
+ } \
+ } while (0)
+
+#define check_err(err_, what_failed_) \
+ do { \
+ if (err_) { \
+ if (verbose) { \
+ fprintf(stderr, "error: %s, at line %d\n", (what_failed_), __LINE__); \
+ } \
+ errs += (err_); \
+ } \
+ } while (0)
+
+/* tests */
+int indexed_contig_test(void);
+int indexed_zeroblock_first_test(void);
+int indexed_zeroblock_middle_test(void);
+int indexed_zeroblock_last_test(void);
+int indexed_contig_leading_zero_test(void);
+int indexed_same_lengths(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+static int pack_and_unpack(char *typebuf,
+ int count,
+ MPI_Datatype datatype,
+ int typebufsz);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = indexed_contig_test();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in indexed_contig_test.\n",
+ err);
+ errs += err;
+
+ err = indexed_zeroblock_first_test();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in indexed_zeroblock_first_test.\n",
+ err);
+ errs += err;
+
+ err = indexed_zeroblock_middle_test();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in indexed_zeroblock_middle_test.\n",
+ err);
+ errs += err;
+
+ err = indexed_zeroblock_last_test();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in indexed_zeroblock_last_test.\n",
+ err);
+ errs += err;
+
+ err = indexed_contig_leading_zero_test();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in indexed_contig_leading_zero_test.\n",
+ err);
+ errs += err;
+
+ err = indexed_same_lengths();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in indexed_contig_leading_zero_test.\n",
+ err);
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+int indexed_zeroblock_first_test(void)
+{
+ int err, errs = 0;
+
+ MPI_Datatype type;
+ int len[3] = { 0, 1, 1 };
+ int disp[3] = { 0, 1, 4 };
+ MPI_Aint lb, ub;
+
+ err = MPI_Type_indexed(3, len, disp, MPI_INT, &type);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating indexed type in indexed_zeroblock_first_test()\n");
+ }
+ errs += 1;
+ }
+
+ MPI_Type_lb(type, &lb);
+ if (lb != sizeof(int)) {
+ if (verbose) {
+ fprintf(stderr,
+ "lb mismatch; is %d, should be %d\n",
+ (int) lb, (int) sizeof(int));
+ }
+ errs++;
+ }
+ MPI_Type_ub(type, &ub);
+ if (ub != 5 * sizeof(int)) {
+ if (verbose) {
+ fprintf(stderr,
+ "ub mismatch; is %d, should be %d\n",
+ (int) ub, (int) (5 * sizeof(int)));
+ }
+ errs++;
+ }
+
+ MPI_Type_free( &type );
+
+ return errs;
+}
+
+int indexed_zeroblock_middle_test(void)
+{
+ int err, errs = 0;
+
+ MPI_Datatype type;
+ int len[3] = { 1, 0, 1 };
+ int disp[3] = { 1, 2, 4 };
+ MPI_Aint lb, ub;
+
+ err = MPI_Type_indexed(3, len, disp, MPI_INT, &type);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating indexed type in indexed_zeroblock_middle_test()\n");
+ }
+ errs += 1;
+ }
+
+ MPI_Type_lb(type, &lb);
+ if (lb != sizeof(int)) {
+ if (verbose) {
+ fprintf(stderr,
+ "lb mismatch; is %d, should be %d\n",
+ (int) lb, (int) sizeof(int));
+ }
+ errs++;
+ }
+ MPI_Type_ub(type, &ub);
+ if (ub != 5 * sizeof(int)) {
+ if (verbose) {
+ fprintf(stderr,
+ "ub mismatch; is %d, should be %d\n",
+ (int) ub, (int) (5 * sizeof(int)));
+ }
+ errs++;
+ }
+
+ MPI_Type_free( &type );
+
+ return errs;
+}
+
+int indexed_zeroblock_last_test(void)
+{
+ int err, errs = 0;
+
+ MPI_Datatype type;
+ int len[3] = { 1, 1, 0 };
+ int disp[3] = { 1, 4, 8 };
+ MPI_Aint lb, ub;
+
+ err = MPI_Type_indexed(3, len, disp, MPI_INT, &type);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating indexed type in indexed_zeroblock_last_test()\n");
+ }
+ errs += 1;
+ }
+
+ MPI_Type_lb(type, &lb);
+ if (lb != sizeof(int)) {
+ if (verbose) {
+ fprintf(stderr,
+ "lb mismatch; is %d, should be %d\n",
+ (int) lb, (int) sizeof(int));
+ }
+ errs++;
+ }
+ MPI_Type_ub(type, &ub);
+ if (ub != 5 * sizeof(int)) {
+ if (verbose) {
+ fprintf(stderr,
+ "ub mismatch; is %d, should be %d\n",
+ (int) ub, (int) (5 * sizeof(int)));
+ }
+ errs++;
+ }
+
+ MPI_Type_free( &type );
+
+ return errs;
+}
+
+/* indexed_contig_test()
+ *
+ * Tests behavior with an indexed array that can be compacted but should
+ * continue to be stored as an indexed type. Specifically for coverage.
+ *
+ * Returns the number of errors encountered.
+ */
+int indexed_contig_test(void)
+{
+ int buf[9] = {-1, 1, 2, 3, -2, 4, 5, -3, 6};
+ int err, errs = 0;
+
+ int i, count = 5;
+ int blklen[] = { 1, 2, 1, 1, 1 };
+ int disp[] = { 1, 2, 5, 6, 8 };
+ MPI_Datatype newtype;
+
+ int size, int_size;
+
+ err = MPI_Type_indexed(count,
+ blklen,
+ disp,
+ MPI_INT,
+ &newtype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating indexed type in indexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_size(MPI_INT, &int_size);
+
+ err = MPI_Type_size(newtype, &size);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type size in indexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ if (size != 6 * int_size) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: size != 6 * int_size in indexed_contig_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_commit(&newtype);
+
+ err = pack_and_unpack((char *) buf, 1, newtype, 9 * sizeof(int));
+ if (err != 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "error packing/unpacking in indexed_contig_test()\n");
+ }
+ errs += err;
+ }
+
+ for (i=0; i < 9; i++) {
+ int goodval;
+
+ switch(i) {
+ case 1:
+ goodval = 1;
+ break;
+ case 2:
+ goodval = 2;
+ break;
+ case 3:
+ goodval = 3;
+ break;
+ case 5:
+ goodval = 4;
+ break;
+ case 6:
+ goodval = 5;
+ break;
+ case 8:
+ goodval = 6;
+ break;
+ default:
+ goodval = 0; /* pack_and_unpack() zeros before unpack */
+ break;
+ }
+ if (buf[i] != goodval) {
+ errs++;
+ if (verbose) fprintf(stderr, "buf[%d] = %d; should be %d\n",
+ i, buf[i], goodval);
+ }
+ }
+
+ MPI_Type_free( &newtype );
+
+ return errs;
+}
+
+/* very similar to indexed_zeroblock_first_test, but only has a single contig in
+ * order to catch a particular optimization path in MPICH's
+ * Dataloop_create_indexed routine */
+int indexed_contig_leading_zero_test(void)
+{
+ int err, errs = 0;
+
+ int i;
+ MPI_Datatype type = MPI_DATATYPE_NULL;
+ MPI_Datatype struct_type = MPI_DATATYPE_NULL;
+ MPI_Datatype types[2];
+ int len[3] = { 0, 4, 0 };
+ int disp[3] = { INT_MAX, 2, INT_MAX};
+ MPI_Aint adisp[3];
+ MPI_Aint lb, ub;
+ int *buf = NULL;
+
+ err = MPI_Type_indexed(3, len, disp, MPI_INT, &type);
+ check_err(err, "creating indexed type in indexed_contig_leading_zero_test()");
+ err = MPI_Type_commit(&type);
+ check_err(err, "committing indexed type in indexed_contig_leading_zero_test()");
+
+ MPI_Type_lb(type, &lb);
+ check(lb == 2 * sizeof(int));
+ MPI_Type_ub(type, &ub);
+ check(ub == 6 * sizeof(int));
+
+ /* make sure packing/unpacking works (hits a simple "is_contig" case in
+ * MPICH's pack/unpack routines) */
+ buf = malloc(10*sizeof(int));
+ assert(buf != NULL);
+ for (i = 0; i < 10; ++i) {
+ buf[i] = i + 1;
+ }
+ err = pack_and_unpack((char *) buf, 1, type, 10 * sizeof(int));
+ check_err(err, "packing/unpacking in indexed_contig_leading_zero_test()");
+ for (i = 0; i < 10; ++i) {
+ int expected;
+ if (i >= 2 && i < 6)
+ expected = i + 1;
+ else
+ expected = 0;
+ check(buf[i] == expected);
+ }
+ free(buf);
+
+ /* -------------------------------------------------------------------- */
+ /* A more rigorous test of the indexed type. Use a hard-to-optimize struct
+ * type to force a more complicated datatype processing path
+ * (MPID_Segment_manipulate in MPICH) */
+ len[0] = 1;
+ len[1] = 1;
+ adisp[0] = 0;
+ adisp[1] = 8*sizeof(int);
+ types[0] = type;
+ types[1] = MPI_INT;
+
+ /* struct layout: xx0123xx4x ('x' indicates a hole), one char is an
+ * MPI_INT */
+ MPI_Type_create_struct(2, len, adisp, types, &struct_type);
+ check_err(err, "creating struct type in indexed_contig_leading_zero_test()");
+ err = MPI_Type_commit(&struct_type);
+ check_err(err, "committing struct type in indexed_contig_leading_zero_test()");
+
+ buf = malloc(10*sizeof(int));
+ assert(buf != NULL);
+ for (i = 0; i < 10; ++i) {
+ buf[i] = i + 1;
+ }
+ err = pack_and_unpack((char *) buf, 1, struct_type, 10 * sizeof(int));
+ check_err(err, "packing/unpacking in indexed_contig_test()");
+
+ for (i = 0; i < 10; ++i) {
+ int expected;
+ if ((i >= 2 && i < 6) || i == 8)
+ expected = i + 1;
+ else
+ expected = 0;
+ check(buf[i] == expected);
+ }
+ free(buf);
+
+ MPI_Type_free(&struct_type);
+ MPI_Type_free( &type );
+
+ /* -------------------------------------------------------------------- */
+ /* now do the same as above, but with hindexed */
+ len[0] = 0;
+ len[1] = 4;
+ len[2] = 0;
+ /* use *_MAX vars to improve our chances of hitting any pointer-casting
+ * bugs in a big way (segfaults, etc.) */
+ /* FIXME: This should also look at long, or use a different approach */
+#if defined(HAVE_LONG_LONG) && defined(LLONG_MAX)
+ if (sizeof(MPI_Aint) == sizeof(long long)) {
+ adisp[0] = (MPI_Aint)LLONG_MAX;
+ adisp[1] = 2*sizeof(int);
+ adisp[2] = (MPI_Aint)LLONG_MAX;
+ }
+ else
+#endif
+ {
+ adisp[0] = (MPI_Aint)INT_MAX;
+ adisp[1] = 2*sizeof(int);
+ adisp[2] = (MPI_Aint)INT_MAX;
+ }
+
+ err = MPI_Type_hindexed(3, len, adisp, MPI_INT, &type);
+ check_err(err, "creating hindexed type in indexed_contig_leading_zero_test()");
+
+ err = MPI_Type_commit(&type);
+ check_err(err, "committing hindexed type in indexed_contig_leading_zero_test()");
+
+ MPI_Type_lb(type, &lb);
+ check(lb == 2 * sizeof(int));
+ MPI_Type_ub(type, &ub);
+ check(ub == 6 * sizeof(int));
+
+ buf = malloc(10*sizeof(int));
+ assert(buf != NULL);
+ for (i = 0; i < 10; ++i) {
+ buf[i] = i + 1;
+ }
+ err = pack_and_unpack((char *) buf, 1, type, 10 * sizeof(int));
+ check_err(err, "packing/unpacking in indexed_contig_test()");
+
+ for (i = 0; i < 10; ++i) {
+ int expected;
+ if (i >= 2 && i < 6)
+ expected = i + 1;
+ else
+ expected = 0;
+ check(buf[i] == expected);
+ }
+ free(buf);
+
+
+ /* -------------------------------------------------------------------- */
+ /* A more rigorous test of the hindexed type. Use a hard-to-optimize struct
+ * type to force a more complicated datatype processing path
+ * (MPID_Segment_manipulate in MPICH) */
+ len[0] = 1;
+ len[1] = 1;
+ adisp[0] = 0;
+ adisp[1] = 8*sizeof(int);
+
+ /* struct layout: xx0123xx4x ('x' indicates a hole), one char is an
+ * MPI_INT */
+ err = MPI_Type_create_struct(2, len, adisp, types, &struct_type);
+ check_err(err, "committing struct type in indexed_contig_leading_zero_test()");
+ err = MPI_Type_commit(&struct_type);
+ check_err(err, "committing struct type in indexed_contig_leading_zero_test()");
+
+ buf = malloc(10*sizeof(int));
+ assert(buf != NULL);
+ for (i = 0; i < 10; ++i) {
+ buf[i] = i + 1;
+ }
+ /* fails in old MPICH (3.0rc1 and earlier), despite correct ub/lb
+ * determination */
+ err = pack_and_unpack((char *) buf, 1, struct_type, 10 * sizeof(int));
+ check_err(err, "packing/unpacking in indexed_contig_test()");
+
+ for (i = 0; i < 10; ++i) {
+ int expected;
+ if ((i >= 2 && i < 6) || i == 8)
+ expected = i + 1;
+ else
+ expected = 0;
+ check(buf[i] == expected);
+ }
+ free(buf);
+
+ MPI_Type_free(&struct_type);
+ MPI_Type_free(&type);
+
+ return errs;
+}
+
+/* Test an indexed (and hindexed) type where the block length is the same for
+ * all blocks, but with differing displacements so that it cannot directly be
+ * converted to a vector type. It is also important to add a dummy element at
+ * the beginning in order to cause int/MPI_Aint misalignment for the
+ * displacement of the first non-zero-width component. */
+int indexed_same_lengths(void)
+{
+ int err, errs = 0;
+
+ int i;
+ MPI_Datatype type = MPI_DATATYPE_NULL;
+ int len[4];
+ int disp[4];
+ MPI_Aint adisp[4];
+ MPI_Aint lb, ub;
+ int *buf = NULL;
+
+ len[0] = 0;
+ len[1] = 1;
+ len[2] = 1;
+ len[3] = 1;
+
+ disp[0] = 0;
+ disp[1] = 1;
+ disp[2] = 3;
+ disp[3] = 8;
+
+ err = MPI_Type_indexed(4, len, disp, MPI_INT, &type);
+ check_err(err, "creating indexed type in indexed_same_lengths()");
+ err = MPI_Type_commit(&type);
+ check_err(err, "committing indexed type in indexed_same_lengths()");
+
+ MPI_Type_lb(type, &lb);
+ check(lb == 1 * sizeof(int));
+ MPI_Type_ub(type, &ub);
+ check(ub == 9 * sizeof(int));
+
+ buf = malloc(10*sizeof(int));
+ assert(buf != NULL);
+ for (i = 0; i < 10; ++i) {
+ buf[i] = i + 1;
+ }
+ err = pack_and_unpack((char *) buf, 1, type, 10 * sizeof(int));
+ check_err(err, "packing/unpacking in indexed_same_lengths()");
+ for (i = 0; i < 10; ++i) {
+ int expected;
+ if (i == 1 || i == 3 || i == 8)
+ expected = i + 1;
+ else
+ expected = 0;
+ check(buf[i] == expected);
+ }
+ free(buf);
+
+ MPI_Type_free(&type);
+
+ /* -------------------------------------------------------------------- */
+ /* now do the same as above, but with hindexed */
+ len[0] = 0;
+ len[1] = 1;
+ len[2] = 1;
+ len[3] = 1;
+
+ adisp[0] = 0 * sizeof(int);
+ adisp[1] = 1 * sizeof(int);
+ adisp[2] = 3 * sizeof(int);
+ adisp[3] = 8 * sizeof(int);
+
+ err = MPI_Type_hindexed(4, len, adisp, MPI_INT, &type);
+ check_err(err, "creating hindexed type in indexed_same_lengths()");
+ err = MPI_Type_commit(&type);
+ check_err(err, "committing hindexed type in indexed_same_lengths()");
+
+ MPI_Type_lb(type, &lb);
+ check(lb == 1 * sizeof(int));
+ MPI_Type_ub(type, &ub);
+ check(ub == 9 * sizeof(int));
+
+ buf = malloc(10*sizeof(int));
+ assert(buf != NULL);
+ for (i = 0; i < 10; ++i) {
+ buf[i] = i + 1;
+ }
+ err = pack_and_unpack((char *) buf, 1, type, 10 * sizeof(int));
+ check_err(err, "packing/unpacking in indexed_same_lengths()");
+ for (i = 0; i < 10; ++i) {
+ int expected;
+ if (i == 1 || i == 3 || i == 8)
+ expected = i + 1;
+ else
+ expected = 0;
+ check(buf[i] == expected);
+ }
+ free(buf);
+
+ MPI_Type_free(&type);
+
+ return errs;
+}
+
+/* pack_and_unpack()
+ *
+ * Perform packing and unpacking of a buffer for the purposes of checking
+ * to see if we are processing a type correctly. Zeros the buffer between
+ * these two operations, so the data described by the type should be in
+ * place upon return but all other regions of the buffer should be zero.
+ *
+ * Parameters:
+ * typebuf - pointer to buffer described by datatype and count that
+ * will be packed and then unpacked into
+ * count, datatype - description of typebuf
+ * typebufsz - size of typebuf; used specifically to zero the buffer
+ * between the pack and unpack steps
+ *
+ */
+static int pack_and_unpack(char *typebuf,
+ int count,
+ MPI_Datatype datatype,
+ int typebufsz)
+{
+ char *packbuf;
+ int err, errs = 0, pack_size, type_size, position;
+
+ err = MPI_Type_size(datatype, &type_size);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Type_size call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+
+ type_size *= count;
+
+ err = MPI_Pack_size(count, datatype, MPI_COMM_SELF, &pack_size);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Pack_size call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+ packbuf = (char *) malloc(pack_size);
+ if (packbuf == NULL) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in malloc call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+
+ position = 0;
+ err = MPI_Pack(typebuf,
+ count,
+ datatype,
+ packbuf,
+ type_size,
+ &position,
+ MPI_COMM_SELF);
+
+ if (position != type_size) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (pack)\n",
+ position, type_size);
+ }
+
+ memset(typebuf, 0, typebufsz);
+ position = 0;
+ err = MPI_Unpack(packbuf,
+ type_size,
+ &position,
+ typebuf,
+ count,
+ datatype,
+ MPI_COMM_SELF);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Unpack call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+ free(packbuf);
+
+ if (position != type_size) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (unpack)\n",
+ position, type_size);
+ }
+
+ return errs;
+}
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2012 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+
+/* This test checks for large count functionality ("MPI_Count") mandated by
+ * MPI-3, as well as behavior of corresponding pre-MPI-3 interfaces that now
+ * have better defined behavior when an "int" quantity would overflow. */
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+
+/* assert-like macro that bumps the err count and emits a message */
+#define check(x_) \
+ do { \
+ if (!(x_)) { \
+ ++errs; \
+ if (errs < 10) { \
+ fprintf(stderr, "check failed: (%s), line %d\n", #x_, __LINE__); \
+ } \
+ } \
+ } while (0)
+
+int main(int argc, char *argv[])
+{
+ int errs = 0;
+ int wrank, wsize;
+ int size, elements, count;
+ MPI_Aint lb, extent;
+ MPI_Count size_x, lb_x, extent_x, elements_x;
+ double imx4i_true_extent;
+ MPI_Datatype imax_contig = MPI_DATATYPE_NULL;
+ MPI_Datatype four_ints = MPI_DATATYPE_NULL;
+ MPI_Datatype imx4i = MPI_DATATYPE_NULL;
+ MPI_Datatype imx4i_rsz = MPI_DATATYPE_NULL;
+ MPI_Status status;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
+ MPI_Comm_size(MPI_COMM_WORLD, &wsize);
+
+ check(sizeof(MPI_Count) >= sizeof(int));
+ check(sizeof(MPI_Count) >= sizeof(MPI_Aint));
+ check(sizeof(MPI_Count) >= sizeof(MPI_Offset));
+
+ /* the following two checks aren't explicitly required by the standard, but
+ * it's hard to imagine a world without them holding true and so most of the
+ * subsequent code probably depends on them to some degree */
+ check(sizeof(MPI_Aint) >= sizeof(int));
+ check(sizeof(MPI_Offset) >= sizeof(int));
+
+ /* not much point in checking for integer overflow cases if MPI_Count is
+ * only as large as an int */
+ if (sizeof(MPI_Count) == sizeof(int))
+ goto epilogue;
+
+ /* a very large type */
+ MPI_Type_contiguous(INT_MAX, MPI_CHAR, &imax_contig);
+ MPI_Type_commit(&imax_contig);
+
+ /* a small-ish contig */
+ MPI_Type_contiguous(4, MPI_INT, &four_ints);
+ MPI_Type_commit(&four_ints);
+
+ /* a type with size>INT_MAX */
+ MPI_Type_vector(INT_MAX/2, 1, 3, four_ints, &imx4i);
+ MPI_Type_commit(&imx4i);
+ /* don't forget, ub for dtype w/ stride doesn't include any holes at the end
+ * of the type, hence the more complicated calculation below */
+ imx4i_true_extent = 3LL*4LL*sizeof(int)*((INT_MAX/2)-1) + 4LL*sizeof(int);
+
+ /* sanity check that the MPI_COUNT predefined named datatype exists */
+ MPI_Send(&imx4i_true_extent, 1, MPI_COUNT, MPI_PROC_NULL, 0, MPI_COMM_SELF);
+
+ /* the same oversized type but with goofy extents */
+ MPI_Type_create_resized(imx4i, /*lb=*/INT_MAX, /*extent=*/-1024, &imx4i_rsz);
+ MPI_Type_commit(&imx4i_rsz);
+
+ /* MPI_Type_size */
+ MPI_Type_size(imax_contig, &size);
+ check(size == INT_MAX);
+ MPI_Type_size(four_ints, &size);
+ check(size == 4*sizeof(int));
+ MPI_Type_size(imx4i, &size);
+ check(size == MPI_UNDEFINED); /* should overflow an int */
+ MPI_Type_size(imx4i_rsz, &size);
+ check(size == MPI_UNDEFINED); /* should overflow an int */
+
+ /* MPI_Type_size_x */
+ MPI_Type_size_x(imax_contig, &size_x);
+ check(size_x == INT_MAX);
+ MPI_Type_size_x(four_ints, &size_x);
+ check(size_x == 4*sizeof(int));
+ MPI_Type_size_x(imx4i, &size_x);
+ check(size_x == 4LL*sizeof(int)*(INT_MAX/2)); /* should overflow an int */
+ MPI_Type_size_x(imx4i_rsz, &size_x);
+ check(size_x == 4LL*sizeof(int)*(INT_MAX/2)); /* should overflow an int */
+
+ /* MPI_Type_get_extent */
+ MPI_Type_get_extent(imax_contig, &lb, &extent);
+ check(lb == 0);
+ check(extent == INT_MAX);
+ MPI_Type_get_extent(four_ints, &lb, &extent);
+ check(lb == 0);
+ check(extent == 4*sizeof(int));
+ MPI_Type_get_extent(imx4i, &lb, &extent);
+ check(lb == 0);
+ if (sizeof(MPI_Aint) == sizeof(int))
+ check(extent == MPI_UNDEFINED);
+ else
+ check(extent == imx4i_true_extent);
+
+ MPI_Type_get_extent(imx4i_rsz, &lb, &extent);
+ check(lb == INT_MAX);
+ check(extent == -1024);
+
+ /* MPI_Type_get_extent_x */
+ MPI_Type_get_extent_x(imax_contig, &lb_x, &extent_x);
+ check(lb_x == 0);
+ check(extent_x == INT_MAX);
+ MPI_Type_get_extent_x(four_ints, &lb_x, &extent_x);
+ check(lb_x == 0);
+ check(extent_x == 4*sizeof(int));
+ MPI_Type_get_extent_x(imx4i, &lb_x, &extent_x);
+ check(lb_x == 0);
+ check(extent_x == imx4i_true_extent);
+ MPI_Type_get_extent_x(imx4i_rsz, &lb_x, &extent_x);
+ check(lb_x == INT_MAX);
+ check(extent_x == -1024);
+
+ /* MPI_Type_get_true_extent */
+ MPI_Type_get_true_extent(imax_contig, &lb, &extent);
+ check(lb == 0);
+ check(extent == INT_MAX);
+ MPI_Type_get_true_extent(four_ints, &lb, &extent);
+ check(lb == 0);
+ check(extent == 4*sizeof(int));
+ MPI_Type_get_true_extent(imx4i, &lb, &extent);
+ check(lb == 0);
+ if (sizeof(MPI_Aint) == sizeof(int))
+ check(extent == MPI_UNDEFINED);
+ else
+ check(extent == imx4i_true_extent);
+ MPI_Type_get_true_extent(imx4i_rsz, &lb, &extent);
+ check(lb == 0);
+ if (sizeof(MPI_Aint) == sizeof(int))
+ check(extent == MPI_UNDEFINED);
+ else
+ check(extent == imx4i_true_extent);
+
+ /* MPI_Type_get_true_extent_x */
+ MPI_Type_get_true_extent_x(imax_contig, &lb_x, &extent_x);
+ check(lb_x == 0);
+ check(extent_x == INT_MAX);
+ MPI_Type_get_true_extent_x(four_ints, &lb_x, &extent_x);
+ check(lb_x == 0);
+ check(extent_x == 4*sizeof(int));
+ MPI_Type_get_true_extent_x(imx4i, &lb_x, &extent_x);
+ check(lb_x == 0);
+ check(extent_x == imx4i_true_extent);
+ MPI_Type_get_true_extent_x(imx4i_rsz, &lb_x, &extent_x);
+ check(lb_x == 0);
+ check(extent_x == imx4i_true_extent);
+
+
+ /* MPI_{Status_set_elements,Get_elements}{,_x} */
+
+ /* set simple */
+ MPI_Status_set_elements(&status, MPI_INT, 10);
+ MPI_Get_elements(&status, MPI_INT, &elements);
+ MPI_Get_elements_x(&status, MPI_INT, &elements_x);
+ MPI_Get_count(&status, MPI_INT, &count);
+ check(elements == 10);
+ check(elements_x == 10);
+ check(count == 10);
+
+ /* set_x simple */
+ MPI_Status_set_elements_x(&status, MPI_INT, 10);
+ MPI_Get_elements(&status, MPI_INT, &elements);
+ MPI_Get_elements_x(&status, MPI_INT, &elements_x);
+ MPI_Get_count(&status, MPI_INT, &count);
+ check(elements == 10);
+ check(elements_x == 10);
+ check(count == 10);
+
+ /* Sets elements corresponding to count=1 of the given MPI datatype, using
+ * set_elements and set_elements_x. Checks expected values are returned by
+ * get_elements, get_elements_x, and get_count (including MPI_UNDEFINED
+ * clipping) */
+#define check_set_elements(type_, elts_) \
+ do { \
+ elements = elements_x = count = 0xfeedface; \
+ /* can't use legacy "set" for large element counts */ \
+ if ((elts_) <= INT_MAX) { \
+ MPI_Status_set_elements(&status, (type_), 1); \
+ MPI_Get_elements(&status, (type_), &elements); \
+ MPI_Get_elements_x(&status, (type_), &elements_x); \
+ MPI_Get_count(&status, (type_), &count); \
+ check(elements == (elts_)); \
+ check(elements_x == (elts_)); \
+ check(count == 1); \
+ } \
+ \
+ elements = elements_x = count = 0xfeedface; \
+ MPI_Status_set_elements_x(&status, (type_), 1); \
+ MPI_Get_elements(&status, (type_), &elements); \
+ MPI_Get_elements_x(&status, (type_), &elements_x); \
+ MPI_Get_count(&status, (type_), &count); \
+ if ((elts_) > INT_MAX) { \
+ check(elements == MPI_UNDEFINED); \
+ } \
+ else { \
+ check(elements == (elts_)); \
+ } \
+ check(elements_x == (elts_)); \
+ check(count == 1); \
+ } while (0) \
+
+ check_set_elements(imax_contig, INT_MAX);
+ check_set_elements(four_ints, 4);
+ check_set_elements(imx4i, 4LL*(INT_MAX/2));
+ check_set_elements(imx4i_rsz, 4LL*(INT_MAX/2));
+
+epilogue:
+ if (imax_contig != MPI_DATATYPE_NULL) MPI_Type_free(&imax_contig);
+ if (four_ints != MPI_DATATYPE_NULL) MPI_Type_free(&four_ints);
+ if (imx4i != MPI_DATATYPE_NULL) MPI_Type_free(&imx4i);
+ if (imx4i_rsz != MPI_DATATYPE_NULL) MPI_Type_free(&imx4i_rsz);
+
+ MPI_Reduce((wrank == 0 ? MPI_IN_PLACE : &errs), &errs, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (wrank == 0) {
+ if (errs) {
+ printf("found %d errors\n", errs);
+ }
+ else {
+ printf(" No errors\n");
+ }
+ }
+
+ MPI_Finalize();
+
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+/*
+ The default behavior of the test routines should be to briefly indicate
+ the cause of any errors - in this test, that means that verbose needs
+ to be set. Verbose should turn on output that is independent of error
+ levels.
+*/
+static int verbose = 1;
+
+/* tests */
+int int_with_lb_ub_test(void);
+int contig_of_int_with_lb_ub_test(void);
+int contig_negextent_of_int_with_lb_ub_test(void);
+int vector_of_int_with_lb_ub_test(void);
+int vector_blklen_of_int_with_lb_ub_test(void);
+int vector_blklen_stride_of_int_with_lb_ub_test(void);
+int vector_blklen_stride_negextent_of_int_with_lb_ub_test(void);
+int vector_blklen_negstride_negextent_of_int_with_lb_ub_test(void);
+int int_with_negextent_test(void);
+int vector_blklen_negstride_of_int_with_lb_ub_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MTest_Init( &argc, &argv );
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = int_with_lb_ub_test();
+ if (err && verbose) fprintf(stderr, "found %d errors in simple lb/ub test\n", err);
+ errs += err;
+
+ err = contig_of_int_with_lb_ub_test();
+ if (err && verbose) fprintf(stderr, "found %d errors in contig test\n", err);
+ errs += err;
+
+ err = contig_negextent_of_int_with_lb_ub_test();
+ if (err && verbose) fprintf(stderr, "found %d errors in negextent contig test\n", err);
+ errs += err;
+
+ err = vector_of_int_with_lb_ub_test();
+ if (err && verbose) fprintf(stderr, "found %d errors in simple vector test\n", err);
+ errs += err;
+
+ err = vector_blklen_of_int_with_lb_ub_test();
+ if (err && verbose) fprintf(stderr, "found %d errors in vector blklen test\n", err);
+ errs += err;
+
+ err = vector_blklen_stride_of_int_with_lb_ub_test();
+ if (err && verbose) fprintf(stderr, "found %d errors in strided vector test\n", err);
+ errs += err;
+
+ err = vector_blklen_negstride_of_int_with_lb_ub_test();
+ if (err && verbose) fprintf(stderr, "found %d errors in negstrided vector test\n", err);
+ errs += err;
+
+ err = int_with_negextent_test();
+ if (err && verbose) fprintf(stderr, "found %d errors in negextent lb/ub test\n", err);
+ errs += err;
+
+ err = vector_blklen_stride_negextent_of_int_with_lb_ub_test();
+ if (err && verbose) fprintf(stderr, "found %d errors in strided negextent vector test\n", err);
+ errs += err;
+
+ err = vector_blklen_negstride_negextent_of_int_with_lb_ub_test();
+ if (err && verbose) fprintf(stderr, "found %d errors in negstrided negextent vector test\n", err);
+ errs += err;
+
+ MTest_Finalize( errs );
+ MPI_Finalize();
+ return 0;
+}
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
+
+int int_with_lb_ub_test(void)
+{
+ int err, errs = 0, val;
+ MPI_Aint lb, extent, aval, true_lb;
+ int blocks[3] = { 1, 4, 1 };
+ MPI_Aint disps[3] = { -3, 0, 6 };
+ MPI_Datatype types[3] = { MPI_LB, MPI_BYTE, MPI_UB };
+
+ MPI_Datatype eviltype;
+
+ err = MPI_Type_struct(3, blocks, disps, types, &eviltype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_struct failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ err = MPI_Type_size(eviltype, &val);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_size failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (val != 4) {
+ errs++;
+ if (verbose) fprintf(stderr, " size of type = %d; should be %d\n", val, 4);
+ }
+
+ err = MPI_Type_extent(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 9) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %ld; should be %d\n", (long) aval, 9);
+ }
+
+ err = MPI_Type_lb(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_lb failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n", (int) aval, -3);
+ }
+
+ err = MPI_Type_get_extent(eviltype, &lb, &extent);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (lb != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n",
+ (int) aval, -3);
+ }
+
+ if (extent != 9) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n",
+ (int) extent, 9);
+ }
+
+ err = MPI_Type_ub(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_ub failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 6) {
+ errs++;
+ if (verbose) fprintf(stderr, " ub of type = %d; should be %d\n", (int) aval, 6);
+ }
+
+ err = MPI_Type_get_true_extent(eviltype, &true_lb, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_true_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (true_lb != 0) {
+ errs++;
+ if (verbose) fprintf(stderr, " true_lb of type = %d; should be %d\n", (int) true_lb, 0);
+ }
+
+ if (aval != 4) {
+ errs++;
+ if (verbose) fprintf(stderr, " true extent of type = %d; should be %d\n", (int) aval, 4);
+ }
+
+ MPI_Type_free(&eviltype);
+
+ return errs;
+}
+
+int contig_of_int_with_lb_ub_test(void)
+{
+ int err, errs = 0, val;
+ MPI_Aint lb, extent, aval, true_lb;
+ int blocks[3] = { 1, 4, 1 };
+ MPI_Aint disps[3] = { -3, 0, 6 };
+ MPI_Datatype types[3] = { MPI_LB, MPI_BYTE, MPI_UB };
+ char *typemapstring = 0;
+
+ MPI_Datatype inttype, eviltype;
+
+ /* build same type as in int_with_lb_ub_test() */
+ typemapstring = (char*)"{ (LB,-3),4*(BYTE,0),(UB,6) }";
+ err = MPI_Type_struct(3, blocks, disps, types, &inttype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_struct of %s failed.\n",
+ typemapstring );
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ typemapstring=(char*)"{ (LB,-3),4*(BYTE,0),(UB,6),(LB,6),4*(BYTE,9),(UB,15),(LB,15),4*(BYTE,18),(UB,24)}";
+ err = MPI_Type_contiguous(3, inttype, &eviltype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_contiguous of %s failed.\n",
+ typemapstring );
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_size(eviltype, &val);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_size of %s failed.\n",
+ typemapstring );
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (val != 12) {
+ errs++;
+ if (verbose) fprintf(stderr, " size of type = %d; should be %d\n",
+ val, 12);
+ }
+
+ err = MPI_Type_extent(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 27) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n", (int) aval, 27);
+ if (verbose) fprintf( stderr, " for type %s\n", typemapstring );
+ }
+
+ err = MPI_Type_lb(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_lb failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d from Type_lb; should be %d in %s\n", (int) aval, -3, typemapstring );
+ }
+
+ err = MPI_Type_get_extent(eviltype, &lb, &extent);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (lb != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d from Type_get_extent; should be %d in %s\n",
+ (int) aval, -3, typemapstring );
+ }
+
+ if (extent != 27) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d from Type_get_extent; should be %d in %s\n",
+ (int) extent, 27, typemapstring);
+ }
+
+ err = MPI_Type_ub(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_ub failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 24) {
+ errs++;
+ if (verbose) fprintf(stderr, " ub of type = %d in Type_ub; should be %din %s\n", (int) aval, 24, typemapstring);
+ }
+
+ err = MPI_Type_get_true_extent(eviltype, &true_lb, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_true_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (true_lb != 0) {
+ errs++;
+ if (verbose) fprintf(stderr, " true_lb of type = %d; should be %d in %s\n", (int) true_lb, 0, typemapstring);
+ }
+
+ if (aval != 22) {
+ errs++;
+ if (verbose) fprintf(stderr, " true extent of type = %d; should be %d in %s\n", (int) aval, 22, typemapstring);
+ }
+
+ MPI_Type_free( &inttype );
+ MPI_Type_free( &eviltype );
+
+ return errs;
+}
+
+int contig_negextent_of_int_with_lb_ub_test(void)
+{
+ int err, errs = 0, val;
+ MPI_Aint lb, extent, aval, true_lb;
+ int blocks[3] = { 1, 4, 1 };
+ MPI_Aint disps[3] = { 6, 0, -3 };
+ MPI_Datatype types[3] = { MPI_LB, MPI_BYTE, MPI_UB };
+ char *typemapstring = 0;
+
+ MPI_Datatype inttype, eviltype;
+
+ /* build same type as in int_with_lb_ub_test() */
+ typemapstring = (char*)"{ (LB,6),4*(BYTE,0),(UB,-3) }";
+ err = MPI_Type_struct(3, blocks, disps, types, &inttype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_struct of %s failed.\n",
+ typemapstring );
+ if (verbose) MTestPrintError( err );
+ /* No point in continuing */
+ return errs;
+ }
+
+ typemapstring = (char*)"{ (LB,6),4*(BYTE,0),(UB,-3),(LB,-3),4*(BYTE,-9),(UB,-12),(LB,-12),4*(BYTE,-18),(UB,-21) }";
+ err = MPI_Type_contiguous(3, inttype, &eviltype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_contiguous of %s failed.\n",
+ typemapstring);
+ if (verbose) MTestPrintError( err );
+ /* No point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_size(eviltype, &val);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_size of %s failed.\n",
+ typemapstring);
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (val != 12) {
+ errs++;
+ if (verbose) fprintf(stderr, " size of type = %d; should be %d\n", val, 12);
+ }
+
+ err = MPI_Type_extent(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 9) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n", (int) aval, 9);
+ }
+
+ err = MPI_Type_lb(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_lb failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -12) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n", (int) aval, -12);
+ }
+
+ err = MPI_Type_get_extent(eviltype, &lb, &extent);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (lb != -12) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n",
+ (int) aval, -12);
+ }
+
+ if (extent != 9) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n",
+ (int) extent, 9);
+ }
+
+ err = MPI_Type_ub(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_ub failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " ub of type = %d; should be %d\n", (int) aval, -3);
+ }
+
+ err = MPI_Type_get_true_extent(eviltype, &true_lb, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_true_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (true_lb != -18) {
+ errs++;
+ if (verbose) fprintf(stderr, " true_lb of type = %d; should be %d\n", (int) true_lb, -18);
+ }
+
+ if (aval != 22) {
+ errs++;
+ if (verbose) fprintf(stderr, " true extent of type = %d; should be %d\n", (int) aval, 22);
+ }
+
+ MPI_Type_free( &inttype );
+ MPI_Type_free( &eviltype );
+
+ return errs;
+}
+
+int vector_of_int_with_lb_ub_test(void)
+{
+ int err, errs = 0, val;
+ MPI_Aint lb, extent, aval, true_lb;
+ int blocks[3] = { 1, 4, 1 };
+ MPI_Aint disps[3] = { -3, 0, 6 };
+ MPI_Datatype types[3] = { MPI_LB, MPI_BYTE, MPI_UB };
+
+ MPI_Datatype inttype, eviltype;
+
+ /* build same type as in int_with_lb_ub_test() */
+ err = MPI_Type_struct(3, blocks, disps, types, &inttype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_struct failed.\n");
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_vector(3, 1, 1, inttype, &eviltype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_vector failed.\n");
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_size(eviltype, &val);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_size failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (val != 12) {
+ errs++;
+ if (verbose) fprintf(stderr, " size of type = %d; should be %d\n", val, 12);
+ }
+
+ err = MPI_Type_extent(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 27) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n", (int) aval, 27);
+ }
+
+ err = MPI_Type_lb(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_lb failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n", (int) aval, -3);
+ }
+
+ err = MPI_Type_get_extent(eviltype, &lb, &extent);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (lb != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n",
+ (int) aval, -3);
+ }
+
+ if (extent != 27) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n",
+ (int) extent, 27);
+ }
+
+ err = MPI_Type_ub(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_ub failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 24) {
+ errs++;
+ if (verbose) fprintf(stderr, " ub of type = %d; should be %d\n", (int) aval, 24);
+ }
+
+ err = MPI_Type_get_true_extent(eviltype, &true_lb, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_true_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (true_lb != 0) {
+ errs++;
+ if (verbose) fprintf(stderr, " true_lb of type = %d; should be %d\n", (int) true_lb, 0);
+ }
+
+ if (aval != 22) {
+ errs++;
+ if (verbose) fprintf(stderr, " true extent of type = %d; should be %d\n", (int) aval, 22);
+ }
+
+ MPI_Type_free( &inttype );
+ MPI_Type_free( &eviltype );
+
+ return errs;
+}
+
+/*
+ * blklen = 4
+ */
+int vector_blklen_of_int_with_lb_ub_test(void)
+{
+ int err, errs = 0, val;
+ MPI_Aint lb, extent, aval, true_lb;
+ int blocks[3] = { 1, 4, 1 };
+ MPI_Aint disps[3] = { -3, 0, 6 };
+ MPI_Datatype types[3] = { MPI_LB, MPI_BYTE, MPI_UB };
+
+ MPI_Datatype inttype, eviltype;
+
+ /* build same type as in int_with_lb_ub_test() */
+ err = MPI_Type_struct(3, blocks, disps, types, &inttype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_struct failed.\n");
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_vector(3, 4, 1, inttype, &eviltype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_vector failed.\n");
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_size(eviltype, &val);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_size failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (val != 48) {
+ errs++;
+ if (verbose) fprintf(stderr, " size of type = %d; should be %d\n", val, 48);
+ }
+
+ err = MPI_Type_extent(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 54) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n", (int) aval, 54);
+ }
+
+ err = MPI_Type_lb(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_lb failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n", (int) aval, -3);
+ if (verbose) MTestPrintError( err );
+ }
+
+ err = MPI_Type_get_extent(eviltype, &lb, &extent);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (lb != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n",
+ (int) aval, -3);
+ }
+
+ if (extent != 54) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n",
+ (int) extent, 54);
+ }
+
+ err = MPI_Type_ub(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_ub failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 51) {
+ errs++;
+ if (verbose) fprintf(stderr, " ub of type = %d; should be %d\n", (int) aval, 51);
+ }
+
+ err = MPI_Type_get_true_extent(eviltype, &true_lb, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_true_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (true_lb != 0) {
+ errs++;
+ if (verbose) fprintf(stderr, " true_lb of type = %d; should be %d\n", (int) true_lb, 0);
+ }
+
+ if (aval != 49) {
+ errs++;
+ if (verbose) fprintf(stderr, " true extent of type = %d; should be %d\n", (int) aval, 49);
+ }
+
+ MPI_Type_free( &inttype );
+ MPI_Type_free( &eviltype );
+
+ return errs;
+}
+
+int vector_blklen_stride_of_int_with_lb_ub_test(void)
+{
+ int err, errs = 0, val;
+ MPI_Aint lb, extent, aval, true_lb;
+ int blocks[3] = { 1, 4, 1 };
+ MPI_Aint disps[3] = { -3, 0, 6 };
+ MPI_Datatype types[3] = { MPI_LB, MPI_BYTE, MPI_UB };
+ char *typemapstring = 0;
+
+ MPI_Datatype inttype, eviltype;
+
+ /* build same type as in int_with_lb_ub_test() */
+ typemapstring = (char*)"{ (LB,-3),4*(BYTE,0),(UB,6) }";
+ err = MPI_Type_struct(3, blocks, disps, types, &inttype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_struct of %s failed.\n",
+ typemapstring );
+ if (verbose) MTestPrintError( err );
+ /* No point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_vector(3, 4, 5, inttype, &eviltype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_vector failed.\n");
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_size(eviltype, &val);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_size failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (val != 48) {
+ errs++;
+ if (verbose) fprintf(stderr, " size of type = %d; should be %d\n", val, 48);
+ }
+
+ err = MPI_Type_extent(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 126) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n", (int) aval, 126);
+ }
+
+ err = MPI_Type_lb(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_lb failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n", (int) aval, -3);
+ }
+
+ err = MPI_Type_get_extent(eviltype, &lb, &extent);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (lb != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n",
+ (int) aval, -3);
+ }
+
+ if (extent != 126) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n",
+ (int) extent, 126);
+ }
+
+ err = MPI_Type_ub(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_ub failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 123) {
+ errs++;
+ if (verbose) fprintf(stderr, " ub of type = %d; should be %d\n", (int) aval, 123);
+ }
+
+ err = MPI_Type_get_true_extent(eviltype, &true_lb, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_true_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (true_lb != 0) {
+ errs++;
+ if (verbose) fprintf(stderr, " true_lb of type = %d; should be %d\n", (int) true_lb, 0);
+ }
+
+ if (aval != 121) {
+ errs++;
+ if (verbose) fprintf(stderr, " true extent of type = %d; should be %d\n", (int) aval, 121);
+ }
+
+ MPI_Type_free( &inttype );
+ MPI_Type_free( &eviltype );
+
+ return errs;
+}
+
+int vector_blklen_negstride_of_int_with_lb_ub_test(void)
+{
+ int err, errs = 0, val;
+ MPI_Aint lb, extent, aval, true_lb;
+ int blocks[3] = { 1, 4, 1 };
+ MPI_Aint disps[3] = { -3, 0, 6 };
+ MPI_Datatype types[3] = { MPI_LB, MPI_BYTE, MPI_UB };
+
+ MPI_Datatype inttype, eviltype;
+
+ /* build same type as in int_with_lb_ub_test() */
+ err = MPI_Type_struct(3, blocks, disps, types, &inttype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_struct failed.\n");
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_vector(3, 4, -5, inttype, &eviltype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_vector failed.\n");
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_size(eviltype, &val);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_size failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (val != 48) {
+ errs++;
+ if (verbose) fprintf(stderr, " size of type = %d; should be %d\n", val, 48);
+ }
+
+ err = MPI_Type_extent(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 126) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n", (int) aval, 126);
+ }
+
+ err = MPI_Type_lb(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_lb failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -93) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n", (int) aval, -93);
+ }
+
+ err = MPI_Type_get_extent(eviltype, &lb, &extent);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (lb != -93) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n",
+ (int) aval, -93);
+ }
+
+ if (extent != 126) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n",
+ (int) extent, 126);
+ }
+
+ err = MPI_Type_ub(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_ub failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 33) {
+ errs++;
+ if (verbose) fprintf(stderr, " ub of type = %d; should be %d\n", (int) aval, 33);
+ }
+
+ err = MPI_Type_get_true_extent(eviltype, &true_lb, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_true_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (true_lb != -90) {
+ errs++;
+ if (verbose) fprintf(stderr, " true_lb of type = %d; should be %d\n", (int) true_lb, -90);
+ }
+
+ if (aval != 121) {
+ errs++;
+ if (verbose) fprintf(stderr, " true extent of type = %d; should be %d\n", (int) aval, 121);
+ }
+
+ MPI_Type_free( &inttype );
+ MPI_Type_free( &eviltype );
+
+ return errs;
+}
+
+int int_with_negextent_test(void)
+{
+ int err, errs = 0, val;
+ MPI_Aint lb, extent, aval, true_lb;
+ int blocks[3] = { 1, 4, 1 };
+ MPI_Aint disps[3] = { 6, 0, -3 };
+ MPI_Datatype types[3] = { MPI_LB, MPI_BYTE, MPI_UB };
+ char *typemapstring =0;
+
+ MPI_Datatype eviltype;
+
+ typemapstring = (char*)"{ (LB,6),4*(BYTE,0),(UB,-3) }";
+ err = MPI_Type_struct(3, blocks, disps, types, &eviltype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_struct of %s failed.\n",
+ typemapstring );
+ if (verbose) MTestPrintError( err );
+ /* No point in contiuing */
+ return errs;
+ }
+
+ err = MPI_Type_size(eviltype, &val);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_size failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (val != 4) {
+ errs++;
+ if (verbose) fprintf(stderr, " size of type = %d; should be %d\n", val, 4);
+ }
+
+ err = MPI_Type_extent(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -9) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n", (int) aval, -9);
+ }
+
+ err = MPI_Type_lb(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_lb failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 6) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n", (int) aval, 6);
+ }
+
+ err = MPI_Type_get_extent(eviltype, &lb, &extent);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (lb != 6) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n",
+ (int) aval, 6);
+ }
+
+ if (extent != -9) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n",
+ (int) extent, -9);
+ }
+
+ err = MPI_Type_ub(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_ub failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " ub of type = %d; should be %d\n", (int) aval, -3);
+ }
+
+ err = MPI_Type_get_true_extent(eviltype, &true_lb, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_true_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (true_lb != 0) {
+ errs++;
+ if (verbose) fprintf(stderr, " true_lb of type = %d; should be %d\n", (int) true_lb, 0);
+ }
+
+ if (aval != 4) {
+ errs++;
+ if (verbose) fprintf(stderr, " true extent of type = %d; should be %d\n", (int) aval, 4);
+ }
+
+ MPI_Type_free(&eviltype);
+
+ return errs;
+}
+
+int vector_blklen_stride_negextent_of_int_with_lb_ub_test(void)
+{
+ int err, errs = 0, val;
+ MPI_Aint lb, extent, true_lb, aval;
+ int blocks[3] = { 1, 4, 1 };
+ MPI_Aint disps[3] = { 6, 0, -3 };
+ MPI_Datatype types[3] = { MPI_LB, MPI_BYTE, MPI_UB };
+ MPI_Datatype inttype, eviltype;
+ char *typemapstring = 0;
+
+ /* build same type as in int_with_lb_ub_test() */
+ typemapstring = (char*)"{ (LB,6),4*(BYTE,0),(UB,-3) }";
+ err = MPI_Type_struct(3, blocks, disps, types, &inttype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_struct of %s failed.\n",
+ typemapstring );
+ if (verbose) MTestPrintError( err );
+ /* No point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_vector(3, 4, 5, inttype, &eviltype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_vector failed.\n");
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_size(eviltype, &val);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_size failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (val != 48) {
+ errs++;
+ if (verbose) fprintf(stderr, " size of type = %d; should be %d\n", val, 48);
+ }
+
+ err = MPI_Type_extent(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 108) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n", (int) aval, 108);
+ }
+
+ err = MPI_Type_lb(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_lb failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -111) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n", (int) aval, -111);
+ }
+
+ err = MPI_Type_get_extent(eviltype, &lb, &extent);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (lb != -111) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %d; should be %d\n",
+ (int) aval, -111);
+ }
+
+ if (extent != 108) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %d; should be %d\n",
+ (int) extent, 108);
+ }
+
+ err = MPI_Type_ub(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_ub failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -3) {
+ errs++;
+ if (verbose) fprintf(stderr, " ub of type = %d; should be %d\n", (int) aval, -3);
+ }
+
+ err = MPI_Type_get_true_extent(eviltype, &true_lb, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_true_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (true_lb != -117) {
+ errs++;
+ if (verbose) fprintf(stderr, " true_lb of type = %d; should be %d\n", (int) true_lb, -117);
+ }
+
+ if (aval != 121) {
+ errs++;
+ if (verbose) fprintf(stderr, " true extent of type = %d; should be %d\n", (int) aval, 121);
+ }
+
+ MPI_Type_free( &inttype );
+ MPI_Type_free( &eviltype );
+
+ return errs;
+}
+
+int vector_blklen_negstride_negextent_of_int_with_lb_ub_test(void)
+{
+ int err, errs = 0, val;
+ MPI_Aint extent, lb, aval, true_lb;
+ int blocks[3] = { 1, 4, 1 };
+ MPI_Aint disps[3] = { 6, 0, -3 };
+ MPI_Datatype types[3] = { MPI_LB, MPI_BYTE, MPI_UB };
+
+ MPI_Datatype inttype, eviltype;
+
+ /* build same type as in int_with_lb_ub_test() */
+ err = MPI_Type_struct(3, blocks, disps, types, &inttype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_struct failed.\n");
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_vector(3, 4, -5, inttype, &eviltype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_vector failed.\n");
+ if (verbose) MTestPrintError( err );
+ /* no point in continuing */
+ return errs;
+ }
+
+ err = MPI_Type_size(eviltype, &val);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_size failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (val != 48) {
+ errs++;
+ if (verbose) fprintf(stderr, " size of type = %d; should be %d\n", val, 48);
+ }
+
+ err = MPI_Type_extent(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 108) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %ld; should be %d\n", (long) aval, 108);
+ }
+
+ err = MPI_Type_lb(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_lb failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != -21) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %ld; should be %d\n", (long) aval, -21);
+ }
+
+ err = MPI_Type_get_extent(eviltype, &lb, &extent);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (lb != -21) {
+ errs++;
+ if (verbose) fprintf(stderr, " lb of type = %ld; should be %d\n",
+ (long) aval, -21);
+ }
+
+ if (extent != 108) {
+ errs++;
+ if (verbose) fprintf(stderr, " extent of type = %ld; should be %d\n",
+ (long) extent, 108);
+ }
+
+
+ err = MPI_Type_ub(eviltype, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_ub failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (aval != 87) {
+ errs++;
+ if (verbose) fprintf(stderr, " ub of type = %ld; should be %d\n", (long) aval, 87);
+ }
+
+ err = MPI_Type_get_true_extent(eviltype, &true_lb, &aval);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr, " MPI_Type_get_true_extent failed.\n");
+ if (verbose) MTestPrintError( err );
+ }
+
+ if (true_lb != -27) {
+ errs++;
+ if (verbose) fprintf(stderr, " true_lb of type = %ld; should be %d\n", (long) true_lb, -27);
+ }
+
+ if (aval != 121) {
+ errs++;
+ if (verbose) fprintf(stderr, " true extent of type = %ld; should be %d\n", (long) aval, 121);
+ }
+
+ MPI_Type_free( &inttype );
+ MPI_Type_free( &eviltype );
+
+ return errs;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+/* based on the pack.c test in the mpich suite.
+ */
+
+#include "mpi.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 0;
+
+#define BUF_SIZE 16384
+
+int main(int argc, char *argv[]);
+int parse_args(int argc, char **argv);
+
+int main(int argc, char *argv[])
+{
+ int errs = 0;
+ char buffer[BUF_SIZE];
+ int n, size;
+ double a,b;
+ int pos;
+
+ /* Initialize MPI */
+ MPI_Init(&argc, &argv);
+ parse_args(argc, argv);
+
+ pos = 0;
+ n = 10;
+ a = 1.1;
+ b = 2.2;
+
+ MPI_Pack(&n, 1, MPI_INT, buffer, BUF_SIZE, &pos, MPI_COMM_WORLD);
+ MPI_Pack(&a, 1, MPI_DOUBLE, buffer, BUF_SIZE, &pos, MPI_COMM_WORLD);
+ MPI_Pack(&b, 1, MPI_DOUBLE, buffer, BUF_SIZE, &pos, MPI_COMM_WORLD);
+
+ size = pos;
+ pos = 0;
+ n = 0;
+ a = 0;
+ b = 0;
+
+ MPI_Unpack(buffer, size, &pos, &n, 1, MPI_INT, MPI_COMM_WORLD);
+ MPI_Unpack(buffer, size, &pos, &a, 1, MPI_DOUBLE, MPI_COMM_WORLD);
+ MPI_Unpack(buffer, size, &pos, &b, 1, MPI_DOUBLE, MPI_COMM_WORLD);
+ /* Check results */
+ if (n != 10) {
+ errs++;
+ if (verbose) fprintf(stderr, "Wrong value for n; got %d expected %d\n", n, 10 );
+ }
+ if (a != 1.1) {
+ errs++;
+ if (verbose) fprintf(stderr, "Wrong value for a; got %f expected %f\n", a, 1.1 );
+ }
+ if (b != 2.2) {
+ errs++;
+ if (verbose) fprintf(stderr, "Wrong value for b; got %f expected %f\n", b, 2.2 );
+ }
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2012 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "mpi.h"
+#include "mpitest.h"
+
+/* Some MPI implementations should not support MPI_LONG_DOUBLE because it has
+ * different representations/sizes among several concurrently supported
+ * compilers. For example, a 16-byte GCC implementation and an 8-byte Cray
+ * compiler implementation.
+ *
+ * This test ensures that simplistic build logic/configuration did not result in
+ * a defined, yet incorrectly sized, MPI predefined datatype for long double and
+ * long double _Complex. See tt#1671 for more info.
+ *
+ * Based on a test suggested by Jim Hoekstra @ Iowa State University. */
+
+int main(int argc, char *argv[])
+{
+ int rank, size, type_size;
+ int errs = 0;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+ if (rank == 0) {
+#ifdef HAVE_LONG_DOUBLE
+ if (MPI_LONG_DOUBLE != MPI_DATATYPE_NULL) {
+ MPI_Type_size(MPI_LONG_DOUBLE, &type_size);
+ if (type_size != sizeof(long double)) {
+ printf("type_size != sizeof(long double) : (%zd != %zd)\n",
+ (size_t)type_size, sizeof(long double));
+ ++errs;
+ }
+ }
+#endif
+#if defined(HAVE_LONG_DOUBLE__COMPLEX) && defined(USE_LONG_DOUBLE_COMPLEX)
+ if (MPI_C_LONG_DOUBLE_COMPLEX != MPI_DATATYPE_NULL) {
+ MPI_Type_size(MPI_C_LONG_DOUBLE_COMPLEX, &type_size);
+ if (type_size != sizeof(long double _Complex)) {
+ printf("type_size != sizeof(long double _Complex) : (%zd != %zd)\n",
+ (size_t)type_size, sizeof(long double _Complex));
+ ++errs;
+ }
+ }
+#endif
+ if (errs) {
+ printf("found %d errors\n", errs);
+ }
+ else {
+ printf(" No errors\n");
+ }
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpi.h"
+#include "mpitest.h"
+
+/*
+ The default behavior of the test routines should be to briefly indicate
+ the cause of any errors - in this test, that means that verbose needs
+ to be set. Verbose should turn on output that is independent of error
+ levels.
+*/
+static int verbose = 1;
+
+int main(int argc, char *argv[]);
+int parse_args(int argc, char **argv);
+int lots_of_types_test(void);
+
+struct test_struct_1 {
+ int a,b,c,d;
+};
+
+int main(int argc, char *argv[])
+{
+ int err, errs = 0;
+
+ /* Initialize MPI */
+ MTest_Init(&argc, &argv);
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ err = lots_of_types_test();
+ if (verbose && err) fprintf(stderr, "error in lots_of_types_test\n");
+ errs += err;
+
+ /* print message and exit */
+ MTest_Finalize( errs );
+
+ MPI_Finalize();
+ return 0;
+}
+
+/* this test allocates 1024 indexed datatypes with 1024 distinct blocks
+ * each. it's possible that a low memory machine will run out of memory
+ * running this test; it appears to take ~25MB of memory at this time.
+ * -- Rob Ross, 11/2/2005
+ */
+#define NUM_DTYPES 1024
+#define NUM_BLOCKS 1024
+int lots_of_types_test(void)
+{
+ int err, errs = 0;
+ int i;
+ MPI_Datatype mytypes[NUM_DTYPES];
+
+ int sendbuf[4] = { 1, 2, 3, 4 };
+
+ int count, elements;
+ MPI_Request request;
+ MPI_Status status;
+
+ /* note: first element of struct has zero blklen and should be dropped */
+ int disps[NUM_BLOCKS];
+ int blks[NUM_BLOCKS];
+
+ for (i=0; i < NUM_DTYPES; i++)
+ mytypes[i] = MPI_DATATYPE_NULL;
+
+ for (i=0; i < NUM_DTYPES; i++) {
+ int j;
+
+ disps[0] = 0;
+ blks[0] = 4;
+
+ for (j=1; j < NUM_BLOCKS; j++) {
+ disps[j] = 4 * j;
+ blks[j] = (j % 3) + 1;
+ }
+
+ err = MPI_Type_indexed(NUM_BLOCKS, blks, disps, MPI_INT, &mytypes[i]);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_indexed returned error on type %d\n",
+ i);
+ }
+ mytypes[i] = MPI_DATATYPE_NULL;
+ goto fn_exit;
+ }
+
+ MPI_Type_commit(&mytypes[i]);
+ }
+
+ for (i=0; i < NUM_DTYPES; i++) {
+ int j;
+ int recvbuf[4] = { -1, -1, -1, -1 };
+
+ /* we will only receive 4 ints, so short buffer is ok */
+ err = MPI_Irecv(recvbuf, 1, mytypes[i], 0, 0, MPI_COMM_SELF, &request);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Irecv returned error\n");
+ }
+ }
+
+ err = MPI_Send(sendbuf, 4, MPI_INT, 0, 0, MPI_COMM_SELF);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Send returned error\n");
+ }
+ }
+
+ err = MPI_Wait(&request, &status);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Wait returned error\n");
+ }
+ }
+
+ /* verify data */
+ for (j=0; j < 4; j++) {
+ if (recvbuf[j] != sendbuf[j]) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "recvbuf[%d] = %d; should be %d\n",
+ j, recvbuf[j], sendbuf[j]);
+ }
+ }
+ }
+
+ /* verify count and elements */
+ err = MPI_Get_count(&status, mytypes[i], &count);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Get_count returned error\n");
+ }
+ }
+ if (count != MPI_UNDEFINED) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "count = %d; should be MPI_UNDEFINED (%d)\n",
+ count, MPI_UNDEFINED);
+ }
+ }
+
+ err = MPI_Get_elements(&status, mytypes[i], &elements);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Get_elements returned error\n");
+ }
+ }
+ if (elements != 4) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "elements = %d; should be 4\n", elements);
+ }
+ }
+ }
+
+ fn_exit:
+ for (i=0; i < NUM_DTYPES; i++) {
+ if (mytypes[i] != MPI_DATATYPE_NULL)
+ MPI_Type_free(&mytypes[i]);
+ }
+
+ return errs;
+}
+
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 0;
+
+int short_int_pack_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+static int pack_and_unpack(char *typebuf,
+ int count,
+ MPI_Datatype datatype,
+ int typebufsz);
+
+int main(int argc, char *argv[])
+{
+ int err, errs = 0;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ err = short_int_pack_test();
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+int short_int_pack_test(void)
+{
+ int i, err, errs = 0;
+
+ struct shortint { short a; int b; } sibuf[16];
+
+ for (i=0; i < 16; i++) {
+ sibuf[i].a = (short) (i * 2);
+ sibuf[i].b = i * 2 + 1;
+ }
+
+ err = pack_and_unpack((char *) sibuf, 16, MPI_SHORT_INT, sizeof(sibuf));
+ if (err != 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "error packing/unpacking in short_int_pack_test()\n");
+ }
+ errs += err;
+ }
+
+ for (i=0; i < 16; i++) {
+ if (sibuf[i].a != (short) (i * 2)) {
+ err++;
+ if (verbose) {
+ fprintf(stderr,
+ "buf[%d] has invalid short (%d); should be %d\n",
+ i, (int) sibuf[i].a, i * 2);
+ }
+ }
+ if (sibuf[i].b != i * 2 + 1) {
+ err++;
+ if (verbose) {
+ fprintf(stderr,
+ "buf[%d] has invalid int (%d); should be %d\n",
+ i, (int) sibuf[i].b, i * 2 + 1);
+ }
+ }
+ }
+
+ return errs;
+}
+
+/* pack_and_unpack()
+ *
+ * Perform packing and unpacking of a buffer for the purposes of checking
+ * to see if we are processing a type correctly. Zeros the buffer between
+ * these two operations, so the data described by the type should be in
+ * place upon return but all other regions of the buffer should be zero.
+ *
+ * Parameters:
+ * typebuf - pointer to buffer described by datatype and count that
+ * will be packed and then unpacked into
+ * count, datatype - description of typebuf
+ * typebufsz - size of typebuf; used specifically to zero the buffer
+ * between the pack and unpack steps
+ *
+ */
+static int pack_and_unpack(char *typebuf,
+ int count,
+ MPI_Datatype datatype,
+ int typebufsz)
+{
+ char *packbuf;
+ int err, errs = 0, pack_size, type_size, position;
+
+ err = MPI_Type_size(datatype, &type_size);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Type_size call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+
+ type_size *= count;
+
+ err = MPI_Pack_size(count, datatype, MPI_COMM_SELF, &pack_size);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Pack_size call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+ packbuf = (char *) malloc(pack_size);
+ if (packbuf == NULL) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in malloc call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+
+ position = 0;
+ err = MPI_Pack(typebuf,
+ count,
+ datatype,
+ packbuf,
+ type_size,
+ &position,
+ MPI_COMM_SELF);
+
+ if (position != type_size) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (pack)\n",
+ position, type_size);
+ }
+
+ memset(typebuf, 0, typebufsz);
+ position = 0;
+ err = MPI_Unpack(packbuf,
+ type_size,
+ &position,
+ typebuf,
+ count,
+ datatype,
+ MPI_COMM_SELF);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "error in MPI_Unpack call; aborting after %d errors\n",
+ errs);
+ }
+ return errs;
+ }
+ free(packbuf);
+
+ if (position != type_size) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (unpack)\n",
+ position, type_size);
+ }
+
+ return errs;
+}
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 1;
+
+
+
+int parse_args(int argc, char **argv);
+
+MPI_Aint pairtype_displacement(MPI_Datatype type, int *out_size_p);
+
+MPI_Aint pairtype_displacement(MPI_Datatype type, int *out_size_p)
+{
+ MPI_Aint disp;
+
+ /* Note that a portable test may not use a switch statement for
+ datatypes, as they are not required to be compile-time constants */
+ if (type == MPI_FLOAT_INT) {
+ struct { float a; int b; } foo;
+ disp = (MPI_Aint) ((char *) &foo.b - (char *) &foo.a);
+ *out_size_p = sizeof(foo);
+ }
+ else if (type == MPI_DOUBLE_INT) {
+ struct { double a; int b; } foo;
+ disp = (MPI_Aint) ((char *) &foo.b - (char *) &foo.a);
+ *out_size_p = sizeof(foo);
+ }
+ else if (type == MPI_LONG_INT) {
+ struct { long a; int b; } foo;
+ disp = (MPI_Aint) ((char *) &foo.b - (char *) &foo.a);
+ *out_size_p = sizeof(foo);
+ }
+ else if (type == MPI_SHORT_INT) {
+ struct { short a; int b; } foo;
+ disp = (MPI_Aint) ((char *) &foo.b - (char *) &foo.a);
+ *out_size_p = sizeof(foo);
+ }
+ else if (type == MPI_LONG_DOUBLE_INT && type != MPI_DATATYPE_NULL) {
+ struct { long double a; int b; } foo;
+ disp = (MPI_Aint) ((char *) &foo.b - (char *) &foo.a);
+ *out_size_p = sizeof(foo);
+ }
+ else {
+ disp = -1;
+ }
+ return disp;
+}
+
+int main(int argc, char *argv[])
+{
+
+struct { MPI_Datatype atype, ptype; char name[32]; }
+pairtypes[] =
+ { {MPI_FLOAT, MPI_FLOAT_INT, "MPI_FLOAT_INT"},
+ {MPI_DOUBLE, MPI_DOUBLE_INT, "MPI_DOUBLE_INT"},
+ {MPI_LONG, MPI_LONG_INT, "MPI_LONG_INT"},
+ {MPI_SHORT, MPI_SHORT_INT, "MPI_SHORT_INT"},
+ {MPI_LONG_DOUBLE, MPI_LONG_DOUBLE_INT, "MPI_LONG_DOUBLE_INT"},
+ {(MPI_Datatype) -1, (MPI_Datatype) -1, "end"}
+ };
+ int errs = 0;
+
+ int i;
+ int blks[2] = {1, 1};
+ MPI_Aint disps[2] = {0, 0};
+ MPI_Datatype types[2] = {MPI_INT, MPI_INT};
+ MPI_Datatype stype;
+
+ MPI_Init(&argc, &argv);
+ parse_args(argc, argv);
+
+ for (i=0; pairtypes[i].atype != (MPI_Datatype) -1; i++) {
+ int atype_size, ptype_size, stype_size, handbuilt_extent=0;
+ MPI_Aint ptype_extent, stype_extent, dummy_lb;
+
+ types[0] = pairtypes[i].atype;
+
+ /* Check for undefined optional types, such as
+ LONG_DOUBLE_INT (if, for example, long double or
+ long long are not supported) */
+ if (types[0] == MPI_DATATYPE_NULL) continue;
+
+ MPI_Type_size(types[0], &atype_size);
+ disps[1] = pairtype_displacement(pairtypes[i].ptype,
+ &handbuilt_extent);
+
+ MPI_Type_create_struct(2, blks, disps, types, &stype);
+
+ MPI_Type_size(stype, &stype_size);
+ MPI_Type_size(pairtypes[i].ptype, &ptype_size);
+ if (stype_size != ptype_size) {
+ errs++;
+
+ if (verbose) fprintf(stderr,
+ "size of %s (%d) does not match size of hand-built MPI struct (%d)\n",
+ pairtypes[i].name, ptype_size, stype_size);
+ }
+
+ MPI_Type_get_extent(stype, &dummy_lb, &stype_extent);
+ MPI_Type_get_extent(pairtypes[i].ptype, &dummy_lb, &ptype_extent);
+ if (stype_extent != ptype_extent || stype_extent != handbuilt_extent) {
+ errs++;
+
+ if (verbose) fprintf(stderr,
+ "extent of %s (%d) does not match extent of either hand-built MPI struct (%d) or equivalent C struct (%d)\n",
+ pairtypes[i].name, (int) stype_extent,
+ (int) ptype_extent,
+ handbuilt_extent);
+ }
+ MPI_Type_free( &stype );
+ }
+
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+int parse_args(int argc, char **argv)
+{
+ /* We use a simple test because getopt isn't universally available */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ if (argc > 1 && strcmp(argv[1], "-nov") == 0)
+ verbose = 0;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+
+/* Tests that commit of a couple of basic types succeeds. */
+
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 0;
+
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int mpi_err, errs = 0;
+ MPI_Datatype type;
+
+ MPI_Init(&argc, &argv);
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ type = MPI_INT;
+ mpi_err = MPI_Type_commit(&type);
+ if (mpi_err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_commit of MPI_INT failed.\n");
+ }
+ errs++;
+ }
+
+ type = MPI_FLOAT_INT;
+ mpi_err = MPI_Type_commit(&type);
+ if (mpi_err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_commit of MPI_FLOAT_INT failed.\n");
+ }
+ errs++;
+ }
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpitest.h"
+
+static int verbose = 0;
+
+/* tests */
+int builtin_float_test(void);
+int vector_of_vectors_test(void);
+int optimizable_vector_of_basics_test(void);
+int struct_of_basics_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MTest_Init(&argc, &argv);
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = builtin_float_test();
+ if (err && verbose) fprintf(stderr, "%d errors in builtin float test.\n",
+ err);
+ errs += err;
+
+ err = vector_of_vectors_test();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in vector of vectors test.\n", err);
+ errs += err;
+
+ err = optimizable_vector_of_basics_test();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in vector of basics test.\n", err);
+ errs += err;
+
+ err = struct_of_basics_test();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in struct of basics test.\n", err);
+ errs += err;
+
+ MTest_Finalize( errs );
+ MPI_Finalize();
+ return 0;
+}
+
+/* builtin_float_test()
+ *
+ * Tests functionality of get_envelope() and get_contents() on a MPI_FLOAT.
+ *
+ * Returns the number of errors encountered.
+ */
+int builtin_float_test(void)
+{
+ int nints, nadds, ntypes, combiner;
+
+ int err, errs = 0;
+
+ err = MPI_Type_get_envelope(MPI_FLOAT,
+ &nints,
+ &nadds,
+ &ntypes,
+ &combiner);
+
+ if (combiner != MPI_COMBINER_NAMED) errs++;
+
+ /* Note: it is erroneous to call MPI_Type_get_contents() on a basic. */
+ return errs;
+}
+
+/* vector_of_vectors_test()
+ *
+ * Builds a vector of a vector of ints. Assuming an int array of size 9
+ * integers, and treating the array as a 3x3 2D array, this will grab the
+ * corners.
+ *
+ * Returns the number of errors encountered.
+ */
+int vector_of_vectors_test(void)
+{
+ MPI_Datatype inner_vector;
+ MPI_Datatype outer_vector;
+ int array[9] = { 1, -1, 2,
+ -2, -3, -4,
+ 3, -5, 4 };
+
+ char *buf;
+ int i, err, errs = 0;
+ MPI_Aint sizeoftype, position;
+
+ /* set up type */
+ err = MPI_Type_vector(2,
+ 1,
+ 2,
+ MPI_INT,
+ &inner_vector);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs;
+ }
+
+ err = MPI_Type_vector(2,
+ 1,
+ 2,
+ inner_vector,
+ &outer_vector);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs;
+ }
+
+ MPI_Type_commit(&outer_vector);
+
+ MPI_Pack_external_size((char*)"external32", 1, outer_vector, &sizeoftype);
+ if (sizeoftype != 4*4) {
+ errs++;
+ if (verbose) fprintf(stderr, "size of type = %d; should be %d\n",
+ (int) sizeoftype, 4*4);
+ return errs;
+ }
+
+ buf = (char *) malloc(sizeoftype);
+
+ position = 0;
+ err = MPI_Pack_external((char*)"external32",
+ array,
+ 1,
+ outer_vector,
+ buf,
+ sizeoftype,
+ &position);
+
+ if (position != sizeoftype) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (pack)\n",
+ (int) position, (int) sizeoftype);
+ }
+
+ memset(array, 0, 9*sizeof(int));
+ position = 0;
+ err = MPI_Unpack_external((char*)"external32",
+ buf,
+ sizeoftype,
+ &position,
+ array,
+ 1,
+ outer_vector);
+
+ if (position != sizeoftype) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (unpack)\n",
+ (int) position, (int) sizeoftype);
+ }
+
+ for (i=0; i < 9; i++) {
+ int goodval;
+ switch (i) {
+ case 0:
+ goodval = 1;
+ break;
+ case 2:
+ goodval = 2;
+ break;
+ case 6:
+ goodval = 3;
+ break;
+ case 8:
+ goodval = 4;
+ break;
+ default:
+ goodval = 0;
+ break;
+ }
+ if (array[i] != goodval) {
+ errs++;
+ if (verbose) fprintf(stderr, "array[%d] = %d; should be %d\n",
+ i, array[i], goodval);
+ }
+ }
+
+ MPI_Type_free(&inner_vector);
+ MPI_Type_free(&outer_vector);
+ return errs;
+}
+
+/* optimizable_vector_of_basics_test()
+ *
+ * Builds a vector of ints. Count is 10, blocksize is 2, stride is 2, so this
+ * is equivalent to a contig of 20.
+ *
+ * Returns the number of errors encountered.
+ */
+int optimizable_vector_of_basics_test(void)
+{
+ MPI_Datatype parent_type;
+ int array[20] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19 };
+ char *buf;
+ int i;
+ MPI_Aint sizeofint, sizeoftype, position;
+
+ int err, errs = 0;
+
+ MPI_Pack_external_size((char*)"external32", 1, MPI_INT, &sizeofint);
+
+ if (sizeofint != 4) {
+ errs++;
+ if (verbose) fprintf(stderr,
+ "size of external32 MPI_INT = %d; should be %d\n",
+ (int) sizeofint, 4);
+ }
+
+ /* set up type */
+ err = MPI_Type_vector(10,
+ 2,
+ 2,
+ MPI_INT,
+ &parent_type);
+
+ MPI_Type_commit(&parent_type);
+
+ MPI_Pack_external_size((char*)"external32", 1, parent_type, &sizeoftype);
+
+
+ if (sizeoftype != 20 * sizeofint) {
+ errs++;
+ if (verbose) fprintf(stderr, "size of vector = %d; should be %d\n",
+ (int) sizeoftype, (int) (20 * sizeofint));
+ }
+
+ buf = (char *) malloc(sizeoftype);
+
+ position = 0;
+ err = MPI_Pack_external((char*)"external32",
+ array,
+ 1,
+ parent_type,
+ buf,
+ sizeoftype,
+ &position);
+
+ if (position != sizeoftype) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (pack)\n",
+ (int) position, (int) sizeoftype);
+ }
+
+ memset(array, 0, 20 * sizeof(int));
+ position = 0;
+ err = MPI_Unpack_external((char*)"external32",
+ buf,
+ sizeoftype,
+ &position,
+ array,
+ 1,
+ parent_type);
+
+ if (position != sizeoftype) {
+ errs++;
+ if (verbose) fprintf(stderr,
+ "position = %ld; should be %ld (unpack)\n",
+ (long) position, (long) sizeoftype);
+ }
+
+ for (i=0; i < 20; i++) {
+ if (array[i] != i) {
+ errs++;
+ if (verbose) fprintf(stderr, "array[%d] = %d; should be %d\n",
+ i, array[i], i);
+ }
+ }
+
+ MPI_Type_free(&parent_type);
+ return errs;
+}
+
+/* struct_of_basics_test()
+ *
+ * Builds a struct of ints. Count is 10, all blocksizes are 2, all
+ * strides are 2*sizeofint, so this is equivalent to a contig of 20.
+ *
+ * Returns the number of errors encountered.
+ */
+int struct_of_basics_test(void)
+{
+ MPI_Datatype parent_type;
+ int array[20] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19 };
+ char *buf;
+ int i;
+ MPI_Aint sizeofint, sizeoftype, position;
+ int blocks[10];
+ MPI_Aint indices[10];
+ MPI_Datatype types[10];
+
+ int err, errs = 0;
+
+ MPI_Pack_external_size((char*)"external32", 1, MPI_INT, &sizeofint);
+
+ if (sizeofint != 4) {
+ errs++;
+ if (verbose) fprintf(stderr,
+ "size of external32 MPI_INT = %d; should be %d\n",
+ (int) sizeofint, 4);
+ }
+
+ for (i = 0; i < 10; i++) {
+ blocks[i] = 2;
+ indices[i] = 2 * i * sizeofint;
+ /* This will cause MPICH to consider this as a blockindex. We
+ * need different types here. */
+ types[i] = MPI_INT;
+ }
+
+ /* set up type */
+ err = MPI_Type_struct(10,
+ blocks,
+ indices,
+ types,
+ &parent_type);
+
+ MPI_Type_commit(&parent_type);
+
+ MPI_Pack_external_size((char*)"external32", 1, parent_type, &sizeoftype);
+
+ if (sizeoftype != 20 * sizeofint) {
+ errs++;
+ if (verbose) fprintf(stderr, "size of vector = %d; should be %d\n",
+ (int) sizeoftype, (int) (20 * sizeofint));
+ }
+
+ buf = (char *) malloc(sizeoftype);
+
+ position = 0;
+ err = MPI_Pack_external((char*)"external32",
+ array,
+ 1,
+ parent_type,
+ buf,
+ sizeoftype,
+ &position);
+
+ if (position != sizeoftype) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (pack)\n",
+ (int) position, (int) sizeoftype);
+ }
+
+ memset(array, 0, 20 * sizeof(int));
+ position = 0;
+ err = MPI_Unpack_external((char*)"external32",
+ buf,
+ sizeoftype,
+ &position,
+ array,
+ 1,
+ parent_type);
+
+ if (position != sizeoftype) {
+ errs++;
+ if (verbose) fprintf(stderr,
+ "position = %ld; should be %ld (unpack)\n",
+ (long) position, (long) sizeoftype);
+ }
+
+ for (i=0; i < 20; i++) {
+ if (array[i] != i) {
+ errs++;
+ if (verbose) fprintf(stderr, "array[%d] = %d; should be %d\n",
+ i, array[i], i);
+ }
+ }
+
+ MPI_Type_free(&parent_type);
+ return errs;
+}
+
+int parse_args(int argc, char **argv)
+{
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 0;
+
+/* tests */
+int builtin_float_test(void);
+int vector_of_vectors_test(void);
+int optimizable_vector_of_basics_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = builtin_float_test();
+ if (err && verbose) fprintf(stderr, "%d errors in builtin float test.\n",
+ err);
+ errs += err;
+
+ err = vector_of_vectors_test();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in vector of vectors test.\n", err);
+ errs += err;
+
+ err = optimizable_vector_of_basics_test();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in vector of basics test.\n", err);
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+/* builtin_float_test()
+ *
+ * Tests functionality of get_envelope() and get_contents() on a MPI_FLOAT.
+ *
+ * Returns the number of errors encountered.
+ */
+int builtin_float_test(void)
+{
+ int nints, nadds, ntypes, combiner;
+
+ int err, errs = 0;
+
+ err = MPI_Type_get_envelope(MPI_FLOAT,
+ &nints,
+ &nadds,
+ &ntypes,
+ &combiner);
+
+ if (combiner != MPI_COMBINER_NAMED) errs++;
+
+ /* Note: it is erroneous to call MPI_Type_get_contents() on a basic. */
+ return errs;
+}
+
+/* vector_of_vectors_test()
+ *
+ * Builds a vector of a vector of ints. Assuming an int array of size 9
+ * integers, and treating the array as a 3x3 2D array, this will grab the
+ * corners.
+ *
+ * Returns the number of errors encountered.
+ */
+int vector_of_vectors_test(void)
+{
+ MPI_Datatype inner_vector;
+ MPI_Datatype outer_vector;
+ int array[9] = { 1, -1, 2,
+ -2, -3, -4,
+ 3, -5, 4 };
+
+ char *buf;
+ int i, err, errs = 0, sizeoftype, position;
+
+ /* set up type */
+ err = MPI_Type_vector(2,
+ 1,
+ 2,
+ MPI_INT,
+ &inner_vector);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs;
+ }
+
+ err = MPI_Type_vector(2,
+ 1,
+ 2,
+ inner_vector,
+ &outer_vector);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) fprintf(stderr,
+ "error in MPI call; aborting after %d errors\n",
+ errs+1);
+ return errs;
+ }
+
+ MPI_Type_commit(&outer_vector);
+ MPI_Type_size(outer_vector, &sizeoftype);
+ if (sizeoftype != 4*sizeof(int)) {
+ errs++;
+ if (verbose) fprintf(stderr, "size of type = %d; should be %d\n",
+ (int) sizeoftype, (int) (4*sizeof(int)));
+ return errs;
+ }
+
+ buf = (char *) malloc(sizeoftype);
+
+ position = 0;
+ err = MPI_Pack(array,
+ 1,
+ outer_vector,
+ buf,
+ sizeoftype,
+ &position,
+ MPI_COMM_WORLD);
+
+ if (position != sizeoftype) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (pack)\n",
+ position, sizeoftype);
+ }
+
+ memset(array, 0, 9*sizeof(int));
+ position = 0;
+ err = MPI_Unpack(buf,
+ sizeoftype,
+ &position,
+ array,
+ 1,
+ outer_vector,
+ MPI_COMM_WORLD);
+
+ if (position != sizeoftype) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (unpack)\n",
+ position, sizeoftype);
+ }
+
+ for (i=0; i < 9; i++) {
+ int goodval;
+ switch (i) {
+ case 0:
+ goodval = 1;
+ break;
+ case 2:
+ goodval = 2;
+ break;
+ case 6:
+ goodval = 3;
+ break;
+ case 8:
+ goodval = 4;
+ break;
+ default:
+ goodval = 0;
+ break;
+ }
+ if (array[i] != goodval) {
+ errs++;
+ if (verbose) fprintf(stderr, "array[%d] = %d; should be %d\n",
+ i, array[i], goodval);
+ }
+ }
+
+ MPI_Type_free(&inner_vector);
+ MPI_Type_free(&outer_vector);
+ return errs;
+}
+
+/* optimizable_vector_of_basics_test()
+ *
+ * Builds a vector of ints. Count is 10, blocksize is 2, stride is 2, so this
+ * is equivalent to a contig of 20.
+ *
+ * Returns the number of errors encountered.
+ */
+int optimizable_vector_of_basics_test(void)
+{
+ MPI_Datatype parent_type;
+ int array[20] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19 };
+ char *buf;
+ int i, sizeofint, sizeoftype, position;
+
+ int err, errs = 0;
+
+ MPI_Type_size(MPI_INT, &sizeofint);
+
+ if (sizeofint != sizeof(int)) {
+ errs++;
+ if (verbose) fprintf(stderr, "size of MPI_Int = %d; should be %d\n",
+ sizeofint, (int) sizeof(int));
+ }
+
+ /* set up type */
+ err = MPI_Type_vector(10,
+ 2,
+ 2,
+ MPI_INT,
+ &parent_type);
+
+ MPI_Type_commit(&parent_type);
+
+ MPI_Type_size(parent_type, &sizeoftype);
+
+ if (sizeoftype != 20 * sizeof(int)) {
+ errs++;
+ if (verbose) fprintf(stderr, "size of vector = %d; should be %d\n",
+ (int) sizeoftype, (int) (20 * sizeof(int)));
+ }
+
+ buf = (char *) malloc(sizeoftype);
+
+ position = 0;
+ err = MPI_Pack(array,
+ 1,
+ parent_type,
+ buf,
+ sizeoftype,
+ &position,
+ MPI_COMM_WORLD);
+
+ if (position != sizeoftype) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (pack)\n",
+ position, sizeoftype);
+ }
+
+ memset(array, 0, 20 * sizeof(int));
+ position = 0;
+ err = MPI_Unpack(buf,
+ sizeoftype,
+ &position,
+ array,
+ 1,
+ parent_type,
+ MPI_COMM_WORLD);
+
+ if (position != sizeoftype) {
+ errs++;
+ if (verbose) fprintf(stderr, "position = %d; should be %d (unpack)\n",
+ position, sizeoftype);
+ }
+
+ for (i=0; i < 20; i++) {
+ if (array[i] != i) {
+ errs++;
+ if (verbose) fprintf(stderr, "array[%d] = %d; should be %d\n",
+ i, array[i], i);
+ }
+ }
+
+ MPI_Type_free(&parent_type);
+ return errs;
+}
+
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 0;
+
+/* tests */
+int derived_resized_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = derived_resized_test();
+ if (err && verbose) fprintf(stderr, "%d errors in derived_resized test.\n",
+ err);
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+/* derived_resized_test()
+ *
+ * Tests behavior with resizing of a simple derived type.
+ *
+ * Returns the number of errors encountered.
+ */
+int derived_resized_test(void)
+{
+ int err, errs = 0;
+
+ int count = 2;
+ MPI_Datatype newtype, resizedtype;
+
+ int size;
+ MPI_Aint extent;
+
+ err = MPI_Type_contiguous(count,
+ MPI_INT,
+ &newtype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating type in derived_resized_test()\n");
+ }
+ errs++;
+ }
+
+ err = MPI_Type_create_resized(newtype,
+ (MPI_Aint) 0,
+ (MPI_Aint) (2*sizeof(int) + 10),
+ &resizedtype);
+
+ err = MPI_Type_size(resizedtype, &size);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type size in derived_resized_test()\n");
+ }
+ errs++;
+ }
+
+ if (size != 2*sizeof(int)) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: size != %d in derived_resized_test()\n", (int) (2*sizeof(int)));
+ }
+ errs++;
+ }
+
+ err = MPI_Type_extent(resizedtype, &extent);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type extent in derived_resized_test()\n");
+ }
+ errs++;
+ }
+
+ if (extent != 2*sizeof(int) + 10) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: invalid extent (%d) in derived_resized_test(); should be %d\n",
+ (int) extent,
+ (int) (2*sizeof(int) + 10));
+ }
+ errs++;
+ }
+
+ MPI_Type_free( &newtype );
+ MPI_Type_free( &resizedtype );
+
+ return errs;
+}
+
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+
+/* Tests that Type_get_extent of a couple of basic types succeeds. */
+
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 0;
+
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int mpi_err, errs = 0, size;
+ MPI_Aint lb, ub, extent;
+ MPI_Datatype type;
+
+ struct { float a; int b; } foo;
+
+ MPI_Init(&argc, &argv);
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ type = MPI_INT;
+ mpi_err = MPI_Type_size(type, &size);
+ if (mpi_err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_size of MPI_INT failed.\n");
+ }
+ errs++;
+ }
+ if (size != sizeof(int)) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_size of MPI_INT incorrect size (%d); should be %d.\n",
+ size, (int) sizeof(int));
+ }
+ errs++;
+ }
+
+ mpi_err = MPI_Type_get_extent(type, &lb, &extent);
+ if (mpi_err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_get_extent of MPI_INT failed.\n");
+ }
+ errs++;
+ }
+ if (extent != sizeof(int)) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_get_extent of MPI_INT returned incorrect extent (%d); should be %d.\n",
+ (int) extent, (int) sizeof(int));
+ }
+ errs++;
+ }
+ if (lb != 0) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_get_extent of MPI_INT returned incorrect lb (%d); should be 0.\n",
+ (int) lb);
+ }
+ errs++;
+ }
+ mpi_err = MPI_Type_ub(type, &ub);
+ if (mpi_err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_ub of MPI_INT failed.\n");
+ }
+ errs++;
+ }
+ if (ub != extent - lb) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_ub of MPI_INT returned incorrect ub (%d); should be %d.\n",
+ (int) ub, (int) (extent - lb));
+ }
+ errs++;
+ }
+
+ type = MPI_FLOAT_INT;
+ mpi_err = MPI_Type_size(type, &size);
+ if (mpi_err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_size of MPI_FLOAT_INT failed.\n");
+ }
+ errs++;
+ }
+ if (size != sizeof(float) + sizeof(int)) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_size of MPI_FLOAT_INT returned incorrect size (%d); should be %d.\n",
+ size, (int) (sizeof(float) + sizeof(int)));
+ }
+ errs++;
+ }
+
+ mpi_err = MPI_Type_get_extent(type, &lb, &extent);
+ if (mpi_err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_get_extent of MPI_FLOAT_INT failed.\n");
+ }
+ errs++;
+ }
+ if (extent != sizeof(foo)) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_get_extent of MPI_FLOAT_INT returned incorrect extent (%d); should be %d.\n",
+ (int) extent, (int) sizeof(foo));
+ }
+ errs++;
+ }
+ if (lb != 0) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_get_extent of MPI_FLOAT_INT returned incorrect lb (%d); should be 0.\n",
+ (int) lb);
+ }
+ errs++;
+ }
+ mpi_err = MPI_Type_ub(type, &ub);
+ if (mpi_err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_ub of MPI_FLOAT_INT failed.\n");
+ }
+ errs++;
+ }
+ if (ub != extent - lb) {
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_ub of MPI_FLOAT_INT returned incorrect ub (%d); should be %d.\n",
+ (int) ub, (int) (extent - lb));
+ }
+ errs++;
+ }
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ *
+ * (C) 2003 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+/*
+static char MTEST_Descrip[] = "Test of the sized types, supported in MPI-2";
+*/
+
+int main( int argc, char *argv[] )
+{
+ int errs = 0;
+ int size;
+
+ MTest_Init( &argc, &argv );
+
+ MPI_Type_size( MPI_REAL4, &size );
+ if (size != 4) {
+ errs ++;
+ printf( "MPI_REAL4 has size %d\n", size );
+ }
+ MPI_Type_size( MPI_REAL8, &size );
+ if (size != 8) {
+ errs ++;
+ printf( "MPI_REAL8 has size %d\n", size );
+ }
+ if (MPI_REAL16 != MPI_DATATYPE_NULL) {
+ MPI_Type_size( MPI_REAL16, &size );
+ if (size != 16) {
+ errs ++;
+ printf( "MPI_REAL16 has size %d\n", size );
+ }
+ }
+
+ MPI_Type_size( MPI_COMPLEX8, &size );
+ if (size != 8) {
+ errs ++;
+ printf( "MPI_COMPLEX8 has size %d\n", size );
+ }
+ MPI_Type_size( MPI_COMPLEX16, &size );
+ if (size != 16) {
+ errs ++;
+ printf( "MPI_COMPLEX16 has size %d\n", size );
+ }
+ if (MPI_COMPLEX32 != MPI_DATATYPE_NULL) {
+ MPI_Type_size( MPI_COMPLEX32, &size );
+ if (size != 32) {
+ errs ++;
+ printf( "MPI_COMPLEX32 has size %d\n", size );
+ }
+ }
+
+ MPI_Type_size( MPI_INTEGER1, &size );
+ if (size != 1) {
+ errs ++;
+ printf( "MPI_INTEGER1 has size %d\n", size );
+ }
+ MPI_Type_size( MPI_INTEGER2, &size );
+ if (size != 2) {
+ errs ++;
+ printf( "MPI_INTEGER2 has size %d\n", size );
+ }
+ MPI_Type_size( MPI_INTEGER4, &size );
+ if (size != 4) {
+ errs ++;
+ printf( "MPI_INTEGER4 has size %d\n", size );
+ }
+ if (MPI_INTEGER8 != MPI_DATATYPE_NULL) {
+ MPI_Type_size( MPI_INTEGER8, &size );
+ if (size != 8) {
+ errs ++;
+ printf( "MPI_INTEGER8 has size %d\n", size );
+ }
+ }
+#ifdef HAVE_MPI_INTEGER16
+ if (MPI_INTEGER16 != MPI_DATATYPE_NULL) {
+ MPI_Type_size( MPI_INTEGER16, &size );
+ if (size != 16) {
+ errs ++;
+ printf( "MPI_INTEGER16 has size %d\n", size );
+ }
+ }
+#endif
+
+ MTest_Finalize( errs );
+ MPI_Finalize();
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "mpi.h"
+
+static int verbose = 0;
+int a[100][100][100], e[9][9][9];
+
+int main(int argc, char *argv[]);
+
+/* helper functions */
+static int parse_args(int argc, char **argv);
+
+int main(int argc, char *argv[])
+{
+ /* Variable declarations */
+ MPI_Datatype oneslice, twoslice, threeslice;
+ int errs = 0;
+ MPI_Aint sizeofint, bufsize, position;
+ void *buffer;
+
+ int i, j, k;
+
+ /* Initialize a to some known values. */
+ for (i = 0; i < 100; i++) {
+ for (j = 0; j < 100; j++) {
+ for (k = 0; k < 100; k++) {
+ a[i][j][k] = i*1000000+j*1000+k;
+ }
+ }
+ }
+
+ /* Initialize MPI */
+ MPI_Init(&argc, &argv);
+ MPI_Type_extent(MPI_INT, &sizeofint);
+
+ parse_args(argc, argv);
+
+ /* Create data types. */
+ /* NOTE: This differs from the way that it's done on the sheet. */
+ /* On the sheet, the slice is a[0, 2, 4, ..., 16][2-10][1-9]. */
+ /* Below, the slice is a[0-8][2-10][1, 3, 5, ..., 17]. */
+ MPI_Type_vector(9, 1, 2, MPI_INT, &oneslice);
+ MPI_Type_hvector(9, 1, 100*sizeofint, oneslice, &twoslice);
+ MPI_Type_hvector(9, 1, 100*100*sizeofint, twoslice, &threeslice);
+
+ MPI_Type_commit(&threeslice);
+
+ /* Pack it into a buffer. */
+ position = 0;
+/* MPI_Pack_size(1, threeslice, MPI_COMM_WORLD, &bufsize); */
+ MPI_Pack_external_size((char*)"external32", 1, threeslice, &bufsize);
+ if (bufsize != 2916)
+ {
+ fprintf(stderr," Error on pack size! Got %d; expecting %d\n", (int) bufsize, 2916);
+ }
+ buffer = (void *) malloc((unsigned) bufsize);
+
+ /* -1 to indices on sheet to compensate for Fortran --> C */
+ MPI_Pack_external((char*)"external32",
+ &(a[0][2][1]),
+ 1, threeslice,
+ buffer,
+ bufsize,
+ &position);
+
+ /* Unpack the buffer into e. */
+ position = 0;
+ MPI_Unpack_external((char*)"external32",
+ buffer,
+ bufsize,
+ &position,
+ e, 9*9*9,
+ MPI_INT);
+
+ /* Display errors, if any. */
+ for (i = 0; i < 9; i++) {
+ for (j = 0; j < 9; j++) {
+ for (k = 0; k < 9; k++) {
+ /* The truncation in integer division makes this safe. */
+ if (e[i][j][k] != a[i][j+2][k*2+1]) {
+ errs++;
+ if (verbose) {
+ printf("Error in location %d x %d x %d: %d, should be %d.\n",
+ i, j, k, e[i][j][k], a[i][j+2][k*2+1]);
+ }
+ }
+ }
+ }
+ }
+
+ /* Release memory. */
+ free(buffer);
+
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+
+ MPI_Type_free(&oneslice);
+ MPI_Type_free(&twoslice);
+ MPI_Type_free(&threeslice);
+
+ MPI_Finalize();
+ return 0;
+}
+
+/* parse_args()
+ */
+static int parse_args(int argc, char **argv)
+{
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include "mpitest.h"
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 0;
+int a[100][100][100], e[9][9][9];
+
+int main(int argc, char *argv[]);
+
+/* helper functions */
+static int parse_args(int argc, char **argv);
+
+int main(int argc, char *argv[])
+{
+ /* Variable declarations */
+ MPI_Datatype oneslice, twoslice, threeslice;
+ int errs = 0;
+ MPI_Aint sizeofint;
+
+ int bufsize, position;
+ void *buffer;
+
+ int i, j, k;
+
+ /* Initialize a to some known values. */
+ for (i = 0; i < 100; i++) {
+ for (j = 0; j < 100; j++) {
+ for (k = 0; k < 100; k++) {
+ a[i][j][k] = i*1000000+j*1000+k;
+ }
+ }
+ }
+
+ /* Initialize MPI */
+ MPI_Init(&argc, &argv);
+ MPI_Type_extent(MPI_INT, &sizeofint);
+
+ parse_args(argc, argv);
+
+ /* Create data types. */
+ /* NOTE: This differs from the way that it's done on the sheet. */
+ /* On the sheet, the slice is a[0, 2, 4, ..., 16][2-10][1-9]. */
+ /* Below, the slice is a[0-8][2-10][1, 3, 5, ..., 17]. */
+ MPI_Type_vector(9, 1, 2, MPI_INT, &oneslice);
+ MPI_Type_hvector(9, 1, 100*sizeofint, oneslice, &twoslice);
+ MPI_Type_hvector(9, 1, 100*100*sizeofint, twoslice, &threeslice);
+
+ MPI_Type_commit(&threeslice);
+
+ /* Pack it into a buffer. */
+ position = 0;
+ MPI_Pack_size(1, threeslice, MPI_COMM_WORLD, &bufsize);
+ buffer = (void *) malloc((unsigned) bufsize);
+
+ /* -1 to indices on sheet to compensate for Fortran --> C */
+ MPI_Pack(&(a[0][2][1]),
+ 1, threeslice,
+ buffer,
+ bufsize,
+ &position,
+ MPI_COMM_WORLD);
+
+ /* Unpack the buffer into e. */
+ position = 0;
+ MPI_Unpack(buffer,
+ bufsize,
+ &position,
+ e, 9*9*9,
+ MPI_INT,
+ MPI_COMM_WORLD);
+
+ /* Display errors, if any. */
+ for (i = 0; i < 9; i++) {
+ for (j = 0; j < 9; j++) {
+ for (k = 0; k < 9; k++) {
+ /* The truncation in integer division makes this safe. */
+ if (e[i][j][k] != a[i][j+2][k*2+1]) {
+ errs++;
+ if (verbose) {
+ printf("Error in location %d x %d x %d: %d, should be %d.\n",
+ i, j, k, e[i][j][k], a[i][j+2][k*2+1]);
+ }
+ }
+ }
+ }
+ }
+
+ /* Release memory. */
+ free(buffer);
+
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+
+ MPI_Type_free(&oneslice);
+ MPI_Type_free(&twoslice);
+ MPI_Type_free(&threeslice);
+
+ MPI_Finalize();
+ return 0;
+}
+
+/* parse_args()
+ */
+static int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+/* Based on code from Jeff Parker at IBM. */
+
+#include <stdio.h>
+
+#include <mpi.h>
+#include "mpitest.h"
+
+int main(int argc, char *argv[])
+{
+ MPI_Datatype mystruct, vecs[3];
+ MPI_Aint stride = 5, displs[3];
+ int i=0, blockcount[3];
+ int errs=0;
+
+ MTest_Init( &argc, &argv );
+
+ for(i = 0; i < 3; i++)
+ {
+ MPI_Type_hvector(i, 1, stride, MPI_INT, &vecs[i]);
+ MPI_Type_commit(&vecs[i]);
+ blockcount[i]=1;
+ }
+ displs[0]=0; displs[1]=-100; displs[2]=-200; /* irrelevant */
+
+ MPI_Type_struct(3, blockcount, displs, vecs, &mystruct);
+ MPI_Type_commit(&mystruct);
+
+ MPI_Type_free(&mystruct);
+ for(i = 0; i < 3; i++)
+ {
+ MPI_Type_free(&vecs[i]);
+ }
+
+ /* this time with the first argument always 0 */
+ for(i = 0; i < 3; i++)
+ {
+ MPI_Type_hvector(0, 1, stride, MPI_INT, &vecs[i]);
+ MPI_Type_commit(&vecs[i]);
+ blockcount[i]=1;
+ }
+ displs[0]=0; displs[1]=-100; displs[2]=-200; /* irrelevant */
+
+ MPI_Type_struct(3, blockcount, displs, vecs, &mystruct);
+ MPI_Type_commit(&mystruct);
+
+ MPI_Type_free(&mystruct);
+ for(i = 0; i < 3; i++)
+ {
+ MPI_Type_free(&vecs[i]);
+ }
+
+ MTest_Finalize( errs );
+ MPI_Finalize();
+
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpi.h"
+
+static int verbose = 0;
+
+int main(int argc, char *argv[]);
+int parse_args(int argc, char **argv);
+int single_struct_test(void);
+
+struct test_struct_1 {
+ int a,b,c,d;
+};
+
+int main(int argc, char *argv[])
+{
+ int err, errs = 0;
+
+ /* Initialize MPI */
+ MPI_Init(&argc, &argv);
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ err = single_struct_test();
+ if (verbose && err) fprintf(stderr, "error in single_struct_test\n");
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+int single_struct_test(void)
+{
+ int err, errs = 0;
+ int count, elements;
+ int sendbuf[6] = { 1, 2, 3, 4, 5, 6 };
+ struct test_struct_1 ts1[2];
+ MPI_Datatype mystruct;
+ MPI_Request request;
+ MPI_Status status;
+
+ /* note: first element of struct has zero blklen and should be dropped */
+ MPI_Aint disps[3] = { 2*sizeof(float), 0, 2*sizeof(int) };
+ int blks[3] = { 0, 1, 2 };
+ MPI_Datatype types[3] = { MPI_FLOAT, MPI_INT, MPI_INT };
+
+ ts1[0].a = -1;
+ ts1[0].b = -1;
+ ts1[0].c = -1;
+ ts1[0].d = -1;
+
+ ts1[1].a = -1;
+ ts1[1].b = -1;
+ ts1[1].c = -1;
+ ts1[1].d = -1;
+
+ err = MPI_Type_struct(3, blks, disps, types, &mystruct);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_struct returned error\n");
+ }
+ }
+
+ MPI_Type_commit(&mystruct);
+
+ err = MPI_Irecv(ts1, 2, mystruct, 0, 0, MPI_COMM_SELF, &request);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Irecv returned error\n");
+ }
+ }
+
+ err = MPI_Send(sendbuf, 6, MPI_INT, 0, 0, MPI_COMM_SELF);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Send returned error\n");
+ }
+ }
+
+ err = MPI_Wait(&request, &status);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Wait returned error\n");
+ }
+ }
+
+ /* verify data */
+ if (ts1[0].a != 1) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts1[0].a = %d; should be %d\n", ts1[0].a, 1);
+ }
+ }
+ if (ts1[0].b != -1) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts1[0].b = %d; should be %d\n", ts1[0].b, -1);
+ }
+ }
+ if (ts1[0].c != 2) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts1[0].c = %d; should be %d\n", ts1[0].c, 2);
+ }
+ }
+ if (ts1[0].d != 3) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts1[0].d = %d; should be %d\n", ts1[0].d, 3);
+ }
+ }
+ if (ts1[1].a != 4) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts1[1].a = %d; should be %d\n", ts1[1].a, 4);
+ }
+ }
+ if (ts1[1].b != -1) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts1[1].b = %d; should be %d\n", ts1[1].b, -1);
+ }
+ }
+ if (ts1[1].c != 5) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts1[1].c = %d; should be %d\n", ts1[1].c, 5);
+ }
+ }
+ if (ts1[1].d != 6) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts1[1].d = %d; should be %d\n", ts1[1].d, 6);
+ }
+ }
+
+ /* verify count and elements */
+ err = MPI_Get_count(&status, mystruct, &count);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Get_count returned error\n");
+ }
+ }
+ if (count != 2) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "count = %d; should be 2\n", count);
+ }
+ }
+
+ err = MPI_Get_elements(&status, mystruct, &elements);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Get_elements returned error\n");
+ }
+ }
+ if (elements != 6) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "elements = %d; should be 6\n", elements);
+ }
+ }
+
+ MPI_Type_free(&mystruct);
+
+ return errs;
+}
+
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2008 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi.h"
+#include <string.h>
+
+#define COUNT 14
+#define SIZE 340
+#define EL_COUNT 1131
+
+char s_buf[EL_COUNT*SIZE];
+char r_buf[EL_COUNT*SIZE];
+
+int main( int argc, char **argv )
+{
+ int rank, size, ret;
+ MPI_Status Status;
+ MPI_Request request;
+ MPI_Datatype struct_type, type1[COUNT];
+ MPI_Aint disp1[COUNT] = {0, 0, 332, 340};
+ int block1[COUNT] = {1, 56, 2, 1};
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+ type1[0] = MPI_LB;
+ type1[1] = MPI_FLOAT;
+ type1[2] = MPI_FLOAT;
+ type1[3] = MPI_UB;
+
+ MPI_Type_struct(4, block1, disp1, type1, &struct_type);
+
+ ret = MPI_Type_commit(&struct_type);
+ if (ret != MPI_SUCCESS)
+ {
+ fprintf(stderr, "Could not make struct type."), fflush(stderr);
+ MPI_Abort( MPI_COMM_WORLD, 1 );
+ }
+
+ memset(s_buf, 0, EL_COUNT*SIZE);
+ memset(r_buf, 0, EL_COUNT*SIZE);
+
+ MPI_Isend(s_buf, EL_COUNT, struct_type, 0, 4, MPI_COMM_WORLD, &request);
+ MPI_Recv(r_buf, EL_COUNT, struct_type, 0, 4, MPI_COMM_WORLD, &Status );
+ MPI_Wait(&request, &Status);
+
+ MPI_Type_free(&struct_type);
+
+ MPI_Finalize();
+
+ printf(" No Errors\n");
+
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+/*
+ The default behavior of the test routines should be to briefly indicate
+ the cause of any errors - in this test, that means that verbose needs
+ to be set. Verbose should turn on output that is independent of error
+ levels.
+*/
+static int verbose = 1;
+
+/* tests */
+int no_real_types_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MTest_Init(&argc, &argv);
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = no_real_types_test();
+ if (err && verbose) fprintf(stderr, "%d errors in blockindexed test.\n",
+ err);
+ errs += err;
+
+ MTest_Finalize( errs );
+ MPI_Finalize();
+ return 0;
+}
+
+/* no_real_types_test()
+ *
+ * Tests behavior with an empty struct type
+ *
+ * Returns the number of errors encountered.
+ */
+int no_real_types_test(void)
+{
+ int err, errs = 0;
+
+ int count = 1;
+ int len = 1;
+ MPI_Aint disp = 10;
+ MPI_Datatype type = MPI_LB;
+ MPI_Datatype newtype;
+
+ int size;
+ MPI_Aint extent;
+
+ err = MPI_Type_create_struct(count,
+ &len,
+ &disp,
+ &type,
+ &newtype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating struct type no_real_types_test()\n");
+ }
+ MTestPrintError( err );
+ errs++;
+ }
+
+ err = MPI_Type_size(newtype, &size);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type size in no_real_types_test()\n");
+ }
+ MTestPrintError( err );
+ errs++;
+ }
+
+ if (size != 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: size != 0 in no_real_types_test()\n");
+ }
+ errs++;
+ }
+
+ err = MPI_Type_extent(newtype, &extent);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type extent in no_real_types_test()\n");
+ }
+ MTestPrintError( err );
+ errs++;
+ }
+
+ if (extent != -10) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: extent is %ld but should be -10 in no_real_types_test()\n",
+ (long) extent );
+ fprintf( stderr,
+ "type map is { (LB,10) }, so UB is 0 and extent is ub-lb\n" );
+ }
+ errs++;
+ }
+
+ MPI_Type_free( &newtype );
+
+ return errs;
+}
+
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpi.h"
+
+static int verbose = 0;
+
+int main(int argc, char *argv[]);
+int parse_args(int argc, char **argv);
+int single_struct_test(void);
+int array_of_structs_test(void);
+int struct_of_structs_test(void);
+
+struct test_struct_1 {
+ int a,b;
+ char c,d;
+ int e;
+};
+
+int main(int argc, char *argv[])
+{
+ int err, errs = 0;
+
+ /* Initialize MPI */
+ MPI_Init(&argc, &argv);
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ err = single_struct_test();
+ if (verbose && err) fprintf(stderr, "error in single_struct_test\n");
+ errs += err;
+
+ err = array_of_structs_test();
+ if (verbose && err) fprintf(stderr, "error in array_of_structs_test\n");
+ errs += err;
+
+ err = struct_of_structs_test();
+ if (verbose && err) fprintf(stderr, "error in struct_of_structs_test\n");
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+int single_struct_test(void)
+{
+ int err, errs = 0;
+ int bufsize, position = 0;
+ struct test_struct_1 ts1, ts2;
+ MPI_Datatype mystruct;
+ char *buffer;
+
+ MPI_Aint disps[3] = {0, 2*sizeof(int), 3*sizeof(int)}; /* guessing... */
+ int blks[3] = { 2, 2, 1 };
+ MPI_Datatype types[3] = { MPI_INT, MPI_CHAR, MPI_INT };
+
+ ts1.a = 1;
+ ts1.b = 2;
+ ts1.c = 3;
+ ts1.d = 4;
+ ts1.e = 5;
+
+ err = MPI_Type_struct(3, blks, disps, types, &mystruct);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_struct returned error\n");
+ }
+ }
+
+ MPI_Type_commit(&mystruct);
+
+ MPI_Pack_size(1, mystruct, MPI_COMM_WORLD, &bufsize);
+ buffer = (char *) malloc(bufsize);
+
+ err = MPI_Pack(&ts1,
+ 1,
+ mystruct,
+ buffer,
+ bufsize,
+ &position,
+ MPI_COMM_WORLD);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Pack returned error\n");
+ }
+ }
+
+ position = 0;
+ err = MPI_Unpack(buffer,
+ bufsize,
+ &position,
+ &ts2,
+ 1,
+ mystruct,
+ MPI_COMM_WORLD);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Unpack returned error\n");
+ }
+ }
+
+ MPI_Type_free(&mystruct);
+ free(buffer);
+
+ if (ts1.a != ts2.a) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts2.a = %d; should be %d\n", ts2.a, ts1.a);
+ }
+ }
+ if (ts1.b != ts2.b) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts2.b = %d; should be %d\n", ts2.b, ts1.b);
+ }
+ }
+ if (ts1.c != ts2.c) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts2.c = %d; should be %d\n",
+ (int) ts2.c, (int) ts1.c);
+ }
+ }
+ if (ts1.d != ts2.d) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts2.d = %d; should be %d\n",
+ (int) ts2.d, (int) ts1.d);
+ }
+ }
+ if (ts1.e != ts2.e) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts2.e = %d; should be %d\n", ts2.e, ts1.e);
+ }
+ }
+
+ return errs;
+}
+
+int array_of_structs_test(void)
+{
+ int i, err, errs = 0;
+ int bufsize, position = 0;
+ struct test_struct_1 ts1[10], ts2[10];
+ MPI_Datatype mystruct;
+ char *buffer;
+
+ MPI_Aint disps[3] = {0, 2*sizeof(int), 3*sizeof(int)}; /* guessing... */
+ int blks[3] = { 2, 2, 1 };
+ MPI_Datatype types[3] = { MPI_INT, MPI_CHAR, MPI_INT };
+
+ for (i=0; i < 10; i++) {
+ ts1[i].a = 10*i + 1;
+ ts1[i].b = 10*i + 2;
+ ts1[i].c = 10*i + 3;
+ ts1[i].d = 10*i + 4;
+ ts1[i].e = 10*i + 5;
+
+ ts2[i].a = -13;
+ ts2[i].b = -13;
+ ts2[i].c = -13;
+ ts2[i].d = -13;
+ ts2[i].e = -13;
+ }
+
+ err = MPI_Type_struct(3, blks, disps, types, &mystruct);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Type_struct returned error\n");
+ }
+ }
+
+ MPI_Type_commit(&mystruct);
+
+ MPI_Pack_size(10, mystruct, MPI_COMM_WORLD, &bufsize);
+ buffer = (char *) malloc(bufsize);
+
+ err = MPI_Pack(ts1,
+ 10,
+ mystruct,
+ buffer,
+ bufsize,
+ &position,
+ MPI_COMM_WORLD);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Pack returned error\n");
+ }
+ }
+
+ position = 0;
+ err = MPI_Unpack(buffer,
+ bufsize,
+ &position,
+ ts2,
+ 10,
+ mystruct,
+ MPI_COMM_WORLD);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "MPI_Unpack returned error\n");
+ }
+ }
+
+ MPI_Type_free(&mystruct);
+ free(buffer);
+
+ for (i=0; i < 10; i++) {
+ if (ts1[i].a != ts2[i].a) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts2[%d].a = %d; should be %d\n",
+ i, ts2[i].a, ts1[i].a);
+ }
+ }
+ if (ts1[i].b != ts2[i].b) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts2[%d].b = %d; should be %d\n",
+ i, ts2[i].b, ts1[i].b);
+ }
+ }
+ if (ts1[i].c != ts2[i].c) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts2[%d].c = %d; should be %d\n",
+ i, (int) ts2[i].c, (int) ts1[i].c);
+ }
+ }
+ if (ts1[i].d != ts2[i].d) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts2[%d].d = %d; should be %d\n",
+ i, (int) ts2[i].d, (int) ts1[i].d);
+ }
+ }
+ if (ts1[i].e != ts2[i].e) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "ts2[%d].e = %d; should be %d\n",
+ i, ts2[i].e, ts1[i].e);
+ }
+ }
+ }
+
+ return errs;
+}
+
+int struct_of_structs_test(void)
+{
+ int i, j, err, errs = 0, bufsize, position;
+
+ char buf[50], buf2[50], *packbuf;
+
+ MPI_Aint disps[3] = {0, 3, 0};
+ int blks[3] = {2, 1, 0};
+ MPI_Datatype types[3], chartype, tiletype1, tiletype2, finaltype;
+
+ /* build a contig of one char to try to keep optimizations
+ * from being applied.
+ */
+ err = MPI_Type_contiguous(1, MPI_CHAR, &chartype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "chartype create failed\n");
+ }
+ return errs;
+ }
+
+ /* build a type that we can tile a few times */
+ types[0] = MPI_CHAR;
+ types[1] = chartype;
+
+ err = MPI_Type_struct(2, blks, disps, types, &tiletype1);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "tiletype1 create failed\n");
+ }
+ return errs;
+ }
+
+ /* build the same type again, again to avoid optimizations */
+ err = MPI_Type_struct(2, blks, disps, types, &tiletype2);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "tiletype2 create failed\n");
+ }
+ return errs;
+ }
+
+ /* build a combination of those two tiletypes */
+ disps[0] = 0;
+ disps[1] = 5;
+ disps[2] = 10;
+ blks[0] = 1;
+ blks[1] = 1;
+ blks[2] = 1;
+ types[0] = tiletype1;
+ types[1] = tiletype2;
+ types[2] = MPI_UB;
+ err = MPI_Type_struct(3, blks, disps, types, &finaltype);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "finaltype create failed\n");
+ }
+ return errs;
+ }
+
+ MPI_Type_commit(&finaltype);
+ MPI_Type_free(&chartype);
+ MPI_Type_free(&tiletype1);
+ MPI_Type_free(&tiletype2);
+
+ MPI_Pack_size(5, finaltype, MPI_COMM_WORLD, &bufsize);
+
+ packbuf = malloc(bufsize);
+ if (packbuf == NULL) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "pack buffer allocation (%d bytes) failed\n", bufsize);
+ }
+ return errs;
+ }
+
+ for (j=0; j < 10; j++) {
+ for (i=0; i < 5; i++) {
+ if (i == 2 || i == 4) buf[5*j + i] = 0;
+ else buf[5*j + i] = i;
+ }
+ }
+
+ position = 0;
+ err = MPI_Pack(buf, 5, finaltype, packbuf, bufsize, &position, MPI_COMM_WORLD);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "pack failed\n");
+ }
+ return errs;
+ }
+
+ memset(buf2, 0, 50);
+ position = 0;
+ err = MPI_Unpack(packbuf, bufsize, &position, buf2, 5, finaltype, MPI_COMM_WORLD);
+ if (err != MPI_SUCCESS) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr, "unpack failed\n");
+ }
+ return errs;
+ }
+
+ for (j=0; j < 10; j++) {
+ for (i=0; i < 5; i++) {
+ if (buf[5*j + i] != buf2[5*j + i]) {
+ errs++;
+ if (verbose) {
+ fprintf(stderr,
+ "buf2[%d] = %d; should be %d\n",
+ 5*j + i,
+ (int) buf2[5*j+i],
+ (int) buf[5*j+i]);
+ }
+ }
+ }
+ }
+
+ free(packbuf);
+ MPI_Type_free(&finaltype);
+ return errs;
+}
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2009 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+/* Regression test for MPICH trac ticket #972, originally written by
+ * Rob Latham <robl@mcs.anl.gov> as a simplification of a type
+ * encountered by the HDF5 library.
+ *
+ * Should be run with 1 process. */
+
+#include <stdio.h>
+#include "mpi.h"
+
+/* uncomment to use debugging routine in MPICH
+extern int MPIDU_Datatype_debug(MPI_Datatype type, int depth);
+*/
+
+int makeHDF5type0(MPI_Datatype *type);
+int makeHDF5type0(MPI_Datatype *type)
+{
+ MPI_Datatype ctg, vect, structype, vec2, structype2,
+ vec3, structype3, vec4, structype4, vec5;
+
+ int b[3];
+ MPI_Aint d[3];
+ MPI_Datatype t[3];
+
+ MPI_Type_contiguous(4, MPI_BYTE, &ctg);
+
+ MPI_Type_vector(1, 5, 1, ctg, &vect);
+
+ b[0] = b[1] = b[2] = 1;
+ d[0] = 0; d[1] = 0; d[2] = 40;
+ t[0] = MPI_LB; t[1] = vect; t[2] = MPI_UB;
+ MPI_Type_create_struct(3, b, d, t, &structype);
+
+ MPI_Type_vector(1, 5, 1, structype, &vec2);
+
+ b[0] = b[1] = b[2] = 1;
+ d[0] = 0; d[1] = 2000; d[2] = 400;
+ t[0] = MPI_LB; t[1] = vec2; t[2] = MPI_UB;
+ MPI_Type_create_struct(3, b, d, t, &structype2);
+
+ MPI_Type_vector(1, 5, 1, structype2, &vec3);
+
+ b[0] = b[1] = b[2] = 1;
+ d[0] = 0; d[1] = 0; d[2] = 4000;
+ t[0] = MPI_LB; t[1] = vec3; t[2] = MPI_UB;
+ MPI_Type_create_struct(3, b, d, t, &structype3);
+
+ MPI_Type_vector(1, 5, 1, structype3, &vec4);
+
+ b[0] = b[1] = b[2] = 1;
+ d[0] = 0; d[1] = 0; d[2] = 40000;
+ t[0] = MPI_LB; t[1] = vec4; t[2] = MPI_UB;
+ MPI_Type_create_struct(3, b, d, t, &structype4);
+
+ MPI_Type_vector(1, 1, 1, structype4, &vec5);
+
+ b[0] = b[1] = b[2] = 1;
+ d[0] = 0; d[1] = 160000; d[2] = 200000;
+ t[0] = MPI_LB; t[1] = vec5; t[2] = MPI_UB;
+ MPI_Type_create_struct(3, b, d, t, type);
+
+ MPI_Type_free(&ctg);
+ MPI_Type_free(&vect);
+ MPI_Type_free(&structype);
+ MPI_Type_free(&vec2);
+ MPI_Type_free(&structype2);
+ MPI_Type_free(&vec3);
+ MPI_Type_free(&structype3);
+ MPI_Type_free(&vec4);
+ MPI_Type_free(&structype4);
+ MPI_Type_free(&vec5);
+ MPI_Type_commit(type);
+
+ return 0;
+}
+
+int makeHDF5type1(MPI_Datatype *type);
+int makeHDF5type1(MPI_Datatype *type)
+{
+ MPI_Datatype ctg, vect, structype, vec2, structype2,
+ vec3, structype3, vec4, structype4, vec5;
+
+ int b[3];
+ MPI_Aint d[3];
+ MPI_Datatype t[3];
+
+ MPI_Type_contiguous(4, MPI_BYTE, &ctg);
+
+ MPI_Type_vector(1, 5, 1, ctg, &vect);
+
+ b[0] = b[1] = b[2] = 1;
+ d[0] = 0; d[1] = 20; d[2] = 40;
+ t[0] = MPI_LB; t[1] = vect; t[2] = MPI_UB;
+ MPI_Type_create_struct(3, b, d, t, &structype);
+
+ MPI_Type_vector(1, 5, 1, structype, &vec2);
+
+ b[0] = b[1] = b[2] = 1;
+ d[0] = 0; d[1] = 0; d[2] = 400;
+ t[0] = MPI_LB; t[1] = vec2; t[2] = MPI_UB;
+ MPI_Type_create_struct(3, b, d, t, &structype2);
+
+ MPI_Type_vector(1, 5, 1, structype2, &vec3);
+
+ b[0] = b[1] = b[2] = 1;
+ d[0] = 0; d[1] = 0; d[2] = 4000;
+ t[0] = MPI_LB; t[1] = vec3; t[2] = MPI_UB;
+ MPI_Type_create_struct(3, b, d, t, &structype3);
+
+ MPI_Type_vector(1, 5, 1, structype3, &vec4);
+
+ b[0] = b[1] = b[2] = 1;
+ d[0] = 0; d[1] = 0; d[2] = 40000;
+ t[0] = MPI_LB; t[1] = vec4; t[2] = MPI_UB;
+ MPI_Type_create_struct(3, b, d, t, &structype4);
+
+ MPI_Type_vector(1, 1, 1, structype4, &vec5);
+
+ b[0] = b[1] = b[2] = 1;
+ d[0] = 0; d[1] = 160000; d[2] = 200000;
+ t[0] = MPI_LB; t[1] = vec5; t[2] = MPI_UB;
+ MPI_Type_create_struct(3, b, d, t, type);
+
+ MPI_Type_free(&ctg);
+ MPI_Type_free(&vect);
+ MPI_Type_free(&structype);
+ MPI_Type_free(&vec2);
+ MPI_Type_free(&structype2);
+ MPI_Type_free(&vec3);
+ MPI_Type_free(&structype3);
+ MPI_Type_free(&vec4);
+ MPI_Type_free(&structype4);
+ MPI_Type_free(&vec5);
+ MPI_Type_commit(type);
+
+ return 0;
+}
+
+int makeHDF5type(MPI_Datatype *type);
+int makeHDF5type(MPI_Datatype *type)
+{
+ int i;
+
+#define NTYPES 2
+
+ int blocklens[NTYPES];
+ MPI_Aint disps[NTYPES];
+
+ MPI_Datatype types[NTYPES];
+ makeHDF5type0(&(types[0]));
+ makeHDF5type1(&(types[1]));
+
+ for (i=0; i< NTYPES; i++) {
+ blocklens[i] = 1;
+ disps[i] = 0;
+ }
+
+ MPI_Type_create_struct(NTYPES, blocklens, disps, types, type);
+ MPI_Type_commit(type);
+
+ for(i=0; i<NTYPES; i++) {
+ MPI_Type_free(&(types[i]));
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ MPI_Datatype hdf5type;
+
+ MPI_Init(&argc, &argv);
+ makeHDF5type(&hdf5type);
+
+ /*MPIDU_Datatype_debug(hdf5type, 32);*/
+
+ MPI_Type_free(&hdf5type);
+ MPI_Finalize();
+
+ printf(" No Errors\n");
+
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+static int verbose = 0;
+
+/* tests */
+int builtin_struct_test(void);
+
+/* helper functions */
+int parse_args(int argc, char **argv);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = builtin_struct_test();
+ if (err && verbose) fprintf(stderr, "%d errors in builtin struct test.\n", err);
+ errs += err;
+
+ /* print message and exit */
+ if (errs) {
+ fprintf(stderr, "Found %d errors\n", errs);
+ }
+ else {
+ printf(" No Errors\n");
+ }
+ MPI_Finalize();
+ return 0;
+}
+
+/* builtin_struct_test()
+ *
+ * Tests behavior with a zero-count struct of builtins.
+ *
+ * Returns the number of errors encountered.
+ */
+int builtin_struct_test(void)
+{
+ int err, errs = 0;
+
+ int count = 0;
+ MPI_Datatype newtype;
+
+ int size;
+ MPI_Aint extent;
+
+ err = MPI_Type_create_struct(count,
+ (int *) 0,
+ (MPI_Aint *) 0,
+ (MPI_Datatype *) 0,
+ &newtype);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error creating struct type in builtin_struct_test()\n");
+ }
+ errs++;
+ }
+
+ err = MPI_Type_size(newtype, &size);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type size in builtin_struct_test()\n");
+ }
+ errs++;
+ }
+
+ if (size != 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: size != 0 in builtin_struct_test()\n");
+ }
+ errs++;
+ }
+
+ err = MPI_Type_extent(newtype, &extent);
+ if (err != MPI_SUCCESS) {
+ if (verbose) {
+ fprintf(stderr,
+ "error obtaining type extent in builtin_struct_test()\n");
+ }
+ errs++;
+ }
+
+ if (extent != 0) {
+ if (verbose) {
+ fprintf(stderr,
+ "error: extent != 0 in builtin_struct_test()\n");
+ }
+ errs++;
+ }
+
+ MPI_Type_free( &newtype );
+
+ return errs;
+}
+
+
+int parse_args(int argc, char **argv)
+{
+ /*
+ int ret;
+
+ while ((ret = getopt(argc, argv, "v")) >= 0)
+ {
+ switch (ret) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+ */
+ if (argc > 1 && strcmp(argv[1], "-v") == 0)
+ verbose = 1;
+ return 0;
+}
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int verbose = 0;
+
+/* tests */
+int subarray_1d_c_test1(void);
+int subarray_1d_fortran_test1(void);
+int subarray_2d_c_test1(void);
+int subarray_4d_c_test1(void);
+int subarray_2d_c_test2(void);
+int subarray_2d_fortran_test1(void);
+int subarray_4d_fortran_test1(void);
+
+/* helper functions */
+static int parse_args(int argc, char **argv);
+static int pack_and_unpack(char *typebuf,
+ int count,
+ MPI_Datatype datatype,
+ int typebufsz);
+
+int main(int argc, char **argv)
+{
+ int err, errs = 0;
+
+ MPI_Init(&argc, &argv); /* MPI-1.2 doesn't allow for MPI_Init(0,0) */
+ parse_args(argc, argv);
+
+ /* To improve reporting of problems about operations, we
+ change the error handler to errors return */
+ MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
+
+ /* perform some tests */
+ err = subarray_1d_c_test1();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in 1d subarray c test 1.\n", err);
+ errs += err;
+
+ err = subarray_1d_fortran_test1();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in 1d subarray fortran test 1.\n",
+ err);
+ errs += err;
+
+ err = subarray_2d_c_test1();
+ if (err && verbose) fprintf(stderr,
+ "%d errors in 2d subarray c test 1.\n", err);
+ errs += err;
+