Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add io test in mpich testsuite.
authorAugustin Degomme <adegomme@gmail.com>
Tue, 10 Dec 2019 16:01:35 +0000 (17:01 +0100)
committerAugustin Degomme <adegomme@gmail.com>
Tue, 10 Dec 2019 16:16:57 +0000 (17:16 +0100)
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.

38 files changed:
teshsuite/smpi/hostfile_io
teshsuite/smpi/io-all-at/io-all-at.tesh
teshsuite/smpi/io-all/io-all.tesh
teshsuite/smpi/io-ordered/io-ordered.tesh
teshsuite/smpi/io-shared/io-shared.tesh
teshsuite/smpi/io-simple-at/io-simple-at.tesh
teshsuite/smpi/io-simple/io-simple.tesh
teshsuite/smpi/mpich3-test/io/CMakeLists.txt [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/async.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/async_any.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/bigtype.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/external32-derived-dtype.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/getextent.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/hindexed_io.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_aggregation1.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_aggregation2.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_bigtype.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_coll_test.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_darray_read.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_hindexed.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_hindexed_io.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_noncontig.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_noncontig_coll.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_noncontig_coll2.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_rdwrord.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_setviewcur.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/i_types_with_zeros.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/rdwrord.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/rdwrzero.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/resized.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/resized2.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/setinfo.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/setviewcur.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/simple_collective.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/testlist [new file with mode: 0644]
teshsuite/smpi/mpich3-test/io/userioerr.c [new file with mode: 0644]
teshsuite/smpi/mpich3-test/runtests
tools/cmake/DefinePackages.cmake

index bda0caf..12bb588 100644 (file)
@@ -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
index 0c96e62..ffc8aeb 100644 (file)
@@ -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
index e7d779c..6a7082d 100644 (file)
@@ -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
index e5a56dd..ad8c201 100644 (file)
@@ -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
index 16f351e..8bb5d72 100644 (file)
@@ -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
index b1739bb..59c3f51 100644 (file)
@@ -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 (file)
index 0000000..23a5a2a
--- /dev/null
@@ -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 (file)
index 0000000..b2c5a33
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#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 (file)
index 0000000..00b37e8
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#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 (file)
index 0000000..760894c
--- /dev/null
@@ -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 <mpi.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+
+//#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 (file)
index 0000000..8391a22
--- /dev/null
@@ -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 <stdlib.h>
+#include <stdio.h>
+#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 (file)
index 0000000..a0ea76a
--- /dev/null
@@ -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 <stdio.h>
+#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 (file)
index 0000000..9af0db4
--- /dev/null
@@ -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 <mpi.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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 (file)
index 0000000..a201512
--- /dev/null
@@ -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 <unistd.h>
+#include <stdlib.h>
+#include <mpi.h>
+#include <stdio.h>
+#include <string.h>
+
+#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 (file)
index 0000000..0647c1b
--- /dev/null
@@ -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 <mpi.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string.h>
+
+#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 (file)
index 0000000..90d9234
--- /dev/null
@@ -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 <mpi.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+
+//#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 (file)
index 0000000..8562070
--- /dev/null
@@ -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 <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+/* 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 (file)
index 0000000..a6c3626
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+
+#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 (file)
index 0000000..1672e43
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mpi.h>
+
+#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 (file)
index 0000000..fbe4643
--- /dev/null
@@ -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 <mpi.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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 (file)
index 0000000..d1c9c73
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#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 (file)
index 0000000..d5ae7aa
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* 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 (file)
index 0000000..35466b4
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* 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 (file)
index 0000000..147edb6
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#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 (file)
index 0000000..3d0e2a0
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#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 (file)
index 0000000..70250fb
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include <mpi.h>
+
+#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 (file)
index 0000000..e8dc8e1
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#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 (file)
index 0000000..212fbf7
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#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 (file)
index 0000000..359c57c
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#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 (file)
index 0000000..a39524d
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#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 (file)
index 0000000..8e71b23
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+#include "mpitestconf.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#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 (file)
index 0000000..0b2a51b
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#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 (file)
index 0000000..82c3b4d
--- /dev/null
@@ -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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <mpi.h>
+#include <errno.h>
+#include <getopt.h>
+
+#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 [<OPTIONS>...] <FILE NAME>\n", prog);
+    printf("\n<OPTIONS> 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 (file)
index 0000000..43fb588
--- /dev/null
@@ -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 (file)
index 0000000..5f39002
--- /dev/null
@@ -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 <stdio.h>
+#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;
+}
index 92cba94..3554d67 100755 (executable)
@@ -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; }
index 725e75d..7d624b6 100644 (file)
@@ -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