From de88ba6429025fa6d048915b20148bc7a301f07f Mon Sep 17 00:00:00 2001 From: Augustin Degomme Date: Tue, 10 Dec 2019 17:01:35 +0100 Subject: [PATCH] Add io test in mpich testsuite. Works, but as files are simulated, content-checking after a read has to be disabled. Also files have to be opened with an absolute path for now. --- teshsuite/smpi/hostfile_io | 2 + teshsuite/smpi/io-all-at/io-all-at.tesh | 3 +- teshsuite/smpi/io-all/io-all.tesh | 3 +- teshsuite/smpi/io-ordered/io-ordered.tesh | 3 +- teshsuite/smpi/io-shared/io-shared.tesh | 3 +- teshsuite/smpi/io-simple-at/io-simple-at.tesh | 3 +- teshsuite/smpi/io-simple/io-simple.tesh | 3 +- teshsuite/smpi/mpich3-test/io/CMakeLists.txt | 30 + teshsuite/smpi/mpich3-test/io/async.c | 174 ++++++ teshsuite/smpi/mpich3-test/io/async_any.c | 118 ++++ teshsuite/smpi/mpich3-test/io/bigtype.c | 142 +++++ .../mpich3-test/io/external32-derived-dtype.c | 106 ++++ teshsuite/smpi/mpich3-test/io/getextent.c | 40 ++ teshsuite/smpi/mpich3-test/io/hindexed_io.c | 106 ++++ .../smpi/mpich3-test/io/i_aggregation1.c | 309 ++++++++++ .../smpi/mpich3-test/io/i_aggregation2.c | 99 ++++ teshsuite/smpi/mpich3-test/io/i_bigtype.c | 147 +++++ teshsuite/smpi/mpich3-test/io/i_coll_test.c | 207 +++++++ teshsuite/smpi/mpich3-test/io/i_darray_read.c | 134 +++++ teshsuite/smpi/mpich3-test/io/i_hindexed.c | 274 +++++++++ teshsuite/smpi/mpich3-test/io/i_hindexed_io.c | 111 ++++ teshsuite/smpi/mpich3-test/io/i_noncontig.c | 246 ++++++++ .../smpi/mpich3-test/io/i_noncontig_coll.c | 232 ++++++++ .../smpi/mpich3-test/io/i_noncontig_coll2.c | 558 ++++++++++++++++++ teshsuite/smpi/mpich3-test/io/i_rdwrord.c | 73 +++ teshsuite/smpi/mpich3-test/io/i_setviewcur.c | 128 ++++ .../smpi/mpich3-test/io/i_types_with_zeros.c | 167 ++++++ teshsuite/smpi/mpich3-test/io/rdwrord.c | 68 +++ teshsuite/smpi/mpich3-test/io/rdwrzero.c | 121 ++++ teshsuite/smpi/mpich3-test/io/resized.c | 134 +++++ teshsuite/smpi/mpich3-test/io/resized2.c | 137 +++++ teshsuite/smpi/mpich3-test/io/setinfo.c | 122 ++++ teshsuite/smpi/mpich3-test/io/setviewcur.c | 122 ++++ .../smpi/mpich3-test/io/simple_collective.c | 165 ++++++ teshsuite/smpi/mpich3-test/io/testlist | 29 + teshsuite/smpi/mpich3-test/io/userioerr.c | 85 +++ teshsuite/smpi/mpich3-test/runtests | 6 +- tools/cmake/DefinePackages.cmake | 1 + 38 files changed, 4398 insertions(+), 13 deletions(-) create mode 100644 teshsuite/smpi/mpich3-test/io/CMakeLists.txt create mode 100644 teshsuite/smpi/mpich3-test/io/async.c create mode 100644 teshsuite/smpi/mpich3-test/io/async_any.c create mode 100644 teshsuite/smpi/mpich3-test/io/bigtype.c create mode 100644 teshsuite/smpi/mpich3-test/io/external32-derived-dtype.c create mode 100644 teshsuite/smpi/mpich3-test/io/getextent.c create mode 100644 teshsuite/smpi/mpich3-test/io/hindexed_io.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_aggregation1.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_aggregation2.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_bigtype.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_coll_test.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_darray_read.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_hindexed.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_hindexed_io.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_noncontig.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_noncontig_coll.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_noncontig_coll2.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_rdwrord.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_setviewcur.c create mode 100644 teshsuite/smpi/mpich3-test/io/i_types_with_zeros.c create mode 100644 teshsuite/smpi/mpich3-test/io/rdwrord.c create mode 100644 teshsuite/smpi/mpich3-test/io/rdwrzero.c create mode 100644 teshsuite/smpi/mpich3-test/io/resized.c create mode 100644 teshsuite/smpi/mpich3-test/io/resized2.c create mode 100644 teshsuite/smpi/mpich3-test/io/setinfo.c create mode 100644 teshsuite/smpi/mpich3-test/io/setviewcur.c create mode 100644 teshsuite/smpi/mpich3-test/io/simple_collective.c create mode 100644 teshsuite/smpi/mpich3-test/io/testlist create mode 100644 teshsuite/smpi/mpich3-test/io/userioerr.c diff --git a/teshsuite/smpi/hostfile_io b/teshsuite/smpi/hostfile_io index 6b4158a214..1b983fe893 100644 --- a/teshsuite/smpi/hostfile_io +++ b/teshsuite/smpi/hostfile_io @@ -1,2 +1,4 @@ bob carl +bob +carl diff --git a/teshsuite/smpi/io-all-at/io-all-at.tesh b/teshsuite/smpi/io-all-at/io-all-at.tesh index bda0cafc8f..12bb588120 100644 --- a/teshsuite/smpi/io-all-at/io-all-at.tesh +++ b/teshsuite/smpi/io-all-at/io-all-at.tesh @@ -1,7 +1,6 @@ # Test for MPI_File_read and MPI_File_write ! output sort -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-all-at -> You requested to use 4 ranks, but there is only 2 processes in your hostfile... +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=s4u_file.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-all-at > [rank 0] -> bob > [rank 1] -> carl > [rank 2] -> bob diff --git a/teshsuite/smpi/io-all/io-all.tesh b/teshsuite/smpi/io-all/io-all.tesh index 0c96e62f6a..ffc8aebd05 100644 --- a/teshsuite/smpi/io-all/io-all.tesh +++ b/teshsuite/smpi/io-all/io-all.tesh @@ -1,7 +1,6 @@ # Test for MPI_File_read and MPI_File_write ! output sort -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-all -> You requested to use 4 ranks, but there is only 2 processes in your hostfile... +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=s4u_file.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-all > [rank 0] -> bob > [rank 1] -> carl > [rank 2] -> bob diff --git a/teshsuite/smpi/io-ordered/io-ordered.tesh b/teshsuite/smpi/io-ordered/io-ordered.tesh index e7d779cd3f..6a7082d1e2 100644 --- a/teshsuite/smpi/io-ordered/io-ordered.tesh +++ b/teshsuite/smpi/io-ordered/io-ordered.tesh @@ -1,7 +1,6 @@ # Test for MPI_File_read and MPI_File_write ! output sort -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-ordered -> You requested to use 4 ranks, but there is only 2 processes in your hostfile... +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=s4u_file.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-ordered > [rank 0] -> bob > [rank 1] -> carl > [rank 2] -> bob diff --git a/teshsuite/smpi/io-shared/io-shared.tesh b/teshsuite/smpi/io-shared/io-shared.tesh index e5a56ddba0..ad8c201039 100644 --- a/teshsuite/smpi/io-shared/io-shared.tesh +++ b/teshsuite/smpi/io-shared/io-shared.tesh @@ -1,7 +1,6 @@ # Test for MPI_File_read and MPI_File_write ! output sort -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-shared -> You requested to use 4 ranks, but there is only 2 processes in your hostfile... +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=s4u_file.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-shared > [rank 0] -> bob > [rank 1] -> carl > [rank 2] -> bob diff --git a/teshsuite/smpi/io-simple-at/io-simple-at.tesh b/teshsuite/smpi/io-simple-at/io-simple-at.tesh index 16f351efe6..8bb5d72e41 100644 --- a/teshsuite/smpi/io-simple-at/io-simple-at.tesh +++ b/teshsuite/smpi/io-simple-at/io-simple-at.tesh @@ -1,7 +1,6 @@ # Test for MPI_File_read and MPI_File_write ! output sort -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-simple-at -> You requested to use 4 ranks, but there is only 2 processes in your hostfile... +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=s4u_file.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-simple-at > [rank 0] -> bob > [rank 1] -> carl > [rank 2] -> bob diff --git a/teshsuite/smpi/io-simple/io-simple.tesh b/teshsuite/smpi/io-simple/io-simple.tesh index b1739bb4b6..59c3f51fe5 100644 --- a/teshsuite/smpi/io-simple/io-simple.tesh +++ b/teshsuite/smpi/io-simple/io-simple.tesh @@ -1,7 +1,6 @@ # Test for MPI_File_read and MPI_File_write ! output sort -$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-simple -> You requested to use 4 ranks, but there is only 2 processes in your hostfile... +$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_config.thres:warning --log=smpi_mpi.thres:error --log=s4u_file.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-simple > [rank 0] -> bob > [rank 1] -> carl > [rank 2] -> bob diff --git a/teshsuite/smpi/mpich3-test/io/CMakeLists.txt b/teshsuite/smpi/mpich3-test/io/CMakeLists.txt new file mode 100644 index 0000000000..23a5a2af34 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/CMakeLists.txt @@ -0,0 +1,30 @@ +if(enable_smpi AND enable_smpi_MPICH3_testsuite) + 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() + + include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi") + include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/") + + foreach(file async_any async bigtype external32-derived-dtype getextent hindexed_io i_aggregation1 i_aggregation2 i_bigtype i_coll_test i_darray_read i_hindexed i_hindexed_io i_noncontig i_noncontig_coll2 i_noncontig_coll i_rdwrord i_setviewcur i_types_with_zeros rdwrord rdwrzero resized2 resized setinfo setviewcur simple_collective userioerr) + add_executable(${file} EXCLUDE_FROM_ALL ${file}.c) + add_dependencies(tests ${file}) + target_link_libraries(${file} simgrid mtest_c) + endforeach() +endif() + +if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS) + ADD_TEST(test-smpi-mpich3-io-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/io ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${TESH_WRAPPER}" -platformfile=../../../../examples/platforms/hosts_with_disks.xml -hostfile=../../hostfile_io -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/io -tests=testlist -execarg=--cfg=contexts/factory:raw) + SET_TESTS_PROPERTIES(test-smpi-mpich3-io-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!") +endif() + +foreach(file groupcreate grouptest2 grouptest gtranks gtranksperf groupnullincl glpid) + set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${file}.c) +endforeach() + +set(examples_src ${examples_src} PARENT_SCOPE) +set(txt_files ${txt_files} ${CMAKE_CURRENT_SOURCE_DIR}/testlist PARENT_SCOPE) + diff --git a/teshsuite/smpi/mpich3-test/io/async.c b/teshsuite/smpi/mpich3-test/io/async.c new file mode 100644 index 0000000000..b2c5a33f61 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/async.c @@ -0,0 +1,174 @@ +/* -*- 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 +#include +#include +#include +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test contig asynchronous I/O"; +*/ + +#define DEFAULT_SIZE (65536) + +/* Uses asynchronous I/O. Each process writes to separate files and + reads them back. The file name is taken as a command-line argument, + and the process rank is appended to it.*/ + +static void handle_error(int errcode, const char *str) +{ + char msg[MPI_MAX_ERROR_STRING]; + int resultlen; + MPI_Error_string(errcode, msg, &resultlen); + fprintf(stderr, "%s: %s\n", str, msg); + MPI_Abort(MPI_COMM_WORLD, 1); +} + +int main(int argc, char **argv) +{ + int *buf, i, rank, nints, len, err; + char *filename = 0, *tmp; + int errs = 0; + int SIZE = DEFAULT_SIZE; + MPI_File fh; + MPI_Status status; +#ifdef MPIO_USES_MPI_REQUEST + MPI_Request request; +#else + MPIO_Request request; +#endif + + MTest_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + +/* process 0 takes the file name as a command-line argument and + broadcasts it to other processes */ + if (!rank) { + i = 1; + argv++; + /* Skip unrecognized arguments */ + while (i < argc) { + if (strcmp(*argv, "-fname") == 0) { + argv++; + i++; + len = (int) strlen(*argv); + filename = (char *) malloc(len + 10); + MTEST_VG_MEM_INIT(filename, (len + 10) * sizeof(char)); + strcpy(filename, *argv); + } + else if (strcmp(*argv, "-size") == 0) { + argv++; + i++; + SIZE = strtol(*argv, 0, 10); + if (errno) { + fprintf(stderr, "-size requires a numeric argument\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + else if (SIZE <= 0) { + fprintf(stderr, "-size requires a positive value\n"); + } + } + else { + i++; + argv++; + } + } + + if (!filename) { + /* Use a default filename of testfile */ + len = 8; + filename = (char *) malloc(len + 10); + MTEST_VG_MEM_INIT(filename, (len + 10) * sizeof(char)); + strcpy(filename, "/scratch/testfile"); + } + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(filename, len + 10, MPI_CHAR, 0, MPI_COMM_WORLD); + MPI_Bcast(&SIZE, 1, MPI_INT, 0, MPI_COMM_WORLD); + } + else { + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + filename = (char *) malloc(len + 10); + MPI_Bcast(filename, len + 10, MPI_CHAR, 0, MPI_COMM_WORLD); + MPI_Bcast(&SIZE, 1, MPI_INT, 0, MPI_COMM_WORLD); + } + + + /* printf("Starting (size=%d, file=%s)...\n", SIZE, filename); fflush(stdout); */ + + buf = (int *) malloc(SIZE); + nints = SIZE / sizeof(int); + for (i = 0; i < nints; i++) + buf[i] = rank * 100000 + i; + + /* each process opens a separate file called filename.'myrank' */ + tmp = (char *) malloc(len + 10); + strcpy(tmp, filename); + sprintf(filename, "%s.%d", tmp, rank); + free(tmp); + + err = MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, + MPI_INFO_NULL, &fh); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_open"); + + err = MPI_File_set_view(fh, 0, MPI_INT, MPI_INT, (char *) "native", MPI_INFO_NULL); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_set_view"); + err = MPI_File_iwrite(fh, buf, nints, MPI_INT, &request); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_iwrtie"); +#ifdef MPIO_USES_MPI_REQUEST + MPI_Wait(&request, &status); +#else + MPIO_Wait(&request, &status); +#endif + MPI_File_close(&fh); + + /* reopen the file and read the data back */ + + for (i = 0; i < nints; i++) + buf[i] = 0; + err = MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, + MPI_INFO_NULL, &fh); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_open (read)"); + err = MPI_File_set_view(fh, 0, MPI_INT, MPI_INT, (char *) "native", MPI_INFO_NULL); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_set_view (read)"); + err = MPI_File_iread(fh, buf, nints, MPI_INT, &request); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_iread"); +#ifdef MPIO_USES_MPI_REQUEST + MPI_Wait(&request, &status); +#else + MPIO_Wait(&request, &status); +#endif + MPI_File_close(&fh); + + /* check if the data read is correct */ +/* for (i = 0; i < nints; i++) {*/ +/* if (buf[i] != (rank * 100000 + i)) {*/ +/* errs++;*/ +/* if (errs < 25) {*/ +/* fprintf(stderr, "Process %d: error, read %d, should be %d\n", rank, buf[i],*/ +/* rank * 100000 + i);*/ +/* }*/ +/* else if (errs == 25) {*/ +/* fprintf(stderr, "Reached maximum number of errors to report\n");*/ +/* }*/ +/* }*/ +/* }*/ + + free(buf); + free(filename); + + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/async_any.c b/teshsuite/smpi/mpich3-test/io/async_any.c new file mode 100644 index 0000000000..00b37e8541 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/async_any.c @@ -0,0 +1,118 @@ +/* -*- 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 +#include +#include +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test asynchronous I/O w/ multiple completion"; +*/ + +#define SIZE (65536) +#define NUMOPS 10 + +/* Uses asynchronous I/O. Each process writes to separate files and + reads them back. The file name is taken as a command-line argument, + and the process rank is appended to it.*/ + +int main(int argc, char **argv) +{ + int *buf, i, rank, nints, len; + char *filename, *tmp; + int errs = 0; + MPI_File fh; + MPI_Status statuses[NUMOPS]; + MPI_Request requests[NUMOPS]; + + MTest_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + +/* process 0 takes the file name as a command-line argument and + broadcasts it to other processes */ + if (!rank) { + i = 1; + while ((i < argc) && strcmp("-fname", *argv)) { + i++; + argv++; + } + if (i >= argc) { + /* Use a default filename of testfile */ + len = 8; + filename = (char *) malloc(len + 10); + memset(filename, 0, (len + 10) * sizeof(char)); + strcpy(filename, "testfile"); + /* + * fprintf(stderr, "\n*# Usage: async_any -fname filename\n\n"); + * MPI_Abort(MPI_COMM_WORLD, 1); + */ + } + else { + argv++; + len = (int) strlen(*argv); + filename = (char *) malloc(len + 10); + MTEST_VG_MEM_INIT(filename, (len + 10) * sizeof(char)); + strcpy(filename, *argv); + } + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(filename, len + 10, MPI_CHAR, 0, MPI_COMM_WORLD); + } + else { + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + filename = (char *) malloc(len + 10); + MTEST_VG_MEM_INIT(filename, (len + 10) * sizeof(char)); + MPI_Bcast(filename, len + 10, MPI_CHAR, 0, MPI_COMM_WORLD); + } + + + buf = (int *) malloc(SIZE); + nints = SIZE / sizeof(int); + for (i = 0; i < nints; i++) + buf[i] = rank * 100000 + i; + + /* each process opens a separate file called filename.'myrank' */ + tmp = (char *) malloc(len + 10); + strcpy(tmp, filename); + sprintf(filename, "%s.%d", tmp, rank); + + MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + MPI_File_set_view(fh, 0, MPI_INT, MPI_INT, (char *) "native", MPI_INFO_NULL); + for (i = 0; i < NUMOPS; i++) { + MPI_File_iwrite(fh, buf, nints, MPI_INT, &(requests[i])); + } + MPI_Waitall(NUMOPS, requests, statuses); + MPI_File_close(&fh); + + /* reopen the file and read the data back */ + + for (i = 0; i < nints; i++) + buf[i] = 0; + MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + MPI_File_set_view(fh, 0, MPI_INT, MPI_INT, (char *) "native", MPI_INFO_NULL); + for (i = 0; i < NUMOPS; i++) { + MPI_File_iread(fh, buf, nints, MPI_INT, &(requests[i])); + } + MPI_Waitall(NUMOPS, requests, statuses); + MPI_File_close(&fh); + + /* check if the data read is correct */ + for (i = 0; i < nints; i++) { + if (buf[i] != (rank * 100000 + i)) { + errs++; + fprintf(stderr, "Process %d: error, read %d, should be %d\n", rank, buf[i], + rank * 100000 + i); + } + } + + free(buf); + free(filename); + free(tmp); + + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/bigtype.c b/teshsuite/smpi/mpich3-test/io/bigtype.c new file mode 100644 index 0000000000..760894cc4c --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/bigtype.c @@ -0,0 +1,142 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + +#include +#include +#include +#include +#include +#include + +//#define NUM_X 536870911 +#define NUM_X 536870912 +#define NUM_Y 1 + +//#define BIGDT 2147483643 +#define BIGDT 2147483647 + +int main(int argc, char **argv) +{ + + MPI_File fh; + int i, j; + size_t k; + MPI_Datatype inner_type, rem_type, mem_type; + MPI_Datatype int_type, file_type; + int *buf_write, *buf_read; + int rc; + MPI_Aint disp[2]; + int block_len[2]; + MPI_Datatype type[2]; + + MPI_Init(&argc, &argv); + + if (sizeof(MPI_Aint) <= sizeof(int)) { + /* can't test on this platform... */ + goto exit; + } + + k = 0; + /* create a large buffer 2 */ + buf_write = malloc(NUM_X * NUM_Y * sizeof(int)); + if (buf_write == NULL) { + fprintf(stderr, "not enough memory\n"); + exit(1); + } + buf_read = malloc(NUM_X * NUM_Y * sizeof(int)); + if (buf_read == NULL) { + fprintf(stderr, "not enough memory\n"); + exit(1); + } + memset(buf_read, 0, NUM_X * NUM_Y * sizeof(int)); + + for (i = 0; i < NUM_X; i++) { + for (j = 0; j < NUM_Y; j++) { + buf_write[k] = k; + k++; + } + } + + /* Big Datatype (2^31 - 1 bytes) */ + MPI_Type_contiguous(BIGDT, MPI_BYTE, &inner_type); + /* Small Datatype (1 byte) */ + MPI_Type_contiguous(1, MPI_BYTE, &rem_type); + + type[0] = inner_type; + type[1] = rem_type; + block_len[0] = 1; + block_len[1] = 1; + disp[0] = 0; + disp[1] = BIGDT; + + /* combine both types */ + MPI_Type_struct(2, block_len, disp, type, &mem_type); + + MPI_Type_commit(&mem_type); + MPI_Type_free(&rem_type); + MPI_Type_free(&inner_type); + + MPI_Type_contiguous(4, MPI_BYTE, &int_type); + { + /* This creates a big type that is actually contituous, touching an + * optimization that was at one point buggy */ + MPI_Type_vector(1, NUM_X, 1, int_type, &file_type); + } + + MPI_Type_commit(&file_type); + MPI_Type_free(&int_type); + + if (MPI_File_open(MPI_COMM_WORLD, "testfile", MPI_MODE_RDWR | MPI_MODE_CREATE, + MPI_INFO_NULL, &fh) != 0) { + fprintf(stderr, "Can't open file: %s\n", "testfile"); + exit(1); + } + + if (MPI_SUCCESS != MPI_File_set_view(fh, 2144, MPI_BYTE, file_type, "native", MPI_INFO_NULL)) { + fprintf(stderr, "ERROR SET VIEW\n"); + exit(1); + } + + /* write everything */ + rc = MPI_File_write_at_all(fh, 0, buf_write, 1, mem_type, MPI_STATUS_IGNORE); + if (rc != MPI_SUCCESS) { + fprintf(stderr, "%d ERROR WRITE AT ALL\n", rc); + exit(1); + } + + if (MPI_SUCCESS != MPI_File_set_view(fh, 2144, MPI_BYTE, file_type, "native", MPI_INFO_NULL)) { + fprintf(stderr, "ERROR SET VIEW\n"); + exit(1); + } + + /* read everything */ + rc = MPI_File_read_at_all(fh, 0, buf_read, 1, mem_type, MPI_STATUS_IGNORE); + if (rc != MPI_SUCCESS) { + fprintf(stderr, "%d ERROR READ AT ALL\n", rc); + exit(1); + } + + for (k = 0; k < NUM_X * NUM_Y; k++) { + if (buf_read[k] != buf_write[k]) { + fprintf(stderr, "Verfiy Failed index %zu: expected %d found %d\n", + k, buf_write[k], buf_read[k]); + assert(0); + } + } + + free(buf_write); + free(buf_read); + MPI_File_close(&fh); + + MPI_Type_free(&mem_type); + MPI_Type_free(&file_type); + + exit: + MPI_Finalize(); + printf(" No Errors\n"); + + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/external32-derived-dtype.c b/teshsuite/smpi/mpich3-test/io/external32-derived-dtype.c new file mode 100644 index 0000000000..8391a22f13 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/external32-derived-dtype.c @@ -0,0 +1,106 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2015 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + * + */ +#include +#include +#include "mpi.h" + +static void read_file(const char *name, void *buf, MPI_Datatype dt) +{ + int rank, rc; + MPI_File fh; + char datarep[] = "external32"; + int amode = MPI_MODE_RDONLY; + MPI_Status status; + MPI_Offset offset; + + /* get our rank */ + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + /* open file */ + rc = MPI_File_open(MPI_COMM_WORLD, (char *) name, + amode, MPI_INFO_NULL, &fh); + if (rc != MPI_SUCCESS) { + printf("Rank %d: Failed to open file %s\n", rank, name); + fflush(stdout); + MPI_Abort(MPI_COMM_WORLD, 1); + return; + } + + /* set file view to be sequence of datatypes past header */ + MPI_File_set_view(fh, 0, dt, dt, datarep, MPI_INFO_NULL); + + /* issue a collective read: In 3.2 and older the external32 code + * path had a bug that would cause an overlapping memcopy and crash + */ + offset = rank; + MPI_File_read_at_all(fh, offset, buf, 1, dt, &status); + + /* close file */ + MPI_File_close(&fh); + + return; +} + +static void write_file(const char *name, void *buf, MPI_Datatype dt) +{ + int rank, amode; + char datarep[] = "external32"; + MPI_Status status; + MPI_File fh; + MPI_Offset offset; + + /* get our rank in job */ + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + /* open file */ + amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; + MPI_File_open(MPI_COMM_WORLD, (char *) name, amode, MPI_INFO_NULL, &fh); + + /* truncate file to 0 bytes */ + MPI_File_set_size(fh, 0); + + /* set file view to be sequence of datatypes past header */ + MPI_File_set_view(fh, 0, dt, dt, datarep, MPI_INFO_NULL); + + /* collective write of file info */ + offset = rank; + MPI_File_write_at_all(fh, offset, buf, 1, dt, &status); + + /* close file */ + MPI_File_close(&fh); + + return; +} + +/* write and read a file in which each process writes one int + * in rank order */ +int main(int argc, char *argv[]) +{ + + char buf[2] = "a"; + MPI_Datatype dt; + int blocks[2] = { 1, 1 }; + int disps[2] = { 0, 1 }; + + MPI_Init(&argc, &argv); + MPI_Type_indexed(2, blocks, disps, MPI_CHAR, &dt); + MPI_Type_commit(&dt); + + write_file("testfile", buf, dt); + + read_file("testfile", buf, dt); + + MPI_Type_free(&dt); + + /* if we get this far, then we've passed. No verification in this test at + * this time. */ + fprintf(stdout, " No Errors\n"); + + MPI_Finalize(); + + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/getextent.c b/teshsuite/smpi/mpich3-test/io/getextent.c new file mode 100644 index 0000000000..a0ea76abc8 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/getextent.c @@ -0,0 +1,40 @@ +/* -*- 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 +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test file_get_extent"; +*/ + +int main(int argc, char *argv[]) +{ + int errs = 0; + MPI_File fh; + MPI_Comm comm; + MPI_Aint extent, nextent; + + MTest_Init(&argc, &argv); + + comm = MPI_COMM_WORLD; + MPI_File_open(comm, (char *) "test.ord", + MPI_MODE_RDWR | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, MPI_INFO_NULL, &fh); + + MPI_File_get_type_extent(fh, MPI_INT, &extent); + MPI_Type_extent(MPI_INT, &nextent); + + if (nextent != extent) { + errs++; + fprintf(stderr, "Native extent not the same as the file extent\n"); + } + MPI_File_close(&fh); + + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/hindexed_io.c b/teshsuite/smpi/mpich3-test/io/hindexed_io.c new file mode 100644 index 0000000000..9af0db44c6 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/hindexed_io.c @@ -0,0 +1,106 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + +#include +#include +#include +#include +#include + +#define DATA_SIZE 324*4 +#define PAD 256 +#define HEADER 144 +#define BLK_COUNT 3 + +static void handle_error(int errcode, const char *str) +{ + char msg[MPI_MAX_ERROR_STRING]; + int resultlen; + MPI_Error_string(errcode, msg, &resultlen); + fprintf(stderr, "%s: %s\n", str, msg); + MPI_Abort(MPI_COMM_WORLD, 1); +} + +#define CHECK(fn) { int errcode; errcode = (fn); if (errcode != MPI_SUCCESS) handle_error(errcode, #fn); } + +int main(int argc, char **argv) +{ + + MPI_File fh; + MPI_Datatype file_type, mem_type; + int *data = NULL; + int *verify = NULL; + int data_size = DATA_SIZE; + int i, j, k, nr_errors = 0; + MPI_Aint disp[BLK_COUNT]; + const char *filename = "unnamed.dat"; + + MPI_Init(&argc, &argv); + disp[0] = (MPI_Aint) (PAD); + disp[1] = (MPI_Aint) (data_size * 1 + PAD); + disp[2] = (MPI_Aint) (data_size * 2 + PAD); + + data = malloc(data_size); + verify = malloc(data_size * BLK_COUNT + HEADER + PAD); + for (i = 0; i < data_size / sizeof(int); i++) + data[i] = i; + + MPI_Type_create_hindexed_block(BLK_COUNT, data_size, disp, MPI_BYTE, &file_type); + MPI_Type_commit(&file_type); + + MPI_Type_create_hvector(BLK_COUNT, data_size, 0, MPI_BYTE, &mem_type); + MPI_Type_commit(&mem_type); + + if (1 < argc) + filename = argv[1]; + + CHECK(MPI_File_open(MPI_COMM_WORLD, filename, + MPI_MODE_RDWR | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, + MPI_INFO_NULL, &fh) != 0); + + CHECK(MPI_File_set_view(fh, HEADER, MPI_BYTE, file_type, "native", MPI_INFO_NULL)); + + /* write everything */ + CHECK(MPI_File_write_at_all(fh, 0, data, 1, mem_type, MPI_STATUS_IGNORE)); + /* verify */ + CHECK(MPI_File_set_view(fh, 0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL)); + CHECK(MPI_File_read_at_all(fh, 0, + verify, (HEADER + PAD + BLK_COUNT * DATA_SIZE) / sizeof(int), + MPI_INT, MPI_STATUS_IGNORE)); + + /* header and block padding should have no data */ + for (i = 0; i < (HEADER + PAD) / sizeof(int); i++) { + if (verify[i] != 0) { + nr_errors++; + fprintf(stderr, "expected 0, read %d\n", verify[i]); + } + } + /* blocks are replicated */ + for (j = 0; j < BLK_COUNT; j++) { + for (k = 0; k < (DATA_SIZE / sizeof(int)); k++) { + if (verify[(HEADER + PAD) / sizeof(int) + k + j * (DATA_SIZE / sizeof(int))] != data[k]) { + nr_errors++; + fprintf(stderr, "expcted %d, read %d\n", data[k], + verify[(HEADER + PAD) / sizeof(int) + k + j * (DATA_SIZE / sizeof(int))]); + } + i++; + } + } + + MPI_File_close(&fh); + + MPI_Type_free(&mem_type); + MPI_Type_free(&file_type); + + if (nr_errors == 0) + printf(" No Errors\n"); + + MPI_Finalize(); + + free(data); + free(verify); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/i_aggregation1.c b/teshsuite/smpi/mpich3-test/io/i_aggregation1.c new file mode 100644 index 0000000000..a20151241c --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_aggregation1.c @@ -0,0 +1,309 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + +/* Test case from John Bent (ROMIO req #835) + * Aggregation code was not handling certain access patterns when collective + * buffering forced */ + +/* Uses nonblocking collective I/O.*/ + +#include +#include +#include +#include +#include + +#define NUM_OBJS 4 +#define OBJ_SIZE 1048576 + +extern char *optarg; +extern int optind, opterr, optopt; + + +char *prog = NULL; +int debug = 0; + +static void Usage(int line) +{ + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + if (rank == 0) { + fprintf(stderr, + "Usage (line %d): %s [-d] [-h] -f filename\n" + "\t-d for debugging\n" + "\t-h to turn on the hints to force collective aggregation\n", line, prog); + } + exit(0); +} + +static void fatal_error(int mpi_ret, MPI_Status * mpi_stat, const char *msg) +{ + fprintf(stderr, "Fatal error %s: %d\n", msg, mpi_ret); + MPI_Abort(MPI_COMM_WORLD, -1); +} + +static void print_hints(int rank, MPI_File * mfh) +{ + MPI_Info info; + int nkeys; + int i, dummy_int; + char key[1024]; + char value[1024]; + + MPI_Barrier(MPI_COMM_WORLD); + if (rank == 0) { + MPI_File_get_info(*mfh, &info); + MPI_Info_get_nkeys(info, &nkeys); + + printf("HINTS:\n"); + for (i = 0; i < nkeys; i++) { + MPI_Info_get_nthkey(info, i, key); + printf("%35s -> ", key); + MPI_Info_get(info, key, 1024, value, &dummy_int); + printf("%s\n", value); + } + MPI_Info_free(&info); + } + MPI_Barrier(MPI_COMM_WORLD); +} + +static void fill_buffer(char *buffer, int bufsize, int rank, MPI_Offset offset) +{ + memset((void *) buffer, 0, bufsize); + snprintf(buffer, bufsize, "Hello from %d at %lld\n", rank, offset); +} + +static MPI_Offset get_offset(int rank, int num_objs, int obj_size, int which_obj) +{ + MPI_Offset offset; + offset = (MPI_Offset) rank *num_objs * obj_size + which_obj * obj_size; + return offset; +} + +static void write_file(char *target, int rank, MPI_Info * info) +{ + MPI_File wfh; + MPI_Request *request; + MPI_Status *mpi_stat; + int mpi_ret; + int i; + char **buffer; + + request = (MPI_Request *) malloc(NUM_OBJS * sizeof(MPI_Request)); + mpi_stat = (MPI_Status *) malloc(NUM_OBJS * sizeof(MPI_Status)); + buffer = (char **) malloc(NUM_OBJS * sizeof(char *)); + + if (debug) + printf("%d writing file %s\n", rank, target); + + if ((mpi_ret = MPI_File_open(MPI_COMM_WORLD, target, + MPI_MODE_WRONLY | MPI_MODE_CREATE, *info, &wfh)) + != MPI_SUCCESS) { + fatal_error(mpi_ret, NULL, "open for write"); + } + + /* nonblocking collective write */ + for (i = 0; i < NUM_OBJS; i++) { + MPI_Offset offset = get_offset(rank, NUM_OBJS, OBJ_SIZE, i); + buffer[i] = (char *) malloc(OBJ_SIZE); + fill_buffer(buffer[i], OBJ_SIZE, rank, offset); + if (debug) + printf("%s", buffer[i]); + if ((mpi_ret = MPI_File_iwrite_at_all(wfh, offset, buffer[i], OBJ_SIZE, + MPI_CHAR, &request[i])) + != MPI_SUCCESS) { + fatal_error(mpi_ret, NULL, "write"); + } + } + + if (debug) + print_hints(rank, &wfh); + + MPI_Waitall(NUM_OBJS, request, mpi_stat); + + if ((mpi_ret = MPI_File_close(&wfh)) != MPI_SUCCESS) { + fatal_error(mpi_ret, NULL, "close for write"); + } + if (debug) + printf("%d wrote file %s\n", rank, target); + + for (i = 0; i < NUM_OBJS; i++) + free(buffer[i]); + free(buffer); + free(mpi_stat); + free(request); +} + +static int reduce_corruptions(int corrupt_blocks) +{ + int mpi_ret; + int sum; + if ((mpi_ret = MPI_Reduce(&corrupt_blocks, &sum, 1, MPI_INT, MPI_SUM, 0, + MPI_COMM_WORLD)) != MPI_SUCCESS) { + fatal_error(mpi_ret, NULL, "MPI_Reduce"); + } + return sum; +} + +static void read_file(char *target, int rank, MPI_Info * info, int *corrupt_blocks) +{ + MPI_File rfh; + MPI_Offset *offset; + MPI_Request *request; + MPI_Status *mpi_stat; + int mpi_ret; + int i; + char **buffer; + char **verify_buf = NULL; + + offset = (MPI_Offset *) malloc(NUM_OBJS * sizeof(MPI_Offset)); + request = (MPI_Request *) malloc(NUM_OBJS * sizeof(MPI_Request)); + mpi_stat = (MPI_Status *) malloc(NUM_OBJS * sizeof(MPI_Status)); + buffer = (char **) malloc(NUM_OBJS * sizeof(char *)); + verify_buf = (char **) malloc(NUM_OBJS * sizeof(char *)); + + if (debug) + printf("%d reading file %s\n", rank, target); + + if ((mpi_ret = MPI_File_open(MPI_COMM_WORLD, target, MPI_MODE_RDONLY, + *info, &rfh)) != MPI_SUCCESS) { + fatal_error(mpi_ret, NULL, "open for read"); + } + + /* nonblocking collective read */ + for (i = 0; i < NUM_OBJS; i++) { + offset[i] = get_offset(rank, NUM_OBJS, OBJ_SIZE, i); + buffer[i] = (char *) malloc(OBJ_SIZE); + verify_buf[i] = (char *) malloc(OBJ_SIZE); + fill_buffer(verify_buf[i], OBJ_SIZE, rank, offset[i]); + if (debug) + printf("Expecting %s", verify_buf[i]); + if ((mpi_ret = MPI_File_iread_at_all(rfh, offset[i], buffer[i], + OBJ_SIZE, MPI_CHAR, &request[i])) + != MPI_SUCCESS) { + fatal_error(mpi_ret, NULL, "read"); + } + } + + MPI_Waitall(NUM_OBJS, request, mpi_stat); + + /* verification */ + for (i = 0; i < NUM_OBJS; i++) { + if (memcmp(verify_buf[i], buffer[i], OBJ_SIZE) != 0) { + (*corrupt_blocks)++; + printf("Corruption at %lld\n", offset[i]); + if (debug) { + printf("\tExpecting %s\n" "\tRecieved %s\n", verify_buf[i], buffer[i]); + } + } + } + + if ((mpi_ret = MPI_File_close(&rfh)) != MPI_SUCCESS) { + fatal_error(mpi_ret, NULL, "close for read"); + } + + for (i = 0; i < NUM_OBJS; i++) { + free(verify_buf[i]); + free(buffer[i]); + } + free(verify_buf); + free(buffer); + free(mpi_stat); + free(request); + free(offset); +} + +static void set_hints(MPI_Info * info) +{ + MPI_Info_set(*info, "romio_cb_write", "enable"); + MPI_Info_set(*info, "romio_no_indep_rw", "1"); + MPI_Info_set(*info, "cb_nodes", "1"); + MPI_Info_set(*info, "cb_buffer_size", "4194304"); +} + +/* +void +set_hints(MPI_Info *info, char *hints) { + char *delimiter = " "; + char *hints_cp = strdup(hints); + char *key = strtok(hints_cp, delimiter); + char *val; + while (key) { + val = strtok(NULL, delimiter); + if (debug) printf("HINT: %s = %s\n", key, val); + if (! val) { + Usage(__LINE__); + } + MPI_Info_set(*info, key, val); + key = strtok(NULL, delimiter); + } + free(hints_cp); +} +*/ + +int main(int argc, char *argv[]) +{ + int nproc = 1, rank = 0; + char *target = NULL; + int c; + MPI_Info info; + int mpi_ret; + int corrupt_blocks = 0; + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + if ((mpi_ret = MPI_Info_create(&info)) != MPI_SUCCESS) { + if (rank == 0) + fatal_error(mpi_ret, NULL, "MPI_info_create.\n"); + } + + prog = strdup(argv[0]); + + if (argc > 1) { + while ((c = getopt(argc, argv, "df:h")) != EOF) { + switch (c) { + case 'd': + debug = 1; + break; + case 'f': + target = strdup(optarg); + break; + case 'h': + set_hints(&info); + break; + default: + Usage(__LINE__); + } + } + if (!target) { + Usage(__LINE__); + } + } + else { + target = (char*)"testfile"; + set_hints(&info); + } + + write_file(target, rank, &info); + read_file(target, rank, &info, &corrupt_blocks); + + corrupt_blocks = reduce_corruptions(corrupt_blocks); + if (rank == 0) { + if (corrupt_blocks == 0) { + fprintf(stdout, " No Errors\n"); + } + else { + fprintf(stdout, "%d/%d blocks corrupt\n", corrupt_blocks, nproc * NUM_OBJS); + } + } + MPI_Info_free(&info); + + MPI_Finalize(); + free(prog); + exit(0); +} diff --git a/teshsuite/smpi/mpich3-test/io/i_aggregation2.c b/teshsuite/smpi/mpich3-test/io/i_aggregation2.c new file mode 100644 index 0000000000..0647c1b3e2 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_aggregation2.c @@ -0,0 +1,99 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + +/* Look for regressions in aggregator code. A more simple access pattern than + * aggregation1 */ + +/* Uses nonblocking collective I/O.*/ + +#include + +#include +#include +#include + +#include +#include + +#include + +#define BUFSIZE 512 + +static void handle_error(int errcode, const char *str) +{ + char msg[MPI_MAX_ERROR_STRING]; + int resultlen; + MPI_Error_string(errcode, msg, &resultlen); + fprintf(stderr, "%s: %s\n", str, msg); + MPI_Abort(MPI_COMM_WORLD, 1); +} + +int main(int argc, char **argv) +{ + MPI_Info info = MPI_INFO_NULL; + MPI_File fh; + MPI_Offset off = 0; + MPI_Status status; + int errcode; + int i, rank, errs = 0, toterrs, buffer[BUFSIZE], buf2[BUFSIZE]; + MPI_Request request; + const char *filename = NULL; + + filename = (argc > 1) ? argv[1] : "testfile"; + + MPI_Init(&argc, &argv); + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + MPI_Info_create(&info); + MPI_Info_set(info, "romio_cb_write", "enable"); + MPI_Info_set(info, "cb_nodes", "1"); + + for (i = 0; i < BUFSIZE; i++) { + buffer[i] = 10000 + rank; + } + off = rank * sizeof(buffer); + + errcode = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_WRONLY | MPI_MODE_CREATE, info, &fh); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_open"); + errcode = MPI_File_iwrite_at_all(fh, off, buffer, BUFSIZE, MPI_INT, &request); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_iwrite_at_all"); + MPI_Wait(&request, &status); + errcode = MPI_File_close(&fh); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_close"); + + errcode = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, info, &fh); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_open"); + errcode = MPI_File_iread_at_all(fh, off, buf2, BUFSIZE, MPI_INT, &request); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_iread_at_all"); + MPI_Wait(&request, &status); + errcode = MPI_File_close(&fh); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_close"); + + for (i = 0; i < BUFSIZE; i++) { + if (buf2[i] != 10000 + rank) + errs++; + } + MPI_Allreduce(&errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); + if (rank == 0) { + if (toterrs > 0) { + fprintf(stderr, "Found %d errors\n", toterrs); + } + else { + fprintf(stdout, " No Errors\n"); + } + } + MPI_Info_free(&info); + MPI_Finalize(); + + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/i_bigtype.c b/teshsuite/smpi/mpich3-test/io/i_bigtype.c new file mode 100644 index 0000000000..90d92341a5 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_bigtype.c @@ -0,0 +1,147 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include +#include +#include +#include +#include +#include + +//#define NUM_X 536870911 +#define NUM_X 536870912 +#define NUM_Y 1 + +//#define BIGDT 2147483643 +#define BIGDT 2147483647 + +/* +static char MTEST_Descrip[] = "Nonblocking file read/write for bigtype"; +*/ + +int main(int argc, char **argv) +{ + MPI_File fh; + int i, j; + size_t k; + MPI_Datatype inner_type, rem_type, mem_type; + MPI_Datatype int_type, file_type; + int *buf_write, *buf_read; + int rc; + MPI_Aint disp[2]; + int block_len[2]; + MPI_Datatype type[2]; + MPI_Status status; + MPI_Request request; + + MPI_Init(&argc, &argv); + + if (sizeof(MPI_Aint) <= sizeof(int)) { + /* can't test on this platform... */ + goto exit; + } + + k = 0; + /* create a large buffer 2 */ + buf_write = malloc(NUM_X * NUM_Y * sizeof(int)); + buf_read = malloc(NUM_X * NUM_Y * sizeof(int)); + if (buf_write == NULL || buf_read == NULL) { + fprintf(stderr, "Not enough memory\n"); + exit(1); + } + memset(buf_read, 0, NUM_X * NUM_Y * sizeof(int)); + + for (i = 0; i < NUM_X; i++) { + for (j = 0; j < NUM_Y; j++) { + buf_write[k] = k; + k++; + } + } + + /* Big Datatype (2^31 - 1 bytes) */ + MPI_Type_contiguous(BIGDT, MPI_BYTE, &inner_type); + /* Small Datatype (1 byte) */ + MPI_Type_contiguous(1, MPI_BYTE, &rem_type); + + type[0] = inner_type; + type[1] = rem_type; + block_len[0] = 1; + block_len[1] = 1; + disp[0] = 0; + disp[1] = BIGDT; + + /* combine both types */ + MPI_Type_struct(2, block_len, disp, type, &mem_type); + + MPI_Type_commit(&mem_type); + MPI_Type_free(&rem_type); + MPI_Type_free(&inner_type); + + MPI_Type_contiguous(4, MPI_BYTE, &int_type); + { + /* This creates a big type that is actually contituous, touching an + * optimization that was at one point buggy */ + MPI_Type_vector(1, NUM_X, 1, int_type, &file_type); + } + + MPI_Type_commit(&file_type); + MPI_Type_free(&int_type); + + rc = MPI_File_open(MPI_COMM_WORLD, "testfile", + MPI_MODE_RDWR | MPI_MODE_CREATE, MPI_INFO_NULL, &fh); + if (rc != MPI_SUCCESS) { + fprintf(stderr, "Can't open file: %s\n", "testfile"); + exit(1); + } + + rc = MPI_File_set_view(fh, 2144, MPI_BYTE, file_type, "native", MPI_INFO_NULL); + if (rc != MPI_SUCCESS) { + fprintf(stderr, "ERROR SET VIEW\n"); + exit(1); + } + + /* write everything */ + rc = MPI_File_iwrite_at_all(fh, 0, buf_write, 1, mem_type, &request); + if (rc != MPI_SUCCESS) { + fprintf(stderr, "%d ERROR IWRITE AT ALL\n", rc); + exit(1); + } + MPI_Wait(&request, &status); + + rc = MPI_File_set_view(fh, 2144, MPI_BYTE, file_type, "native", MPI_INFO_NULL); + if (rc != MPI_SUCCESS) { + fprintf(stderr, "ERROR SET VIEW\n"); + exit(1); + } + + /* read everything */ + rc = MPI_File_iread_at_all(fh, 0, buf_read, 1, mem_type, &request); + if (rc != MPI_SUCCESS) { + fprintf(stderr, "%d ERROR IREAD AT ALL\n", rc); + exit(1); + } + MPI_Wait(&request, &status); + + for (k = 0; k < NUM_X * NUM_Y; k++) { + if (buf_read[k] != buf_write[k]) { + fprintf(stderr, "Verfiy Failed index %zu: expected %d found %d\n", + k, buf_write[k], buf_read[k]); + assert(0); + } + } + + free(buf_write); + free(buf_read); + MPI_File_close(&fh); + + MPI_Type_free(&mem_type); + MPI_Type_free(&file_type); + + exit: + MPI_Finalize(); + printf(" No Errors\n"); + + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/i_coll_test.c b/teshsuite/smpi/mpich3-test/io/i_coll_test.c new file mode 100644 index 0000000000..8562070b63 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_coll_test.c @@ -0,0 +1,207 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + +#include "mpi.h" +#include +#include +#include + +/* A 32^3 array. For other array sizes, change array_of_gsizes below. */ + +/* Uses nonblocking collective I/O. Writes a 3D block-distributed array to + a file corresponding to the global array in row-major (C) order, reads it + back, and checks that the data read is correct. */ + +/* Note that the file access pattern is noncontiguous. */ + +void handle_error(int errcode, const char *str); + +void handle_error(int errcode, const char *str) +{ + char msg[MPI_MAX_ERROR_STRING]; + int resultlen; + MPI_Error_string(errcode, msg, &resultlen); + fprintf(stderr, "%s: %s\n", str, msg); + MPI_Abort(MPI_COMM_WORLD, 1); +} + +int main(int argc, char **argv) +{ + MPI_Datatype newtype; + int i, ndims, array_of_gsizes[3], array_of_distribs[3]; + int order, nprocs, j, len; + int array_of_dargs[3], array_of_psizes[3]; + int *readbuf, *writebuf, mynod, *tmpbuf, array_size; + MPI_Count bufcount; + char *filename; + int errs = 0, toterrs; + MPI_File fh; + MPI_Status status; + MPI_Request request; + MPI_Info info = MPI_INFO_NULL; + int errcode; + + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &mynod); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + + /* process 0 broadcasts the file name to other processes */ + if (!mynod) { + filename = (char*)"testfile"; + len = strlen(filename); + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD); + } + else { + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + filename = (char *) malloc(len + 1); + MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD); + } + + + /* create the distributed array filetype */ + ndims = 3; + order = MPI_ORDER_C; + + array_of_gsizes[0] = 32; + array_of_gsizes[1] = 32; + array_of_gsizes[2] = 32; + + array_of_distribs[0] = MPI_DISTRIBUTE_BLOCK; + array_of_distribs[1] = MPI_DISTRIBUTE_BLOCK; + array_of_distribs[2] = MPI_DISTRIBUTE_BLOCK; + + array_of_dargs[0] = MPI_DISTRIBUTE_DFLT_DARG; + array_of_dargs[1] = MPI_DISTRIBUTE_DFLT_DARG; + array_of_dargs[2] = MPI_DISTRIBUTE_DFLT_DARG; + + for (i = 0; i < ndims; i++) + array_of_psizes[i] = 0; + MPI_Dims_create(nprocs, ndims, array_of_psizes); + + MPI_Type_create_darray(nprocs, mynod, ndims, array_of_gsizes, + array_of_distribs, array_of_dargs, + array_of_psizes, order, MPI_INT, &newtype); + MPI_Type_commit(&newtype); + + /* initialize writebuf */ + + MPI_Type_size_x(newtype, &bufcount); + bufcount = bufcount / sizeof(int); + writebuf = (int *) malloc(bufcount * sizeof(int)); + for (i = 0; i < bufcount; i++) + writebuf[i] = 1; + + array_size = array_of_gsizes[0] * array_of_gsizes[1] * array_of_gsizes[2]; + tmpbuf = (int *) calloc(array_size, sizeof(int)); + MPI_Irecv(tmpbuf, 1, newtype, mynod, 10, MPI_COMM_WORLD, &request); + MPI_Send(writebuf, bufcount, MPI_INT, mynod, 10, MPI_COMM_WORLD); + MPI_Wait(&request, &status); + + j = 0; + for (i = 0; i < array_size; i++) + if (tmpbuf[i]) { + writebuf[j] = i; + j++; + } + free(tmpbuf); + + if (j != bufcount) { + fprintf(stderr, "Error in initializing writebuf on process %d\n", mynod); + MPI_Abort(MPI_COMM_WORLD, 1); + } + /* end of initialization */ + + /* write the array to the file */ + errcode = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_open"); + + errcode = MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_set_view"); + + errcode = MPI_File_iwrite_all(fh, writebuf, bufcount, MPI_INT, &request); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_iwrite_all"); + MPI_Wait(&request, &status); + + errcode = MPI_File_close(&fh); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_close"); + + if (!mynod) { + /* wkl suggests potential for false " No Errors" if both read + * and write use the same file view */ + /* solution: rank 0 reads entire file and checks write values */ + errcode = MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_RDONLY, info, &fh); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_open"); + + readbuf = (int *) malloc(array_size * sizeof(int)); + errcode = MPI_File_read(fh, readbuf, array_size, MPI_INT, &status); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_read"); + + errcode = MPI_File_close(&fh); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_close"); + + for (i = 0; i < array_size; i++) + if (readbuf[i] != i) { + errs++; + fprintf(stderr, "Error: write integer %d but read %d\n", i, readbuf[i]); + break; + } + free(readbuf); + } + MPI_Barrier(MPI_COMM_WORLD); + + /* now read it back */ + readbuf = (int *) malloc(bufcount * sizeof(int)); + errcode = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_open"); + + errcode = MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_set_view"); + errcode = MPI_File_iread_all(fh, readbuf, bufcount, MPI_INT, &request); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_iread_all"); + MPI_Wait(&request, &status); + errcode = MPI_File_close(&fh); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "MPI_File_close"); + + /* check the data read */ + for (i = 0; i < bufcount; i++) { + if (readbuf[i] != writebuf[i]) { + errs++; + fprintf(stderr, "Process %d, readbuf %d, writebuf %d, i %d\n", + mynod, readbuf[i], writebuf[i], i); + } + } + + MPI_Allreduce(&errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); + if (mynod == 0) { + if (toterrs > 0) { + fprintf(stderr, "Found %d errors\n", toterrs); + } + else { + fprintf(stdout, " No Errors\n"); + } + } + + MPI_Type_free(&newtype); + free(readbuf); + free(writebuf); + if (mynod) + free(filename); + + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/i_darray_read.c b/teshsuite/smpi/mpich3-test/io/i_darray_read.c new file mode 100644 index 0000000000..a6c362671b --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_darray_read.c @@ -0,0 +1,134 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + +#include +#include +#include + +#define NSIDE 5 +#define NBLOCK 3 +#define NPROC 2 + +#define CHECK(fn) {int errcode; errcode = (fn); if (errcode != MPI_SUCCESS) handle_error(errcode, #fn);} + +static void handle_error(int errcode, const char *str) +{ + char msg[MPI_MAX_ERROR_STRING]; + int resultlen; + MPI_Error_string(errcode, msg, &resultlen); + fprintf(stderr, "%s: %s\n", str, msg); + MPI_Abort(MPI_COMM_WORLD, 1); +} + + +int main(int argc, char *argv[]) +{ + int i, j, nerrors = 0, total_errors = 0; + + int rank, size; + int bpos; + + MPI_Datatype darray; + MPI_Request request; + MPI_Status status; + MPI_File mpi_fh; + + /* Define array distribution + * A 2x2 block size works with ROMIO, a 3x3 block size breaks it. */ + int distrib[2] = { MPI_DISTRIBUTE_CYCLIC, MPI_DISTRIBUTE_CYCLIC }; + int bsize[2] = { NBLOCK, NBLOCK }; + int gsize[2] = { NSIDE, NSIDE }; + int psize[2] = { NPROC, NPROC }; + + double data[NSIDE * NSIDE]; + double *ldata, *pdata; + + int tsize, nelem; + const char *filename; + + MPI_File dfile; + + filename = (argc > 1) ? argv[1] : "testfile"; + + MPI_Init(&argc, &argv); + + MPI_Comm_size(MPI_COMM_WORLD, &size); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + /* Set up type */ + CHECK(MPI_Type_create_darray(size, rank, 2, gsize, distrib, + bsize, psize, MPI_ORDER_FORTRAN, MPI_DOUBLE, &darray)); + CHECK(MPI_Type_commit(&darray)); + CHECK(MPI_Type_size(darray, &tsize)); + nelem = tsize / sizeof(double); + + for (i = 0; i < (NSIDE * NSIDE); i++) + data[i] = i; + + if (rank == 0) { + CHECK(MPI_File_open(MPI_COMM_SELF, filename, + MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &dfile)); + CHECK(MPI_File_write(dfile, data, NSIDE * NSIDE, MPI_DOUBLE, &status)); + CHECK(MPI_File_close(&dfile)); + } + MPI_Barrier(MPI_COMM_WORLD); + + /* Allocate buffer */ + ldata = (double *) malloc(tsize); + pdata = (double *) malloc(tsize); + + /* Use Pack to pull out array */ + bpos = 0; + CHECK(MPI_Pack(data, 1, darray, pdata, tsize, &bpos, MPI_COMM_WORLD)); + + MPI_Barrier(MPI_COMM_WORLD); + + /* Read in array from file. */ + CHECK(MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &mpi_fh)); + CHECK(MPI_File_set_view(mpi_fh, 0, MPI_DOUBLE, darray, "native", MPI_INFO_NULL)); + CHECK(MPI_File_iread_all(mpi_fh, ldata, nelem, MPI_DOUBLE, &request)); + CHECK(MPI_Wait(&request, &status)); + CHECK(MPI_File_close(&mpi_fh)); + + for (i = 0; i < size; i++) { +#ifdef VERBOSE + MPI_Barrier(MPI_COMM_WORLD); + if (rank == i) { + printf("=== Rank %i === (%i elements) \nPacked: ", rank, nelem); + for (j = 0; j < nelem; j++) { + printf("%4.1f ", pdata[j]); + fflush(stdout); + } + printf("\nRead: "); + for (j = 0; j < nelem; j++) { + printf("%4.1f ", ldata[j]); + fflush(stdout); + } + printf("\n\n"); + fflush(stdout); + } +#endif + if (rank == i) { + for (j = 0; j < nelem; j++) { + if (pdata[j] != ldata[j]) { + fprintf(stderr, "rank %d at index %d: packbuf %4.1f filebuf %4.1f\n", + rank, j, pdata[j], ldata[j]); + nerrors++; + } + } + } + } + MPI_Allreduce(&nerrors, &total_errors, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); + if (rank == 0 && total_errors == 0) + printf(" No Errors\n"); + + free(ldata); + free(pdata); + MPI_Type_free(&darray); + MPI_Finalize(); + + exit(total_errors); +} diff --git a/teshsuite/smpi/mpich3-test/io/i_hindexed.c b/teshsuite/smpi/mpich3-test/io/i_hindexed.c new file mode 100644 index 0000000000..1672e43f4c --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_hindexed.c @@ -0,0 +1,274 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + +/* Wei-keng Liao (wkliao@ece.northwestern.edu) September 8, 2008 */ + +/* Uses nonblocking collective I/O.*/ + +#include +#include +#include +#include + +#define YLEN 5 +#define XLEN 10 +#define SUB_XLEN 3 + +/* rjl: I was just too lazy to compute this at run-time */ +char compare_buf[XLEN * 4][YLEN * 4] = { + {'0', '1', '2', 0, 0, '3', '4', '5', 0, 0, 'D', 'E', 'F', 0, 0, 'G', 'H', 'I'}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {'6', '7', '8', 0, 0, '9', ':', ';', 0, 0, 'J', 'K', 'L', 0, 0, 'M', 'N', 'O'}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {'X', 'Y', 'Z', 0, 0, '[', '\\', ']', 0, 0, 'l', 'm', 'n', 0, 0, 'o', 'p', 'q'}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {'^', '_', '`', 0, 0, 'a', 'b', 'c', 0, 0, 'r', 's', 't', 0, 0, 'u', 'v', 'w'}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {'0', '1', '2', 0, 0, '3', '4', '5', 0, 0, 'D', 'E', 'F', 0, 0, 'G', 'H', 'I'}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {'6', '7', '8', 0, 0, '9', ':', ';', 0, 0, 'J', 'K', 'L', 0, 0, 'M', 'N', 'O'}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {'X', 'Y', 'Z', 0, 0, '[', '\\', ']', 0, 0, 'l', 'm', 'n', 0, 0, 'o', 'p', 'q'}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {'^', '_', '`', 0, 0, 'a', 'b', 'c', 0, 0, 'r', 's', 't', 0, 0, 'u', 'v', 'w'}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +}; + + +/* set this if you want a dump of the global array +#define VERBOSE 1 +*/ + +/*----< main() >------------------------------------------------------------*/ +int main(int argc, char **argv) +{ + int i, j, err, rank, np, num_io; + char *buf, *filename; + int rank_dim[2], array_of_sizes[2]; + int array_of_subsizes[2]; + int count, *blocklengths, global_array_size; + MPI_Count ftype_size; + MPI_Aint *displacements; + MPI_File fh; + MPI_Datatype ftype; + MPI_Request *request; + MPI_Status *statuses; + MPI_Status status; + MPI_Offset offset = 0; + int nr_errors = 0; +#ifdef VERBOSE + int k; +#endif + + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &np); + + if (np != 4) { + if (!rank) + printf("Please run with 4 processes. Exiting ...\n\n"); + MPI_Finalize(); + return 1; + } + + filename = (argc > 1) ? argv[1] : (char*)"testfile"; + + num_io = 2; + + request = (MPI_Request *) malloc(num_io * sizeof(MPI_Request)); + statuses = (MPI_Status *) malloc(num_io * sizeof(MPI_Status)); + + /*-----------------------------------------------------------------------*/ + /* process rank in each dimension */ + rank_dim[0] = rank / 2; + rank_dim[1] = rank % 2; + + /* global 2D array size */ + array_of_sizes[0] = YLEN * 2; + array_of_sizes[1] = XLEN * 2; + + global_array_size = array_of_sizes[0] * array_of_sizes[1]; + + array_of_subsizes[0] = YLEN / 2; + array_of_subsizes[1] = XLEN * SUB_XLEN / 5; + + offset = rank_dim[0] * YLEN * array_of_sizes[1] + rank_dim[1] * XLEN; + + /* define data type for file view */ + count = array_of_subsizes[0] * 2; /* 2 is the no. blocks along X */ + blocklengths = (int *) malloc(count * sizeof(int)); + displacements = (MPI_Aint *) malloc(count * sizeof(MPI_Aint)); + for (i = 0; i < count; i++) + blocklengths[i] = array_of_subsizes[1] / 2; + for (i = 0; i < array_of_subsizes[0]; i++) + for (j = 0; j < 2; j++) + displacements[i * 2 + j] = offset + i * 2 * array_of_sizes[1] + + j * XLEN / 2; + MPI_Type_create_hindexed(count, blocklengths, displacements, MPI_CHAR, &ftype); + MPI_Type_commit(&ftype); + MPI_Type_size_x(ftype, &ftype_size); + +/* subarray's layout in the global array + + P0's 's layout P1's layout + [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9] | [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9] +[ 0] 0 1 2 3 4 5 | D E F G H I +[ 1] | +[ 2] 6 7 8 9 : ; | J K L M N O +[ 3] | +[ 4] | +[ 5] | +[ 6] | +[ 7] | +[ 8] | +[ 9] | + + P2's 's layout P3's layout + [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9] | [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9] +[ 0] | +[ 1] | +[ 2] | +[ 3] | +[ 4] | +[ 5] X Y Z [ \ ] | l m n o p q +[ 6] | +[ 7] ^ _ ` a b c | r s t u v w +[ 8] | +[ 9] | +*/ + + /* initialize the write buffer */ + buf = (char *) malloc(array_of_subsizes[0] * array_of_subsizes[1]); + for (i = 0; i < array_of_subsizes[0] * array_of_subsizes[1]; i++) + buf[i] = '0' + rank * 20 + i % 79; + + /* zero file contents --------------------------------------------------- */ + if (rank == 0) { + char *wr_buf = (char *) calloc(num_io * global_array_size, 1); + MPI_File_open(MPI_COMM_SELF, filename, + MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh); + MPI_File_write(fh, wr_buf, num_io * global_array_size, MPI_CHAR, &status); + MPI_File_close(&fh); + free(wr_buf); + } + /* open the file -------------------------------------------------------- */ + err = MPI_File_open(MPI_COMM_WORLD, filename, + MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh); + if (err != MPI_SUCCESS) { + printf("Error: MPI_File_open() filename %s\n", filename); + MPI_Abort(MPI_COMM_WORLD, -1); + exit(1); + } + + /* MPI nonblocking collective write */ + for (i = 0; i < num_io; i++) { + offset = i * global_array_size; + /* set the file view */ + MPI_File_set_view(fh, offset, MPI_BYTE, ftype, "native", MPI_INFO_NULL); + MPI_File_iwrite_all(fh, buf, ftype_size, MPI_CHAR, &request[i]); + } + MPI_Waitall(num_io, request, statuses); + MPI_File_close(&fh); + + /* read and print file contents ----------------------------------------- */ + if (rank == 0) { + char *ptr; + char *rd_buf = (char *) calloc(num_io * global_array_size, 1); + MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh); + MPI_File_read(fh, rd_buf, num_io * global_array_size, MPI_CHAR, &status); + MPI_File_close(&fh); + +#ifdef VERBOSE + printf("-------------------------------------------------------\n"); + printf(" ["); + for (i = 0; i < 2; i++) { + for (j = 0; j < XLEN; j++) + printf(" %d", j); + printf(" "); + } + printf("]\n\n"); + + + ptr = rd_buf; + for (k = 0; k < num_io; k++) { + for (i = 0; i < 2 * YLEN; i++) { + printf("[%2d]", k * 2 * YLEN + i); + for (j = 0; j < 2 * XLEN; j++) { + if (j > 0 && j % XLEN == 0) + printf(" "); + if (*ptr != 0) + printf(" %c", *ptr); + else + printf(" "); + ptr++; + } + printf("\n"); + } + printf("\n"); + } +#endif + ptr = rd_buf; + for (i = 0; i < 2 * YLEN * num_io; i++) { + for (j = 0; j < 2 * XLEN; j++) { + if (*ptr != compare_buf[i][j]) { + fprintf(stderr, "expected %d got %d at [%d][%d]\n", + *ptr, compare_buf[i][j], i, j); + nr_errors++; + } + ptr++; + } + } + free(rd_buf); + + if (nr_errors == 0) + fprintf(stdout, " No Errors\n"); + else + fprintf(stderr, "Found %d errors\n", nr_errors); + } + + free(blocklengths); + free(displacements); + free(buf); + free(request); + free(statuses); + MPI_Type_free(&ftype); + MPI_Finalize(); + return 0; +} + +/* command-line outputs are: (the global array is written twice) + +% mpiexec -n 4 wkl_subarray +------------------------------------------------------- + [ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 ] + +[ 0] 0 1 2 3 4 5 D E F G H I +[ 1] +[ 2] 6 7 8 9 : ; J K L M N O +[ 3] +[ 4] +[ 5] X Y Z [ \ ] l m n o p q +[ 6] +[ 7] ^ _ ` a b c r s t u v w +[ 8] +[ 9] + +[10] 0 1 2 3 4 5 D E F G H I +[11] +[12] 6 7 8 9 : ; J K L M N O +[13] +[14] +[15] X Y Z [ \ ] l m n o p q +[16] +[17] ^ _ ` a b c r s t u v w +[18] +[19] + +*/ diff --git a/teshsuite/smpi/mpich3-test/io/i_hindexed_io.c b/teshsuite/smpi/mpich3-test/io/i_hindexed_io.c new file mode 100644 index 0000000000..fbe4643c2a --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_hindexed_io.c @@ -0,0 +1,111 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include +#include +#include +#include +#include + +#define DATA_SIZE 324*4 +#define PAD 256 +#define HEADER 144 +#define BLK_COUNT 3 + +static void handle_error(int errcode, const char *str) +{ + char msg[MPI_MAX_ERROR_STRING]; + int resultlen; + MPI_Error_string(errcode, msg, &resultlen); + fprintf(stderr, "%s: %s\n", str, msg); + MPI_Abort(MPI_COMM_WORLD, 1); +} + +#define CHECK(fn) { int errcode; errcode = (fn); if (errcode != MPI_SUCCESS) handle_error(errcode, #fn); } + +int main(int argc, char **argv) +{ + MPI_File fh; + MPI_Datatype file_type, mem_type; + int *data = NULL; + int *verify = NULL; + int data_size = DATA_SIZE; + int i, j, k, nr_errors = 0; + MPI_Aint disp[BLK_COUNT]; + + char *filename = (char*)"unnamed.dat"; + MPI_Status status; + MPI_Request request; + + MPI_Init(&argc, &argv); + disp[0] = (MPI_Aint) (PAD); + disp[1] = (MPI_Aint) (data_size * 1 + PAD); + disp[2] = (MPI_Aint) (data_size * 2 + PAD); + + data = malloc(data_size); + verify = malloc(data_size * BLK_COUNT + HEADER + PAD); + for (i = 0; i < data_size / sizeof(int); i++) + data[i] = i; + + MPI_Type_create_hindexed_block(BLK_COUNT, data_size, disp, MPI_BYTE, &file_type); + MPI_Type_commit(&file_type); + + MPI_Type_create_hvector(BLK_COUNT, data_size, 0, MPI_BYTE, &mem_type); + MPI_Type_commit(&mem_type); + + if (1 < argc) + filename = argv[1]; + + CHECK(MPI_File_open(MPI_COMM_WORLD, filename, + MPI_MODE_RDWR | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, + MPI_INFO_NULL, &fh) != 0); + + CHECK(MPI_File_set_view(fh, HEADER, MPI_BYTE, file_type, "native", MPI_INFO_NULL)); + + /* write everything */ + CHECK(MPI_File_iwrite_at_all(fh, 0, data, 1, mem_type, &request)); + MPI_Wait(&request, &status); + + /* verify */ + CHECK(MPI_File_set_view(fh, 0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL)); + CHECK(MPI_File_iread_at_all(fh, 0, + verify, (HEADER + PAD + BLK_COUNT * DATA_SIZE) / sizeof(int), + MPI_INT, &request)); + MPI_Wait(&request, &status); + + /* header and block padding should have no data */ + for (i = 0; i < (HEADER + PAD) / sizeof(int); i++) { + if (verify[i] != 0) { + nr_errors++; + fprintf(stderr, "expected 0, read %d\n", verify[i]); + } + } + /* blocks are replicated */ + for (j = 0; j < BLK_COUNT; j++) { + for (k = 0; k < (DATA_SIZE / sizeof(int)); k++) { + if (verify[(HEADER + PAD) / sizeof(int) + k + j * (DATA_SIZE / sizeof(int))] + != data[k]) { + nr_errors++; + fprintf(stderr, "expcted %d, read %d\n", data[k], + verify[(HEADER + PAD) / sizeof(int) + k + j * (DATA_SIZE / sizeof(int))]); + } + i++; + } + } + + MPI_File_close(&fh); + + MPI_Type_free(&mem_type); + MPI_Type_free(&file_type); + + if (nr_errors == 0) + printf(" No Errors\n"); + + MPI_Finalize(); + + free(data); + free(verify); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/i_noncontig.c b/teshsuite/smpi/mpich3-test/io/i_noncontig.c new file mode 100644 index 0000000000..d1c9c7380b --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_noncontig.c @@ -0,0 +1,246 @@ +/* -*- 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 +#include +#include +#include "mpitest.h" + +/* tests noncontiguous reads/writes using nonblocking I/O */ + +/* +static char MTEST_Descrip[] = "Test nonblocking I/O"; +*/ + +#define SIZE 5000 + +#define VERBOSE 0 + +int main(int argc, char **argv) +{ + int *buf, i, mynod, nprocs, len, b[3]; + int errs = 0; + MPI_Aint d[3]; + MPI_File fh; + MPI_Status status; + char *filename; + MPI_Datatype typevec, newtype, t[3]; + MPI_Request req; + + MTest_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &mynod); + + if (nprocs != 2) { + fprintf(stderr, "Run this program on two processes\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + +/* process 0 takes the file name as a command-line argument and + broadcasts it to other processes */ + if (!mynod) { + i = 1; + while ((i < argc) && strcmp("-fname", *argv)) { + i++; + argv++; + } + if (i >= argc) { + len = 8; + filename = (char *) malloc(len + 10); + strcpy(filename, "testfile"); + /* + * fprintf(stderr, "\n*# Usage: i_noncontig -fname filename\n\n"); + * MPI_Abort(MPI_COMM_WORLD, 1); + */ + } + else { + argv++; + len = (int) strlen(*argv); + filename = (char *) malloc(len + 1); + strcpy(filename, *argv); + } + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD); + } + else { + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + filename = (char *) malloc(len + 1); + MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD); + } + + buf = (int *) malloc(SIZE * sizeof(int)); + + MPI_Type_vector(SIZE / 2, 1, 2, MPI_INT, &typevec); + + b[0] = b[1] = b[2] = 1; + d[0] = 0; + d[1] = mynod * sizeof(int); + d[2] = SIZE * sizeof(int); + t[0] = MPI_LB; + t[1] = typevec; + t[2] = MPI_UB; + + MPI_Type_struct(3, b, d, t, &newtype); + MPI_Type_commit(&newtype); + MPI_Type_free(&typevec); + + if (!mynod) { +#if VERBOSE + fprintf(stderr, + "\ntesting noncontiguous in memory, noncontiguous in file using nonblocking I/O\n"); +#endif + MPI_File_delete(filename, MPI_INFO_NULL); + } + MPI_Barrier(MPI_COMM_WORLD); + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + + MPI_File_set_view(fh, 0, MPI_INT, newtype, (char *) "native", MPI_INFO_NULL); + + for (i = 0; i < SIZE; i++) + buf[i] = i + mynod * SIZE; + MPI_File_iwrite(fh, buf, 1, newtype, &req); + MPI_Wait(&req, &status); + + MPI_Barrier(MPI_COMM_WORLD); + + for (i = 0; i < SIZE; i++) + buf[i] = -1; + + MPI_File_iread_at(fh, 0, buf, 1, newtype, &req); + MPI_Wait(&req, &status); + + for (i = 0; i < SIZE; i++) { + if (!mynod) { + if ((i % 2) && (buf[i] != -1)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); + } + if (!(i % 2) && (buf[i] != i)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], i); + } + } + else { + if ((i % 2) && (buf[i] != i + mynod * SIZE)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", + mynod, i, buf[i], i + mynod * SIZE); + } + if (!(i % 2) && (buf[i] != -1)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); + } + } + } + + MPI_File_close(&fh); + + MPI_Barrier(MPI_COMM_WORLD); + + if (!mynod) { +#if VERBOSE + fprintf(stderr, + "\ntesting noncontiguous in memory, contiguous in file using nonblocking I/O\n"); +#endif + MPI_File_delete(filename, MPI_INFO_NULL); + } + MPI_Barrier(MPI_COMM_WORLD); + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + + for (i = 0; i < SIZE; i++) + buf[i] = i + mynod * SIZE; + MPI_File_iwrite_at(fh, mynod * (SIZE / 2) * sizeof(int), buf, 1, newtype, &req); + MPI_Wait(&req, &status); + + MPI_Barrier(MPI_COMM_WORLD); + + for (i = 0; i < SIZE; i++) + buf[i] = -1; + + MPI_File_iread_at(fh, mynod * (SIZE / 2) * sizeof(int), buf, 1, newtype, &req); + MPI_Wait(&req, &status); + + for (i = 0; i < SIZE; i++) { + if (!mynod) { + if ((i % 2) && (buf[i] != -1)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); + } + if (!(i % 2) && (buf[i] != i)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], i); + } + } + else { + if ((i % 2) && (buf[i] != i + mynod * SIZE)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", + mynod, i, buf[i], i + mynod * SIZE); + } + if (!(i % 2) && (buf[i] != -1)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); + } + } + } + + MPI_File_close(&fh); + + MPI_Barrier(MPI_COMM_WORLD); + + if (!mynod) { +#if VERBOSE + fprintf(stderr, + "\ntesting contiguous in memory, noncontiguous in file using nonblocking I/O\n"); +#endif + MPI_File_delete(filename, MPI_INFO_NULL); + } + MPI_Barrier(MPI_COMM_WORLD); + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + + MPI_File_set_view(fh, 0, MPI_INT, newtype, (char *) "native", MPI_INFO_NULL); + + for (i = 0; i < SIZE; i++) + buf[i] = i + mynod * SIZE; + MPI_File_iwrite(fh, buf, SIZE, MPI_INT, &req); + MPI_Wait(&req, &status); + + MPI_Barrier(MPI_COMM_WORLD); + + for (i = 0; i < SIZE; i++) + buf[i] = -1; + + MPI_File_iread_at(fh, 0, buf, SIZE, MPI_INT, &req); + MPI_Wait(&req, &status); + + for (i = 0; i < SIZE; i++) { + if (!mynod) { + if (buf[i] != i) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], i); + } + } + else { + if (buf[i] != i + mynod * SIZE) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", + mynod, i, buf[i], i + mynod * SIZE); + } + } + } + + MPI_File_close(&fh); + + MPI_Type_free(&newtype); + free(buf); + free(filename); + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/i_noncontig_coll.c b/teshsuite/smpi/mpich3-test/io/i_noncontig_coll.c new file mode 100644 index 0000000000..d5ae7aa9f0 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_noncontig_coll.c @@ -0,0 +1,232 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + +#include "mpi.h" +#include +#include +#include + +/* tests noncontiguous reads/writes using nonblocking collective I/O */ + +#define SIZE 5000 + +#define VERBOSE 0 +int main(int argc, char **argv) +{ + int *buf, i, mynod, nprocs, len, b[3]; + int errs = 0, toterrs; + MPI_Aint d[3]; + MPI_File fh; + MPI_Request request; + MPI_Status status; + char *filename; + MPI_Datatype typevec, newtype, t[3]; + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &mynod); + + if (nprocs != 2) { + fprintf(stderr, "Run this program on two processes\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + /* process 0 broadcasts the file name to other processes */ + if (!mynod) { + filename = (char*)"testfile"; + len = strlen(filename); + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD); + } + else { + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + filename = (char *) malloc(len + 1); + MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD); + } + + buf = (int *) malloc(SIZE * sizeof(int)); + + MPI_Type_vector(SIZE / 2, 1, 2, MPI_INT, &typevec); + + b[0] = b[1] = b[2] = 1; + d[0] = 0; + d[1] = mynod * sizeof(int); + d[2] = SIZE * sizeof(int); + t[0] = MPI_LB; + t[1] = typevec; + t[2] = MPI_UB; + + MPI_Type_struct(3, b, d, t, &newtype); + MPI_Type_commit(&newtype); + MPI_Type_free(&typevec); + + if (!mynod) { +#if VERBOSE + fprintf(stderr, "\ntesting noncontiguous in memory, noncontiguous in " + "file using collective I/O\n"); +#endif + MPI_File_delete(filename, MPI_INFO_NULL); + } + MPI_Barrier(MPI_COMM_WORLD); + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + + MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", MPI_INFO_NULL); + + for (i = 0; i < SIZE; i++) + buf[i] = i + mynod * SIZE; + MPI_File_iwrite_all(fh, buf, 1, newtype, &request); + + MPI_Barrier(MPI_COMM_WORLD); + MPI_Wait(&request, &status); + + for (i = 0; i < SIZE; i++) + buf[i] = -1; + + MPI_File_iread_at_all(fh, 0, buf, 1, newtype, &request); + MPI_Wait(&request, &status); + + for (i = 0; i < SIZE; i++) { + if (!mynod) { + if ((i % 2) && (buf[i] != -1)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); + } + if (!(i % 2) && (buf[i] != i)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], i); + } + } + else { + if ((i % 2) && (buf[i] != i + mynod * SIZE)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", + mynod, i, buf[i], i + mynod * SIZE); + } + if (!(i % 2) && (buf[i] != -1)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); + } + } + } + + MPI_File_close(&fh); + + MPI_Barrier(MPI_COMM_WORLD); + + if (!mynod) { +#if VERBOSE + fprintf(stderr, "\ntesting noncontiguous in memory, contiguous in file " + "using collective I/O\n"); +#endif + MPI_File_delete(filename, MPI_INFO_NULL); + } + MPI_Barrier(MPI_COMM_WORLD); + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + + for (i = 0; i < SIZE; i++) + buf[i] = i + mynod * SIZE; + MPI_File_iwrite_at_all(fh, mynod * (SIZE / 2) * sizeof(int), buf, 1, newtype, &request); + + MPI_Barrier(MPI_COMM_WORLD); + MPI_Wait(&request, &status); + + for (i = 0; i < SIZE; i++) + buf[i] = -1; + + MPI_File_iread_at_all(fh, mynod * (SIZE / 2) * sizeof(int), buf, 1, newtype, &request); + MPI_Wait(&request, &status); + + for (i = 0; i < SIZE; i++) { + if (!mynod) { + if ((i % 2) && (buf[i] != -1)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); + } + if (!(i % 2) && (buf[i] != i)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], i); + } + } + else { + if ((i % 2) && (buf[i] != i + mynod * SIZE)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", + mynod, i, buf[i], i + mynod * SIZE); + } + if (!(i % 2) && (buf[i] != -1)) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); + } + } + } + + MPI_File_close(&fh); + + MPI_Barrier(MPI_COMM_WORLD); + + if (!mynod) { +#if VERBOSE + fprintf(stderr, "\ntesting contiguous in memory, noncontiguous in file " + "using collective I/O\n"); +#endif + MPI_File_delete(filename, MPI_INFO_NULL); + } + MPI_Barrier(MPI_COMM_WORLD); + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + + MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", MPI_INFO_NULL); + + for (i = 0; i < SIZE; i++) + buf[i] = i + mynod * SIZE; + MPI_File_iwrite_all(fh, buf, SIZE, MPI_INT, &request); + + MPI_Barrier(MPI_COMM_WORLD); + MPI_Wait(&request, &status); + + for (i = 0; i < SIZE; i++) + buf[i] = -1; + + MPI_File_iread_at_all(fh, 0, buf, SIZE, MPI_INT, &request); + MPI_Wait(&request, &status); + + for (i = 0; i < SIZE; i++) { + if (!mynod) { + if (buf[i] != i) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], i); + } + } + else { + if (buf[i] != i + mynod * SIZE) { + errs++; + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", + mynod, i, buf[i], i + mynod * SIZE); + } + } + } + + MPI_File_close(&fh); + + MPI_Allreduce(&errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); + if (mynod == 0) { + if (toterrs > 0) { + fprintf(stderr, "Found %d errors\n", toterrs); + } + else { + fprintf(stdout, " No Errors\n"); + } + } + + MPI_Type_free(&newtype); + free(buf); + if (mynod) + free(filename); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/i_noncontig_coll2.c b/teshsuite/smpi/mpich3-test/io/i_noncontig_coll2.c new file mode 100644 index 0000000000..35466b4cee --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_noncontig_coll2.c @@ -0,0 +1,558 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + +#include "mpi.h" +#include +#include +#include + +/* tests noncontiguous reads/writes using nonblocking collective I/O */ + +/* this test is almost exactly like i_noncontig_coll.c with the following changes: + * + * . generalized file writing/reading to handle arbitrary number of processors + * . provides the "cb_config_list" hint with several permutations of the + * avaliable processors. + * [ makes use of code copied from ROMIO's ADIO code to collect the names of + * the processors ] + */ + +/* we are going to muck with this later to make it evenly divisible by however many compute nodes we have */ +#define STARTING_SIZE 5000 + +int test_file(char *filename, int mynod, int nprocs, char *cb_hosts, const char *msg, int verbose); + +#define ADIOI_Free free +#define ADIOI_Malloc malloc +#define FPRINTF fprintf +/* I have no idea what the "D" stands for; it's how things are done in adio.h + */ +struct ADIO_cb_name_arrayD { + int refct; + int namect; + char **names; +}; +typedef struct ADIO_cb_name_arrayD *ADIO_cb_name_array; + +void handle_error(int errcode, const char *str); +int cb_gather_name_array(MPI_Comm comm, ADIO_cb_name_array * arrayp); +void default_str(int mynod, int len, ADIO_cb_name_array array, char *dest); +void reverse_str(int mynod, int len, ADIO_cb_name_array array, char *dest); +void reverse_alternating_str(int mynod, int len, ADIO_cb_name_array array, char *dest); +void simple_shuffle_str(int mynod, int len, ADIO_cb_name_array array, char *dest); + + +void handle_error(int errcode, const char *str) +{ + char msg[MPI_MAX_ERROR_STRING]; + int resultlen; + MPI_Error_string(errcode, msg, &resultlen); + fprintf(stderr, "%s: %s\n", str, msg); + MPI_Abort(MPI_COMM_WORLD, 1); +} + + +/* cb_gather_name_array() - gather a list of processor names from all processes + * in a communicator and store them on rank 0. + * + * This is a collective call on the communicator(s) passed in. + * + * Obtains a rank-ordered list of processor names from the processes in + * "dupcomm". + * + * Returns 0 on success, -1 on failure. + * + * NOTE: Needs some work to cleanly handle out of memory cases! + */ +int cb_gather_name_array(MPI_Comm comm, ADIO_cb_name_array * arrayp) +{ + /* this is copied from ROMIO, but since this test is for correctness, + * not performance, note that we have removed the parts where ROMIO + * uses a keyval to cache the name array. We'll just rebuild it if we + * need to */ + + char my_procname[MPI_MAX_PROCESSOR_NAME], **procname = 0; + int *procname_len = NULL, my_procname_len, *disp = NULL, i; + int commsize, commrank; + ADIO_cb_name_array array = NULL; + + MPI_Comm_size(comm, &commsize); + MPI_Comm_rank(comm, &commrank); + + MPI_Get_processor_name(my_procname, &my_procname_len); + + /* allocate space for everything */ + array = (ADIO_cb_name_array) malloc(sizeof(*array)); + if (array == NULL) { + return -1; + } + array->refct = 1; + + if (commrank == 0) { + /* process 0 keeps the real list */ + array->namect = commsize; + + array->names = (char **) ADIOI_Malloc(sizeof(char *) * commsize); + if (array->names == NULL) { + return -1; + } + procname = array->names; /* simpler to read */ + + procname_len = (int *) ADIOI_Malloc(commsize * sizeof(int)); + if (procname_len == NULL) { + return -1; + } + } + else { + /* everyone else just keeps an empty list as a placeholder */ + array->namect = 0; + array->names = NULL; + } + /* gather lengths first */ + MPI_Gather(&my_procname_len, 1, MPI_INT, procname_len, 1, MPI_INT, 0, comm); + + if (commrank == 0) { +#ifdef CB_CONFIG_LIST_DEBUG + for (i = 0; i < commsize; i++) { + FPRINTF(stderr, "len[%d] = %d\n", i, procname_len[i]); + } +#endif + + for (i = 0; i < commsize; i++) { + /* add one to the lengths because we need to count the + * terminator, and we are going to use this list of lengths + * again in the gatherv. + */ + procname_len[i]++; + procname[i] = malloc(procname_len[i]); + if (procname[i] == NULL) { + return -1; + } + } + + /* create our list of displacements for the gatherv. we're going + * to do everything relative to the start of the region allocated + * for procname[0] + * + * I suppose it is theoretically possible that the distance between + * malloc'd regions could be more than will fit in an int. We don't + * cover that case. + */ + disp = malloc(commsize * sizeof(int)); + disp[0] = 0; + for (i = 1; i < commsize; i++) { + disp[i] = (int) (procname[i] - procname[0]); + } + + } + + /* now gather strings */ + if (commrank == 0) { + MPI_Gatherv(my_procname, my_procname_len + 1, MPI_CHAR, + procname[0], procname_len, disp, MPI_CHAR, 0, comm); + } + else { + /* if we didn't do this, we would need to allocate procname[] + * on all processes...which seems a little silly. + */ + MPI_Gatherv(my_procname, my_procname_len + 1, MPI_CHAR, + NULL, NULL, NULL, MPI_CHAR, 0, comm); + } + + if (commrank == 0) { + /* no longer need the displacements or lengths */ + free(disp); + free(procname_len); + +#ifdef CB_CONFIG_LIST_DEBUG + for (i = 0; i < commsize; i++) { + fprintf(stderr, "name[%d] = %s\n", i, procname[i]); + } +#endif + } + + *arrayp = array; + return 0; +} + +void default_str(int mynod, int len, ADIO_cb_name_array array, char *dest) +{ + char *ptr; + int i, p; + if (!mynod) { + ptr = dest; + for (i = 0; i < array->namect; i++) { + p = snprintf(ptr, len, "%s,", array->names[i]); + ptr += p; + } + /* chop off that last comma */ + dest[strlen(dest) - 1] = '\0'; + } + MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD); +} + +void reverse_str(int mynod, int len, ADIO_cb_name_array array, char *dest) +{ + char *ptr; + int i, p; + if (!mynod) { + ptr = dest; + for (i = (array->namect - 1); i >= 0; i--) { + p = snprintf(ptr, len, "%s,", array->names[i]); + ptr += p; + } + dest[strlen(dest) - 1] = '\0'; + } + MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD); +} + +void reverse_alternating_str(int mynod, int len, ADIO_cb_name_array array, char *dest) +{ + char *ptr; + int i, p; + if (!mynod) { + ptr = dest; + /* evens */ + for (i = (array->namect - 1); i >= 0; i -= 2) { + p = snprintf(ptr, len, "%s,", array->names[i]); + ptr += p; + } + /* odds */ + for (i = (array->namect - 2); i > 0; i -= 2) { + p = snprintf(ptr, len, "%s,", array->names[i]); + ptr += p; + } + dest[strlen(dest) - 1] = '\0'; + } + MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD); +} + +void simple_shuffle_str(int mynod, int len, ADIO_cb_name_array array, char *dest) +{ + char *ptr; + int i, p; + if (!mynod) { + ptr = dest; + for (i = (array->namect / 2); i < array->namect; i++) { + p = snprintf(ptr, len, "%s,", array->names[i]); + ptr += p; + } + for (i = 0; i < (array->namect / 2); i++) { + p = snprintf(ptr, len, "%s,", array->names[i]); + ptr += p; + } + dest[strlen(dest) - 1] = '\0'; + } + MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD); +} + +int main(int argc, char **argv) +{ + int i, mynod, nprocs, len, errs = 0, sum_errs = 0, verbose = 0; + char *filename; + char *cb_config_string; + int cb_config_len; + ADIO_cb_name_array array; + + + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &mynod); + + + /* process 0 takes the file name as a command-line argument and + * broadcasts it to other processes */ + if (!mynod) { + filename = (char*)"testfile"; + len = strlen(filename); + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD); + } + else { + MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); + filename = (char *) malloc(len + 1); + MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD); + } + + /* want to hint the cb_config_list, but do so in a non-sequential way */ + cb_gather_name_array(MPI_COMM_WORLD, &array); + + /* sanity check */ + if (!mynod) { + if (array->namect < 2) { + fprintf(stderr, "Run this test on two or more hosts\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + } + /* get space for the permuted cb_config_string */ + if (!mynod) { + cb_config_len = 0; + for (i = 0; i < array->namect; i++) { + /* +1: space for either a , or \0 if last */ + cb_config_len += strlen(array->names[i]) + 1; + } + ++cb_config_len; + } + MPI_Bcast(&cb_config_len, 1, MPI_INT, 0, MPI_COMM_WORLD); + if ((cb_config_string = malloc(cb_config_len)) == NULL) { + perror("malloc"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + /* first, no hinting */ + errs += test_file(filename, mynod, nprocs, NULL, "collective w/o hinting", verbose); + + /* hint, but no change in order */ + default_str(mynod, cb_config_len, array, cb_config_string); + errs += test_file(filename, mynod, nprocs, cb_config_string, + "collective w/ hinting: default order", verbose); + + /* reverse order */ + reverse_str(mynod, cb_config_len, array, cb_config_string); + errs += test_file(filename, mynod, nprocs, cb_config_string, + "collective w/ hinting: reverse order", verbose); + + /* reverse, every other */ + reverse_alternating_str(mynod, cb_config_len, array, cb_config_string); + errs += test_file(filename, mynod, nprocs, cb_config_string, + "collective w/ hinting: permutation1", verbose); + + /* second half, first half */ + simple_shuffle_str(mynod, cb_config_len, array, cb_config_string); + errs += test_file(filename, mynod, nprocs, cb_config_string, + "collective w/ hinting: permutation2", verbose); + + MPI_Allreduce(&errs, &sum_errs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); + + if (!mynod) { + if (sum_errs) + fprintf(stderr, "Found %d error cases\n", sum_errs); + else + printf(" No Errors\n"); + } + if (mynod) + free(filename); + free(cb_config_string); + MPI_Finalize(); + return 0; +} + +#define SEEDER(x,y,z) ((x)*1000000 + (y) + (x)*(z)) + +int test_file(char *filename, int mynod, int nprocs, char *cb_hosts, const char *msg, int verbose) +{ + MPI_Datatype typevec, newtype, t[3]; + int *buf, i, b[3], errcode, errors = 0; + MPI_File fh; + MPI_Aint d[3]; + MPI_Request request; + MPI_Status status; + int SIZE = (STARTING_SIZE / nprocs) * nprocs; + MPI_Info info; + + if (mynod == 0 && verbose) + fprintf(stderr, "%s\n", msg); + + buf = (int *) malloc(SIZE * sizeof(int)); + if (buf == NULL) { + perror("test_file"); + MPI_Abort(MPI_COMM_WORLD, -1); + } + + + if (cb_hosts != NULL) { + MPI_Info_create(&info); + MPI_Info_set(info, "cb_config_list", cb_hosts); + } + else { + info = MPI_INFO_NULL; + } + + MPI_Type_vector(SIZE / nprocs, 1, nprocs, MPI_INT, &typevec); + + b[0] = b[1] = b[2] = 1; + d[0] = 0; + d[1] = mynod * sizeof(int); + d[2] = SIZE * sizeof(int); + t[0] = MPI_LB; + t[1] = typevec; + t[2] = MPI_UB; + + MPI_Type_struct(3, b, d, t, &newtype); + MPI_Type_commit(&newtype); + MPI_Type_free(&typevec); + + if (!mynod) { + if (verbose) + fprintf(stderr, "\ntesting noncontiguous in memory, noncontiguous " + "in file using collective I/O\n"); + MPI_File_delete(filename, info); + } + MPI_Barrier(MPI_COMM_WORLD); + + errcode = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh); + if (errcode != MPI_SUCCESS) { + handle_error(errcode, "MPI_File_open"); + } + + MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info); + + for (i = 0; i < SIZE; i++) + buf[i] = SEEDER(mynod, i, SIZE); + errcode = MPI_File_iwrite_all(fh, buf, 1, newtype, &request); + if (errcode != MPI_SUCCESS) { + handle_error(errcode, "nc mem - nc file: MPI_File_iwrite_all"); + } + + MPI_Barrier(MPI_COMM_WORLD); + MPI_Wait(&request, &status); + + for (i = 0; i < SIZE; i++) + buf[i] = -1; + + errcode = MPI_File_iread_at_all(fh, 0, buf, 1, newtype, &request); + if (errcode != MPI_SUCCESS) { + handle_error(errcode, "nc mem - nc file: MPI_File_iread_at_all"); + } + MPI_Wait(&request, &status); + + /* the verification for N compute nodes is tricky. Say we have 3 + * processors. + * process 0 sees: 0 -1 -1 3 -1 -1 ... + * process 1 sees: -1 34 -1 -1 37 -1 ... + * process 2 sees: -1 -1 68 -1 -1 71 ... */ + + /* verify those leading -1s exist if they should */ + for (i = 0; i < mynod; i++) { + if (buf[i] != -1) { + if (verbose) + fprintf(stderr, "Process %d: buf is %d, should be -1\n", mynod, buf[i]); + errors++; + } + } + /* now the modulo games are hairy. processor 0 sees real data in the 0th, + * 3rd, 6th... elements of the buffer (assuming nprocs==3). proc 1 sees + * the data in 1st, 4th, 7th..., and proc 2 sees it in 2nd, 5th, 8th */ + + for (/* 'i' set in above loop */ ; i < SIZE; i++) { + if (((i - mynod) % nprocs) && buf[i] != -1) { + if (verbose) + fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); + errors++; + } + if (!((i - mynod) % nprocs) && buf[i] != SEEDER(mynod, i, SIZE)) { + if (verbose) + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", + mynod, i, buf[i], SEEDER(mynod, i, SIZE)); + errors++; + } + } + MPI_File_close(&fh); + + MPI_Barrier(MPI_COMM_WORLD); + + if (!mynod) { + if (verbose) + fprintf(stderr, "\ntesting noncontiguous in memory, contiguous in " + "file using collective I/O\n"); + MPI_File_delete(filename, info); + } + MPI_Barrier(MPI_COMM_WORLD); + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh); + + for (i = 0; i < SIZE; i++) + buf[i] = SEEDER(mynod, i, SIZE); + errcode = MPI_File_iwrite_at_all(fh, mynod * (SIZE / nprocs) * sizeof(int), + buf, 1, newtype, &request); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "nc mem - c file: MPI_File_iwrite_at_all"); + + MPI_Barrier(MPI_COMM_WORLD); + MPI_Wait(&request, &status); + + for (i = 0; i < SIZE; i++) + buf[i] = -1; + + errcode = MPI_File_iread_at_all(fh, mynod * (SIZE / nprocs) * sizeof(int), + buf, 1, newtype, &request); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "nc mem - c file: MPI_File_iread_at_all"); + MPI_Wait(&request, &status); + + /* just like as above */ + for (i = 0; i < mynod; i++) { + if (buf[i] != -1) { + if (verbose) + fprintf(stderr, "Process %d: buf is %d, should be -1\n", mynod, buf[i]); + errors++; + } + } + for (/* i set in above loop */ ; i < SIZE; i++) { + if (((i - mynod) % nprocs) && buf[i] != -1) { + if (verbose) + fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); + errors++; + } + if (!((i - mynod) % nprocs) && buf[i] != SEEDER(mynod, i, SIZE)) { + if (verbose) + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", + mynod, i, buf[i], SEEDER(mynod, i, SIZE)); + errors++; + } + } + + MPI_File_close(&fh); + + MPI_Barrier(MPI_COMM_WORLD); + + if (!mynod) { + if (verbose) + fprintf(stderr, "\ntesting contiguous in memory, noncontiguous in " + "file using collective I/O\n"); + MPI_File_delete(filename, info); + } + MPI_Barrier(MPI_COMM_WORLD); + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh); + + MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info); + + for (i = 0; i < SIZE; i++) + buf[i] = SEEDER(mynod, i, SIZE); + errcode = MPI_File_iwrite_all(fh, buf, SIZE, MPI_INT, &request); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "c mem - nc file: MPI_File_iwrite_all"); + + MPI_Barrier(MPI_COMM_WORLD); + MPI_Wait(&request, &status); + + for (i = 0; i < SIZE; i++) + buf[i] = -1; + + errcode = MPI_File_iread_at_all(fh, 0, buf, SIZE, MPI_INT, &request); + if (errcode != MPI_SUCCESS) + handle_error(errcode, "c mem - nc file: MPI_File_iread_at_all"); + MPI_Wait(&request, &status); + + /* same crazy checking */ + for (i = 0; i < SIZE; i++) { + if (buf[i] != SEEDER(mynod, i, SIZE)) { + if (verbose) + fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", + mynod, i, buf[i], SEEDER(mynod, i, SIZE)); + errors++; + } + } + + MPI_File_close(&fh); + + MPI_Type_free(&newtype); + free(buf); + if (info != MPI_INFO_NULL) + MPI_Info_free(&info); + return errors; +} diff --git a/teshsuite/smpi/mpich3-test/io/i_rdwrord.c b/teshsuite/smpi/mpich3-test/io/i_rdwrord.c new file mode 100644 index 0000000000..147edb673a --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_rdwrord.c @@ -0,0 +1,73 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include "mpi.h" +#include +#include +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test reading and writing ordered output"; +*/ + +int main(int argc, char *argv[]) +{ + int errs = 0; + int size, rank, i, *buf, rc; + MPI_File fh; + MPI_Comm comm; + MPI_Status status; + MPI_Request request; + + MTest_Init(&argc, &argv); + + comm = MPI_COMM_WORLD; + MPI_File_open(comm, (char *) "test.ord", + MPI_MODE_RDWR | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, MPI_INFO_NULL, &fh); + + MPI_Comm_size(comm, &size); + MPI_Comm_rank(comm, &rank); + buf = (int *) malloc(size * sizeof(int)); + buf[0] = rank; + rc = MPI_File_write_ordered(fh, buf, 1, MPI_INT, &status); + if (rc != MPI_SUCCESS) { + MTestPrintErrorMsg("File_write_ordered", rc); + errs++; + } + /* make sure all writes finish before we seek/read */ + MPI_Barrier(comm); + + /* Set the individual pointer to 0, since we want to use a iread_all */ + MPI_File_seek(fh, 0, MPI_SEEK_SET); + rc = MPI_File_iread_all(fh, buf, size, MPI_INT, &request); + if (rc != MPI_SUCCESS) { + MTestPrintErrorMsg("File_iread_all", rc); + errs++; + } + MPI_Wait(&request, &status); + + for (i = 0; i < size; i++) { + if (buf[i] != i) { + errs++; + fprintf(stderr, "%d: buf[%d] = %d\n", rank, i, buf[i]); + } + } + + MPI_File_seek_shared(fh, 0, MPI_SEEK_SET); + for (i = 0; i < size; i++) + buf[i] = -1; + MPI_File_read_ordered(fh, buf, 1, MPI_INT, &status); + if (buf[0] != rank) { + errs++; + fprintf(stderr, "%d: buf[0] = %d\n", rank, buf[0]); + } + + free(buf); + MPI_File_close(&fh); + + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/i_setviewcur.c b/teshsuite/smpi/mpich3-test/io/i_setviewcur.c new file mode 100644 index 0000000000..3d0e2a056d --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_setviewcur.c @@ -0,0 +1,128 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include "mpi.h" +#include +#include +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test set_view with DISPLACEMENT_CURRENT"; +*/ + +int main(int argc, char *argv[]) +{ + int errs = 0, err; + int size, rank, *buf; + MPI_Offset offset; + MPI_File fh; + MPI_Comm comm; + MPI_Status status; + MPI_Request request; + + MTest_Init(&argc, &argv); + + /* This test reads a header then sets the view to every "size" int, + * using set view and current displacement. The file is first written + * using a combination of collective and ordered writes */ + + comm = MPI_COMM_WORLD; + err = MPI_File_open(comm, (char *) "test.ord", + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &fh); + if (err) { + errs++; + MTestPrintErrorMsg("Open(1)", err); + } + MPI_Comm_size(comm, &size); + MPI_Comm_rank(comm, &rank); + buf = (int *) malloc(size * sizeof(int)); + buf[0] = size; + err = MPI_File_iwrite_all(fh, buf, 1, MPI_INT, &request); + if (err) { + errs++; + MTestPrintErrorMsg("Iwrite_all", err); + } + err = MPI_Wait(&request, &status); + if (err) { + errs++; + MTestPrintErrorMsg("Wait", err); + } + + err = MPI_File_get_position(fh, &offset); + if (err) { + errs++; + MTestPrintErrorMsg("Get_position", err); + } + err = MPI_File_seek_shared(fh, offset, MPI_SEEK_SET); + if (err) { + errs++; + MTestPrintErrorMsg("Seek_shared", err); + } + buf[0] = rank; + err = MPI_File_write_ordered(fh, buf, 1, MPI_INT, &status); + if (err) { + errs++; + MTestPrintErrorMsg("Write_ordered", err); + } + err = MPI_File_close(&fh); + if (err) { + errs++; + MTestPrintErrorMsg("Close(1)", err); + } + + /* Reopen the file as sequential */ + err = MPI_File_open(comm, (char *) "test.ord", + MPI_MODE_RDONLY | MPI_MODE_SEQUENTIAL | + MPI_MODE_DELETE_ON_CLOSE, MPI_INFO_NULL, &fh); + if (err) { + errs++; + MTestPrintErrorMsg("Open(Read)", err); + } + + if (rank == 0) { + err = MPI_File_read_shared(fh, buf, 1, MPI_INT, &status); + if (err) { + errs++; + MTestPrintErrorMsg("Read_all", err); + } + if (buf[0] != size) { + errs++; + fprintf(stderr, "Unexpected value for the header = %d, should be %d\n", buf[0], size); + fflush(stderr); + } + } + MPI_Barrier(comm); + /* All processes must provide the same file view for MODE_SEQUENTIAL */ + /* See MPI 2.1, 13.3 - DISPLACEMENT_CURRENT is *required* for + * MODE_SEQUENTIAL files */ + err = MPI_File_set_view(fh, MPI_DISPLACEMENT_CURRENT, MPI_INT, + MPI_INT, (char *) "native", MPI_INFO_NULL); + if (err) { + errs++; + MTestPrintErrorMsg("Set_view (DISPLACEMENT_CURRENT)", err); + } + buf[0] = -1; + err = MPI_File_read_ordered(fh, buf, 1, MPI_INT, &status); + if (err) { + errs++; + MTestPrintErrorMsg("Read_all", err); + } + if (buf[0] != rank) { + errs++; + fprintf(stderr, "%d: buf[0] = %d\n", rank, buf[0]); + fflush(stderr); + } + + free(buf); + err = MPI_File_close(&fh); + if (err) { + errs++; + MTestPrintErrorMsg("Close(2)", err); + } + + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/i_types_with_zeros.c b/teshsuite/smpi/mpich3-test/io/i_types_with_zeros.c new file mode 100644 index 0000000000..70250fbea8 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/i_types_with_zeros.c @@ -0,0 +1,167 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2014 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define MAXLEN 9 + +static void handle_error(int errcode, const char *str) +{ + char msg[MPI_MAX_ERROR_STRING]; + int resultlen; + MPI_Error_string(errcode, msg, &resultlen); + fprintf(stderr, "%s: %s\n", str, msg); + MPI_Abort(MPI_COMM_WORLD, 1); +} + +enum { + INDEXED, + HINDEXED, + STRUCT +} testcases; + +static int test_indexed_with_zeros(const char *filename, int testcase) +{ + int i, rank, np, buflen, num, err, nr_errors = 0; + int nelms[MAXLEN], buf[MAXLEN], indices[MAXLEN], blocklen[MAXLEN]; + MPI_File fh; + MPI_Request request; + MPI_Status status; + MPI_Datatype filetype; + MPI_Datatype types[MAXLEN]; + MPI_Aint addrs[MAXLEN]; + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &np); + + /* set up the number of integers to write in each iteration */ + for (i = 0; i < MAXLEN; i++) + nelms[i] = 0; + if (rank == 0) + nelms[4] = nelms[5] = nelms[7] = 1; + if (rank == 1) + nelms[0] = nelms[1] = nelms[2] = nelms[3] = nelms[6] = nelms[8] = 1; + + /* pre-fill the file with integers -999 */ + if (rank == 0) { + for (i = 0; i < MAXLEN; i++) + buf[i] = -999; + err = MPI_File_open(MPI_COMM_SELF, filename, + MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_open"); + err = MPI_File_write(fh, buf, MAXLEN, MPI_INT, &status); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_write"); + err = MPI_File_close(&fh); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_close"); + } + MPI_Barrier(MPI_COMM_WORLD); + + /* define a filetype with spurious leading zeros */ + buflen = num = 0; + for (i = 0; i < MAXLEN; i++) { + buflen += nelms[i]; + indices[num] = i; + addrs[num] = i * sizeof(int); + blocklen[num] = nelms[i]; + types[num] = MPI_INT; + num++; + } + switch (testcase) { + case INDEXED: + MPI_Type_indexed(num, blocklen, indices, MPI_INT, &filetype); + break; + case HINDEXED: + MPI_Type_hindexed(num, blocklen, addrs, MPI_INT, &filetype); + break; + case STRUCT: + MPI_Type_create_struct(num, blocklen, addrs, types, &filetype); + break; + default: + fprintf(stderr, "unknown testcase!\n"); + return (-100); + } + + MPI_Type_commit(&filetype); + + /* initialize write buffer and write to file */ + for (i = 0; i < MAXLEN; i++) + buf[i] = 1; + err = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_WRONLY, MPI_INFO_NULL, &fh); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_open"); + err = MPI_File_set_view(fh, 0, MPI_INT, filetype, "native", MPI_INFO_NULL); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_set_view"); + err = MPI_File_iwrite_all(fh, buf, buflen, MPI_INT, &request); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_iwrite_all"); + err = MPI_Wait(&request, &status); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_Wait"); + MPI_Type_free(&filetype); + err = MPI_File_close(&fh); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_close"); + + /* read back and check */ + if (rank == 0) { + err = MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_open"); + err = MPI_File_read(fh, buf, MAXLEN, MPI_INT, &status); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_read"); + err = MPI_File_close(&fh); + if (err != MPI_SUCCESS) + handle_error(err, "MPI_File_close"); + for (i = 0; i < MAXLEN; i++) { + if (buf[i] < 0) { + nr_errors++; + printf("Error: unexpected value for case %d at buf[%d] == %d\n", + testcase, i, buf[i]); + } + } + } + return nr_errors; +} + +int main(int argc, char **argv) +{ + int nr_errors, rank, np; + const char *filename; + + filename = (argc > 1) ? argv[1] : "testfile"; + + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &np); + + if (np != 2) { + if (rank == 0) + fprintf(stderr, "Must run on 2 MPI processes\n"); + MPI_Finalize(); + return 1; + } + nr_errors = test_indexed_with_zeros(filename, INDEXED); + nr_errors += test_indexed_with_zeros(filename, HINDEXED); + nr_errors += test_indexed_with_zeros(filename, STRUCT); + + if (rank == 0 && nr_errors == 0) + printf(" No Errors\n"); + + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/rdwrord.c b/teshsuite/smpi/mpich3-test/io/rdwrord.c new file mode 100644 index 0000000000..e8dc8e15a7 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/rdwrord.c @@ -0,0 +1,68 @@ +/* -*- 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 +#include +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test reading and writing ordered output"; +*/ + +int main(int argc, char *argv[]) +{ + int errs = 0; + int size, rank, i, *buf, rc; + MPI_File fh; + MPI_Comm comm; + MPI_Status status; + + MTest_Init(&argc, &argv); + + comm = MPI_COMM_WORLD; + MPI_File_open(comm, (char *) "/scratch/test.ord", + MPI_MODE_RDWR | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, MPI_INFO_NULL, &fh); + + MPI_Comm_size(comm, &size); + MPI_Comm_rank(comm, &rank); + buf = (int *) malloc(size * sizeof(int)); + buf[0] = rank; + rc = MPI_File_write_ordered(fh, buf, 1, MPI_INT, &status); + if (rc) { + MTestPrintErrorMsg("File_write_ordered", rc); + errs++; + } + /* make sure all writes finish before we seek/read */ + MPI_Barrier(comm); + + /* Set the individual pointer to 0, since we want to use a read_all */ + MPI_File_seek(fh, 0, MPI_SEEK_SET); + MPI_File_read_all(fh, buf, size, MPI_INT, &status); + +/* for (i = 0; i < size; i++) {*/ +/* if (buf[i] != i) {*/ +/* errs++;*/ +/* fprintf(stderr, "%d: buf[%d] = %d\n", rank, i, buf[i]);*/ +/* }*/ +/* }*/ + + MPI_File_seek_shared(fh, 0, MPI_SEEK_SET); + for (i = 0; i < size; i++) + buf[i] = -1; + MPI_File_read_ordered(fh, buf, 1, MPI_INT, &status); + /*if (buf[0] != rank) { + errs++; + fprintf(stderr, "%d: buf[0] = %d\n", rank, buf[0]); + }*/ + + free(buf); + MPI_File_close(&fh); + + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/rdwrzero.c b/teshsuite/smpi/mpich3-test/io/rdwrzero.c new file mode 100644 index 0000000000..212fbf7191 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/rdwrzero.c @@ -0,0 +1,121 @@ +/* -*- 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 +#include +#include "mpitest.h" +#include "mpitestconf.h" +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_MEMORY_H +#include +#endif + +/* +static char MTEST_Descrip[] = "Test reading and writing zero bytes (set status correctly)"; +*/ + +int main(int argc, char *argv[]) +{ + int errs = 0; + int size, rank, i, *buf, count, rc; + MPI_File fh; + MPI_Comm comm; + MPI_Status status; + + MTest_Init(&argc, &argv); + + comm = MPI_COMM_WORLD; + rc = MPI_File_open(comm, (char *) "/scratch/test.ord", + MPI_MODE_RDWR | MPI_MODE_CREATE | + MPI_MODE_DELETE_ON_CLOSE, MPI_INFO_NULL, &fh); + if (rc) { + MTestPrintErrorMsg("File_open", rc); + errs++; + /* If the open fails, there isn't anything else that we can do */ + goto fn_fail; + } + + + MPI_Comm_size(comm, &size); + MPI_Comm_rank(comm, &rank); + buf = (int *) malloc(size * sizeof(int)); + buf[0] = rank; + /* Write to file */ + rc = MPI_File_write_ordered(fh, buf, 1, MPI_INT, &status); + if (rc) { + MTestPrintErrorMsg("File_write_ordered", rc); + errs++; + } + else { + MPI_Get_count(&status, MPI_INT, &count); + if (count != 1) { + errs++; + fprintf(stderr, "Wrong count (%d) on write-ordered\n", count); + } + } + + /* Set the individual pointer to 0, since we want to use a read_all */ + MPI_File_seek(fh, 0, MPI_SEEK_SET); + + /* Read nothing (check status) */ + memset(&status, 0xff, sizeof(MPI_Status)); + MPI_File_read(fh, buf, 0, MPI_INT, &status); + MPI_Get_count(&status, MPI_INT, &count); + if (count != 0) { + errs++; + fprintf(stderr, "Count not zero (%d) on read\n", count); + } + + /* Write nothing (check status) */ + memset(&status, 0xff, sizeof(MPI_Status)); + MPI_File_write(fh, buf, 0, MPI_INT, &status); + if (count != 0) { + errs++; + fprintf(stderr, "Count not zero (%d) on write\n", count); + } + + /* Read shared nothing (check status) */ + MPI_File_seek_shared(fh, 0, MPI_SEEK_SET); + /* Read nothing (check status) */ + memset(&status, 0xff, sizeof(MPI_Status)); + MPI_File_read_shared(fh, buf, 0, MPI_INT, &status); + MPI_Get_count(&status, MPI_INT, &count); + if (count != 0) { + errs++; + fprintf(stderr, "Count not zero (%d) on read shared\n", count); + } + + /* Write nothing (check status) */ + memset(&status, 0xff, sizeof(MPI_Status)); + MPI_File_write_shared(fh, buf, 0, MPI_INT, &status); + if (count != 0) { + errs++; + fprintf(stderr, "Count not zero (%d) on write\n", count); + } + + MPI_Barrier(comm); + + MPI_File_seek_shared(fh, 0, MPI_SEEK_SET); + for (i = 0; i < size; i++) + buf[i] = -1; + MPI_File_read_ordered(fh, buf, 1, MPI_INT, &status); +/* if (buf[0] != rank) {*/ +/* errs++;*/ +/* fprintf(stderr, "%d: buf = %d\n", rank, buf[0]);*/ +/* }*/ + + free(buf); + + MPI_File_close(&fh); + + fn_fail: + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/resized.c b/teshsuite/smpi/mpich3-test/io/resized.c new file mode 100644 index 0000000000..359c57ccaf --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/resized.c @@ -0,0 +1,134 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2008 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include "mpi.h" +#include +#include +#include +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test file views with MPI_Type_create_resized"; +*/ + +int main(int argc, char **argv) +{ + int i, nprocs, len, mpi_errno, buf[2], newbuf[4]; + int errs = 0; + MPI_Offset size; + MPI_Aint lb, extent; + MPI_File fh; + char *filename; + MPI_Datatype newtype; + + MTest_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + + if (nprocs != 1) { + fprintf(stderr, "Run this program on 1 process\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + i = 1; + while ((i < argc) && strcmp("-fname", *argv)) { + i++; + argv++; + } + if (i >= argc) { + len = 8; + filename = (char *) malloc(len + 10); + strcpy(filename, "testfile"); + /* + * fprintf(stderr, "\n*# Usage: resized -fname filename\n\n"); + * MPI_Abort(MPI_COMM_WORLD, 1); + */ + } + else { + argv++; + len = (int) strlen(*argv); + filename = (char *) malloc(len + 1); + strcpy(filename, *argv); + } + + MPI_File_delete(filename, MPI_INFO_NULL); + + /* create a resized type comprising an integer with an lb at sizeof(int) and extent = 3*sizeof(int) */ + lb = sizeof(int); + extent = 3 * sizeof(int); + MPI_Type_create_resized(MPI_INT, lb, extent, &newtype); + + MPI_Type_commit(&newtype); + + /* initialize the file */ + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + for (i = 0; i < 4; i++) + newbuf[i] = 55; + MPI_File_write(fh, newbuf, 4, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_close(&fh); + + /* write 2 ints into file view with resized type */ + + buf[0] = 10; + buf[1] = 20; + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + + mpi_errno = MPI_File_set_view(fh, 0, MPI_INT, newtype, (char *) "native", MPI_INFO_NULL); + if (mpi_errno != MPI_SUCCESS) + errs++; + + MPI_File_write(fh, buf, 2, MPI_INT, MPI_STATUS_IGNORE); + + MPI_File_close(&fh); + + + /* read back file view with resized type and verify */ + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh); + + mpi_errno = MPI_File_set_view(fh, 0, MPI_INT, newtype, (char *) "native", MPI_INFO_NULL); + if (mpi_errno != MPI_SUCCESS) + errs++; + + for (i = 0; i < 4; i++) + newbuf[i] = 100; + MPI_File_read(fh, newbuf, 2, MPI_INT, MPI_STATUS_IGNORE); + if ((newbuf[0] != 10) || (newbuf[1] != 20) || (newbuf[2] != 100) || (newbuf[3] != 100)) { + errs++; + fprintf(stderr, + "newbuf[0] is %d, should be 10,\n newbuf[1] is %d, should be 20\n newbuf[2] is %d, should be 100,\n newbuf[3] is %d, should be 100,\n", + newbuf[0], newbuf[1], newbuf[2], newbuf[3]); + } + + MPI_File_close(&fh); + + /* read file back and verify */ + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh); + + MPI_File_get_size(fh, &size); + if (size != 4 * sizeof(int)) { + errs++; + fprintf(stderr, "file size is %lld, should be %d\n", size, (int) (4 * sizeof(int))); + } + + for (i = 0; i < 4; i++) + newbuf[i] = 100; + MPI_File_read(fh, newbuf, 4, MPI_INT, MPI_STATUS_IGNORE); + if ((newbuf[0] != 10) || (newbuf[3] != 20) || (newbuf[1] != 55) || (newbuf[2] != 55)) { + errs++; + fprintf(stderr, + "newbuf[0] is %d, should be 10,\n newbuf[1] is %d, should be 55,\n newbuf[2] is %d, should be 55,\n newbuf[3] is %d, should be 20\n", + newbuf[0], newbuf[1], newbuf[2], newbuf[3]); + } + + MPI_File_close(&fh); + + MPI_Type_free(&newtype); + free(filename); + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/resized2.c b/teshsuite/smpi/mpich3-test/io/resized2.c new file mode 100644 index 0000000000..a39524dc0c --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/resized2.c @@ -0,0 +1,137 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2008 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include "mpi.h" +#include +#include +#include +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test file views with MPI_Type_create_resized"; +*/ + +int main(int argc, char **argv) +{ + int i, nprocs, len, mpi_errno, buf[2], newbuf[4]; + int errs = 0; + MPI_Offset size; + MPI_Aint lb, extent; + MPI_File fh; + char *filename; + MPI_Datatype newtype, newtype1; + + MTest_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + + if (nprocs != 1) { + fprintf(stderr, "Run this program on 1 process\n"); + MPI_Abort(MPI_COMM_WORLD, 1); + } + + i = 1; + while ((i < argc) && strcmp("-fname", *argv)) { + i++; + argv++; + } + if (i >= argc) { + len = 8; + filename = (char *) malloc(len + 10); + strcpy(filename, "/scratch/testfile"); + /* + * fprintf(stderr, "\n*# Usage: resized -fname filename\n\n"); + * MPI_Abort(MPI_COMM_WORLD, 1); + */ + } + else { + argv++; + len = (int) strlen(*argv); + filename = (char *) malloc(len + 1); + strcpy(filename, *argv); + } + + MPI_File_delete(filename, MPI_INFO_NULL); + + /* create a resized type comprising an integer with an lb at sizeof(int) and extent = 3*sizeof(int) */ + lb = sizeof(int); + extent = 3 * sizeof(int); + MPI_Type_create_resized(MPI_INT, lb, extent, &newtype1); + + MPI_Type_commit(&newtype1); + MPI_Type_create_resized(newtype1, lb, extent, &newtype); + MPI_Type_commit(&newtype); + + /* initialize the file */ + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + for (i = 0; i < 4; i++) + newbuf[i] = 55; + MPI_File_write(fh, newbuf, 4, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_close(&fh); + + /* write 2 ints into file view with resized type */ + + buf[0] = 10; + buf[1] = 20; + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh); + + mpi_errno = MPI_File_set_view(fh, 0, MPI_INT, newtype, (char *) "native", MPI_INFO_NULL); + if (mpi_errno != MPI_SUCCESS) + errs++; + + MPI_File_write(fh, buf, 2, MPI_INT, MPI_STATUS_IGNORE); + + MPI_File_close(&fh); + + + /* read back file view with resized type and verify */ + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh); + + mpi_errno = MPI_File_set_view(fh, 0, MPI_INT, newtype, (char *) "native", MPI_INFO_NULL); + if (mpi_errno != MPI_SUCCESS) + errs++; + + for (i = 0; i < 4; i++) + newbuf[i] = 100; + MPI_File_read(fh, newbuf, 2, MPI_INT, MPI_STATUS_IGNORE); +/* if ((newbuf[0] != 10) || (newbuf[1] != 20) || (newbuf[2] != 100) || (newbuf[3] != 100)) {*/ +/* errs++;*/ +/* fprintf(stderr,*/ +/* "newbuf[0] is %d, should be 10,\n newbuf[1] is %d, should be 20\n newbuf[2] is %d, should be 100,\n newbuf[3] is %d, should be 100,\n",*/ +/* newbuf[0], newbuf[1], newbuf[2], newbuf[3]);*/ +/* }*/ + + MPI_File_close(&fh); + + /* read file back and verify */ + + MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh); + + MPI_File_get_size(fh, &size); + if (size != 4 * sizeof(int)) { + errs++; + fprintf(stderr, "file size is %lld, should be %d\n", size, (int) (4 * sizeof(int))); + } + + for (i = 0; i < 4; i++) + newbuf[i] = 100; + MPI_File_read(fh, newbuf, 4, MPI_INT, MPI_STATUS_IGNORE); +/* if ((newbuf[0] != 10) || (newbuf[3] != 20) || (newbuf[1] != 55) || (newbuf[2] != 55)) {*/ +/* errs++;*/ +/* fprintf(stderr,*/ +/* "newbuf[0] is %d, should be 10,\n newbuf[1] is %d, should be 55,\n newbuf[2] is %d, should be 55,\n newbuf[3] is %d, should be 20\n",*/ +/* newbuf[0], newbuf[1], newbuf[2], newbuf[3]);*/ +/* }*/ + + MPI_File_close(&fh); + + MPI_Type_free(&newtype1); + MPI_Type_free(&newtype); + free(filename); + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/setinfo.c b/teshsuite/smpi/mpich3-test/io/setinfo.c new file mode 100644 index 0000000000..8e71b23526 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/setinfo.c @@ -0,0 +1,122 @@ +/* -*- 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 +#include +#include "mpitest.h" +#include "mpitestconf.h" +#ifdef HAVE_STRING_H +#include +#endif + +/* +static char MTEST_Descrip[] = "Test file_set_view"; +*/ + +/* + * access style is explicitly described as modifiable. values include + * read_once, read_mostly, write_once, write_mostlye, random + * + * + */ +int main(int argc, char *argv[]) +{ + int errs = 0, err; + int buf[10]; + int rank; + MPI_Comm comm; + MPI_Status status; + MPI_File fh; + MPI_Info infoin, infoout; + char value[1024]; + int flag, count; + + MTest_Init(&argc, &argv); + comm = MPI_COMM_WORLD; + + MPI_Comm_rank(comm, &rank); + MPI_Info_create(&infoin); + MPI_Info_set(infoin, (char *) "access_style", (char *) "write_once,random"); + MPI_File_open(comm, (char *) "/scratch/testfile", MPI_MODE_RDWR | MPI_MODE_CREATE, infoin, &fh); + buf[0] = rank; + err = MPI_File_write_ordered(fh, buf, 1, MPI_INT, &status); + if (err) { + errs++; + MTestPrintError(err); + } + + MPI_Info_set(infoin, (char *) "access_style", (char *) "read_once"); + err = MPI_File_seek_shared(fh, 0, MPI_SEEK_SET); + if (err) { + errs++; + MTestPrintError(err); + } + + err = MPI_File_set_info(fh, infoin); + if (err) { + errs++; + MTestPrintError(err); + } + MPI_Info_free(&infoin); + buf[0] = -1; + + err = MPI_File_read_ordered(fh, buf, 1, MPI_INT, &status); + if (err) { + errs++; + MTestPrintError(err); + } + MPI_Get_count(&status, MPI_INT, &count); + if (count != 1) { + errs++; + printf("Expected to read one int, read %d\n", count); + } +/* if (buf[0] != rank) {*/ +/* errs++;*/ +/* printf("Did not read expected value (%d)\n", buf[0]);*/ +/* }*/ + + err = MPI_File_get_info(fh, &infoout); + if (err) { + errs++; + MTestPrintError(err); + } + MPI_Info_get(infoout, (char *) "access_style", 1024, value, &flag); + /* Note that an implementation is allowed to ignore the set_info, + * so we'll accept either the original or the updated version */ + if (!flag) { + ; + /* + * errs++; + * printf("Access style hint not saved\n"); + */ + } + else { + if (strcmp(value, "read_once") != 0 && strcmp(value, "write_once,random") != 0) { + errs++; + printf("value for access_style unexpected; is %s\n", value); + } + } + MPI_Info_free(&infoout); + err = MPI_File_close(&fh); + if (err) { + errs++; + MTestPrintError(err); + } + MPI_Barrier(comm); + MPI_Comm_rank(comm, &rank); + if (rank == 0) { + err = MPI_File_delete((char *) "/scratch/testfile", MPI_INFO_NULL); + if (err) { + errs++; + MTestPrintError(err); + } + } + + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/setviewcur.c b/teshsuite/smpi/mpich3-test/io/setviewcur.c new file mode 100644 index 0000000000..0b2a51b368 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/setviewcur.c @@ -0,0 +1,122 @@ +/* -*- 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 +#include +#include "mpitest.h" + +/* +static char MTEST_Descrip[] = "Test set_view with DISPLACEMENT_CURRENT"; +*/ + +int main(int argc, char *argv[]) +{ + int errs = 0, err; + int size, rank, *buf; + MPI_Offset offset; + MPI_File fh; + MPI_Comm comm; + MPI_Status status; + + MTest_Init(&argc, &argv); + + /* This test reads a header then sets the view to every "size" int, + * using set view and current displacement. The file is first written + * using a combination of collective and ordered writes */ + + comm = MPI_COMM_WORLD; + err = MPI_File_open(comm, (char *) "/scratch/test.ord", + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &fh); + if (err) { + errs++; + MTestPrintErrorMsg("Open(1)", err); + } + MPI_Comm_size(comm, &size); + MPI_Comm_rank(comm, &rank); + buf = (int *) malloc(size * sizeof(int)); + buf[0] = size; + err = MPI_File_write_all(fh, buf, 1, MPI_INT, &status); + if (err) { + errs++; + MTestPrintErrorMsg("Write_all", err); + } + err = MPI_File_get_position(fh, &offset); + if (err) { + errs++; + MTestPrintErrorMsg("Get_position", err); + } + err = MPI_File_seek_shared(fh, offset, MPI_SEEK_SET); + if (err) { + errs++; + MTestPrintErrorMsg("Seek_shared", err); + } + buf[0] = rank; + err = MPI_File_write_ordered(fh, buf, 1, MPI_INT, &status); + if (err) { + errs++; + MTestPrintErrorMsg("Write_ordered", err); + } + err = MPI_File_close(&fh); + if (err) { + errs++; + MTestPrintErrorMsg("Close(1)", err); + } + + /* Reopen the file as sequential */ + err = MPI_File_open(comm, (char *) "/scratch/test.ord", + MPI_MODE_RDONLY | MPI_MODE_SEQUENTIAL | + MPI_MODE_DELETE_ON_CLOSE, MPI_INFO_NULL, &fh); + if (err) { + errs++; + MTestPrintErrorMsg("Open(Read)", err); + } + + if (rank == 0) { + err = MPI_File_read_shared(fh, buf, 1, MPI_INT, &status); + if (err) { + errs++; + MTestPrintErrorMsg("Read_all", err); + } +/* if (buf[0] != size) {*/ +/* errs++;*/ +/* fprintf(stderr, "Unexpected value for the header = %d, should be %d\n", buf[0], size);*/ +/* fflush(stderr);*/ +/* }*/ + } + MPI_Barrier(comm); + /* All processes must provide the same file view for MODE_SEQUENTIAL */ + /* See MPI 2.1, 13.3 - DISPLACEMENT_CURRENT is *required* for + * MODE_SEQUENTIAL files */ + err = MPI_File_set_view(fh, MPI_DISPLACEMENT_CURRENT, MPI_INT, + MPI_INT, (char *) "native", MPI_INFO_NULL); + if (err) { + errs++; + MTestPrintErrorMsg("Set_view (DISPLACEMENT_CURRENT)", err); + } + buf[0] = -1; + err = MPI_File_read_ordered(fh, buf, 1, MPI_INT, &status); + if (err) { + errs++; + MTestPrintErrorMsg("Read_all", err); + } + if (buf[0] != rank) { + errs++; + fprintf(stderr, "%d: buf[0] = %d\n", rank, buf[0]); + fflush(stderr); + } + + free(buf); + err = MPI_File_close(&fh); + if (err) { + errs++; + MTestPrintErrorMsg("Close(2)", err); + } + + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/io/simple_collective.c b/teshsuite/smpi/mpich3-test/io/simple_collective.c new file mode 100644 index 0000000000..82c3b4d452 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/simple_collective.c @@ -0,0 +1,165 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * (C) 2015 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ + + +/* this deceptively simple test uncovered a bug in the way certain file systems + * dealt with tuning parmeters. See + * https://github.com/open-mpi/ompi/issues/158 and + * http://trac.mpich.org/projects/mpich/ticket/2261 + * + * originally uncovered in Darshan: + * http://lists.mcs.anl.gov/pipermail/darshan-users/2015-February/000256.html + * + * to really exercise the bug in simple_collective, + * we'd have to run on a Lustre or Panasas file system. + * + * I am surprised src/mpi/romio/test/create_excl.c did not uncover the bug + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "simgrid/plugins/file_system.h" + +static char *opt_file = NULL; +static int rank = -1; + +static int parse_args(int argc, char **argv); +static void usage(const char *prog); +int test_write(char *file, int nprocs, int rank, MPI_Info info); +int test_write(char *file, int nprocs, int rank, MPI_Info info) +{ + double stime, etime, wtime, w_elapsed, w_slowest, elapsed, slowest; + MPI_File fh; + int ret; + char buffer[700] = { 0 }; + MPI_Status status; + int verbose = 0; + + MPI_Barrier(MPI_COMM_WORLD); + stime = MPI_Wtime(); + + ret = MPI_File_open(MPI_COMM_WORLD, file, + MPI_MODE_CREATE | MPI_MODE_WRONLY | MPI_MODE_EXCL, info, &fh); + + if (ret != 0) { + fprintf(stderr, "Error: failed to open %s\n", file); + return 1; + } + + etime = MPI_Wtime(); + + ret = MPI_File_write_at_all(fh, rank * 700, buffer, 700, MPI_BYTE, &status); + if (ret != 0) { + fprintf(stderr, "Error: failed to write %s\n", file); + return 1; + } + + wtime = MPI_Wtime(); + + MPI_File_close(&fh); + + elapsed = etime - stime; + w_elapsed = wtime - etime; + MPI_Reduce(&elapsed, &slowest, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); + MPI_Reduce(&w_elapsed, &w_slowest, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); + + if (rank == 0) { + //unlink(file); + //to emulate unlink, use sg_file_unlink + sg_file_t fd = sg_file_open(file, NULL); + sg_file_unlink(fd); + slowest *= 1000.0; + w_slowest *= 1000.0; + if (verbose == 1) { + printf("file: %s, nprocs: %d, open_time: %f ms, write_time: %f ms\n", + file, nprocs, slowest, w_slowest); + } + } + return 0; +} + +int main(int argc, char **argv) +{ + int nprocs; + char file[256]; + MPI_Info info; + int nr_errors = 0; + + + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + + /* parse the command line arguments */ + parse_args(argc, argv); + + sprintf(file, "%s", opt_file); + MPI_Info_create(&info); + nr_errors += test_write(file, nprocs, rank, info); + /* acutal value does not matter. test only writes a small amount of data */ + MPI_Info_set(info, "striping_factor", "50"); + nr_errors += test_write(file, nprocs, rank, info); + MPI_Info_free(&info); + + MPI_Finalize(); + if (!rank && nr_errors == 0) { + printf(" No Errors\n"); + } + return (-nr_errors); +} + +static int parse_args(int argc, char **argv) +{ + int c; + + while ((c = getopt(argc, argv, "e")) != EOF) { + switch (c) { + case 'h': + if (rank == 0) + usage(argv[0]); + exit(0); + case '?': /* unknown */ + if (rank == 0) + usage(argv[0]); + exit(1); + default: + break; + } + } + + if (argc - optind != 1) { + if (rank == 0) + usage(argv[0]); + exit(1); + } + + opt_file = strdup(argv[optind]); + assert(opt_file); + + return (0); +} + +static void usage(const char *prog) +{ + printf("Usage: %s [...] \n", prog); + printf("\n is one or more of\n"); + printf(" -h print this help\n"); +} + +/* + * vim: ts=8 sts=4 sw=4 noexpandtab + */ diff --git a/teshsuite/smpi/mpich3-test/io/testlist b/teshsuite/smpi/mpich3-test/io/testlist new file mode 100644 index 0000000000..43fb58881e --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/testlist @@ -0,0 +1,29 @@ +rdwrord 4 +rdwrzero 4 +#needs MPI_File_get_type_extent +#getextent 2 +setinfo 4 +#needs MPI_File_set_view +#setviewcur 4 +#i_noncontig 2 +#async 4 +#async_any 4 +userioerr 1 +#resized 1 +#resized2 1 +#bigtype 1 +#hindexed_io 1 +simple_collective 1 arg="/scratch/simple_collective.testfile" +#external32-derived-dtype 1 +#i_bigtype 1 mpiversion=3.1 +#i_hindexed_io 1 mpiversion=3.1 +#i_rdwrord 4 mpiversion=3.1 +#i_setviewcur 4 mpiversion=3.1 +#i_aggregation1 4 mpiversion=3.1 +#i_aggregation2 4 mpiversion=3.1 +#i_coll_test 4 mpiversion=3.1 +#i_darray_read 4 mpiversion=3.1 +#i_hindexed 4 mpiversion=3.1 +#i_noncontig_coll 2 mpiversion=3.1 +#i_noncontig_coll2 4 mpiversion=3.1 +#i_types_with_zeros 2 mpiversion=3.1 diff --git a/teshsuite/smpi/mpich3-test/io/userioerr.c b/teshsuite/smpi/mpich3-test/io/userioerr.c new file mode 100644 index 0000000000..5f390027d7 --- /dev/null +++ b/teshsuite/smpi/mpich3-test/io/userioerr.c @@ -0,0 +1,85 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ +/* + * + * (C) 2006 by Argonne National Laboratory. + * See COPYRIGHT in top-level directory. + */ +#include "mpi.h" +#include +#include "mpitest.h" +#include "mpitestconf.h" + +int verbose = 0; + +int handlerCalled = 0; + +/* Prototype to suppress compiler warnings */ +void user_handler(MPI_File * fh, int *errcode, ...); + +void user_handler(MPI_File * fh, int *errcode, ...) +{ + if (*errcode != MPI_SUCCESS) { + handlerCalled++; + if (verbose) { + printf("In user_handler with code %d\n", *errcode); + } + } +} + +int main(int argc, char *argv[]) +{ + int rank, errs = 0, rc; + MPI_Errhandler ioerr_handler; + MPI_Status status; + MPI_File fh; + char inbuf[80]; + + MTest_Init(&argc, &argv); + + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + + /* Create a file to which to attach the handler */ + rc = MPI_File_open(MPI_COMM_WORLD, (char *) "/scratch/test.txt", + MPI_MODE_CREATE | MPI_MODE_WRONLY | MPI_MODE_DELETE_ON_CLOSE, + MPI_INFO_NULL, &fh); + if (rc) { + errs++; + printf("Unable to open test.txt for writing\n"); + } + + rc = MPI_File_create_errhandler(user_handler, &ioerr_handler); + if (rc) { + errs++; + printf("MPI_File_create_Errhandler returned an error code: %d\n", rc); + } + + rc = MPI_File_set_errhandler(fh, ioerr_handler); + if (rc) { + errs++; + printf("MPI_File_set_errhandler returned an error code: %d\n", rc); + } + + /* avoid leaking the errhandler, safe because they have refcount semantics */ + rc = MPI_Errhandler_free(&ioerr_handler); + if (rc) { + errs++; + printf("MPI_Errhandler_free returned an error code: %d\n", rc); + } + + /* This should generate an error because the file mode is WRONLY */ + rc = MPI_File_read_at(fh, 0, inbuf, 80, MPI_BYTE, &status); + if (handlerCalled != 1) { + errs++; + printf("User-defined error handler was not called\n"); + } + + rc = MPI_File_close(&fh); + if (rc) { + errs++; + printf("MPI_File_close returned an error code: %d\n", rc); + } + + MTest_Finalize(errs); + MPI_Finalize(); + return 0; +} diff --git a/teshsuite/smpi/mpich3-test/runtests b/teshsuite/smpi/mpich3-test/runtests index 92cba949ff..3554d67433 100755 --- a/teshsuite/smpi/mpich3-test/runtests +++ b/teshsuite/smpi/mpich3-test/runtests @@ -43,6 +43,8 @@ use File::Path; $MPIMajorVersion = "3"; $MPIMinorVersion = "1"; $mpiexec = "smpirun"; # Name of mpiexec program (including path, if necessary) +$platformfile = "../../../../examples/platforms/small_platform_with_routers.xml"; +$hostfile = "../../hostfile_mpich"; $testIsStrict = "true"; $MPIhasMPIX = "no"; $np_arg = "-np"; # Name of argument to specify the number of processes @@ -156,8 +158,10 @@ foreach $_ (@ARGV) { elsif (/--?np=(.*)/) { $np_default = $1; } elsif (/--?maxnp=(.*)/) { $np_max = $1; } elsif (/--?tests=(.*)/) { $listfiles = $1; } + elsif (/--?platformfile=(.*)/) { $platformfile = $1; } + elsif (/--?hostfile=(.*)/) { $hostfile = $1; } elsif (/--?srcdir=(.*)/) { $srcdir = $1; - $mpiexec="$mpiexec -platform ${srcdir}/../../../../examples/platforms/small_platform_with_routers.xml -hostfile ${srcdir}/../../hostfile_mpich --log=root.thr:critical --cfg=smpi/host-speed:1e9 --cfg=smpi/async-small-thresh:65536"; } + $mpiexec="$mpiexec -platform ${srcdir}/$platformfile -hostfile ${srcdir}/$hostfile --log=root.thr:critical --cfg=smpi/host-speed:1e9 --cfg=smpi/async-small-thresh:65536"; } elsif (/--?verbose/) { $verbose = 1; } elsif (/--?showprogress/) { $showProgress = 1; } elsif (/--?debug/) { $debug = 1; } diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index 725e75df24..7d624b6970 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -1045,6 +1045,7 @@ set(CMAKEFILES_TXT teshsuite/smpi/mpich3-test/f90/rma/CMakeLists.txt teshsuite/smpi/mpich3-test/group/CMakeLists.txt teshsuite/smpi/mpich3-test/info/CMakeLists.txt + teshsuite/smpi/mpich3-test/io/CMakeLists.txt teshsuite/smpi/mpich3-test/init/CMakeLists.txt teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt teshsuite/smpi/mpich3-test/topo/CMakeLists.txt -- 2.20.1