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.
# 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
# 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
# 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
# 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
# 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
# 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
--- /dev/null
+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)
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <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;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <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;
+}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ *
+ * (C) 2003 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include "mpitest.h"
+
+/*
+static char MTEST_Descrip[] = "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;
+}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- 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);
+}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- 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);
+}
--- /dev/null
+/* -*- 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]
+
+*/
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <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;
+}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- 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;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ *
+ * (C) 2003 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+/*
+static char MTEST_Descrip[] = "Test 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;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ *
+ * (C) 2003 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+#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;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2008 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "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;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ * (C) 2008 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "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;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ *
+ * (C) 2003 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+#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;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
+/*
+ *
+ * (C) 2003 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ */
+#include "mpi.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpitest.h"
+
+/*
+static char MTEST_Descrip[] = "Test 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;
+}
--- /dev/null
+/* -*- 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
+ */
--- /dev/null
+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
--- /dev/null
+/* -*- 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;
+}
$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
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; }
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