summaryrefslogtreecommitdiffstats
path: root/testpar/t_posix_compliant.c
diff options
context:
space:
mode:
authorLeon Arber <larber@ncsa.uiuc.edu>2005-12-08 19:14:28 (GMT)
committerLeon Arber <larber@ncsa.uiuc.edu>2005-12-08 19:14:28 (GMT)
commit5e58d47b984b34f2527da3b538dde1f275ee2d3a (patch)
treec9d1e19516b27b9904724bd9f432626b0b7fbbba /testpar/t_posix_compliant.c
parent88c15b1617872ce1672d7333481a5aa32ee23d5a (diff)
downloadhdf5-5e58d47b984b34f2527da3b538dde1f275ee2d3a.zip
hdf5-5e58d47b984b34f2527da3b538dde1f275ee2d3a.tar.gz
hdf5-5e58d47b984b34f2527da3b538dde1f275ee2d3a.tar.bz2
[svn-r11772] Purpose:
Feature Description: Added posix compliance tests. Solution: These tests do increasingly complicated sets of writes followed by reads. POSIX standards say that any read that can be proven to occur after a write must include the data in that write. These tests attempt to verify whether the underlying filesystem and i/o layer provide such guarantees. Platforms tested: copper, colonelk, red storm Misc. update:
Diffstat (limited to 'testpar/t_posix_compliant.c')
-rw-r--r--testpar/t_posix_compliant.c847
1 files changed, 847 insertions, 0 deletions
diff --git a/testpar/t_posix_compliant.c b/testpar/t_posix_compliant.c
new file mode 100644
index 0000000..d077680
--- /dev/null
+++ b/testpar/t_posix_compliant.c
@@ -0,0 +1,847 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* A series of tests for posix compliance
+ *
+ * These tests do increasingly complicated sets of writes followed by reads.
+ * POSIX standards say that any read that can be proven to occur after a write
+ * must include the data in that write. These tests attempt to verify whether the
+ * underlying filesystem and i/o layer provide such guarantees.
+ *
+ * There are two sets of tests, one which uses POSIX i/o (fread, fwrite) and one which
+ * uses MPI I/O (MPI_File_read, MPI_File_write). Each set has multiple sub-tests, which
+ * test varying patters of writes and reads.
+ *
+ * Leon Arber
+ * larber@ncsa.uiuc.edu
+*/
+
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+
+char* testfile = NULL;
+int err_flag = 0;
+int max_err_print = 5;
+
+#define CHECK_SUCCESS(res) \
+{ \
+ char err_got[MPI_MAX_ERROR_STRING]; \
+ int err_len; \
+ if(res != MPI_SUCCESS) \
+ { \
+ MPI_Error_string(res, err_got, &err_len); \
+ fprintf(stderr, "Line %d, Error: %s\n", __LINE__, err_got); \
+ MPI_Abort(MPI_COMM_WORLD, -2); \
+ } \
+}
+
+#define PRINT_RESULT() \
+{ \
+ int err_result; \
+ MPI_Reduce(&err_flag, &err_result, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD); \
+ if( (rank == 0) && (err_result == 0) ) \
+ printf("PASSED\n"); \
+ fflush(stdout); \
+ fflush(stderr); \
+ err_flag = 0; \
+}
+
+void vrfy_elements(int* a, int* b, int size, int rank);
+int find_writesize(int rank, int numprocs, int write_size);
+
+
+/* All writes are to non-overlapping locations in the file
+ * Then, each task reads another tasks' data
+ * */
+
+int allwrite_allread_blocks(int numprocs, int rank, int write_size)
+{
+ MPI_File fh = MPI_FILE_NULL;
+ int mpio_result;
+ int amode, i;
+ MPI_Info hints_to_test = MPI_INFO_NULL;
+ MPI_Offset offset = rank*write_size*sizeof(int);
+ MPI_Status Status;
+ int* writebuf = (int*)malloc(write_size*sizeof(int));
+ int* readbuf = (int*)malloc (write_size*sizeof(int));
+
+ for(i=0; i<write_size; i++)
+ writebuf[i] = i;
+
+ amode = MPI_MODE_CREATE | MPI_MODE_RDWR | MPI_MODE_DELETE_ON_CLOSE;
+
+ mpio_result = MPI_File_open(MPI_COMM_WORLD, testfile, amode,
+ MPI_INFO_NULL, &fh);
+ CHECK_SUCCESS(mpio_result);
+
+ mpio_result = MPI_File_write_at(fh, offset, writebuf, write_size, MPI_INT, &Status);
+ CHECK_SUCCESS(mpio_result);
+
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ offset = ( (rank+(numprocs-1)) % numprocs)*write_size*sizeof(int);
+
+ mpio_result = MPI_File_read_at(fh, offset, readbuf, write_size, MPI_INT, &Status);
+ CHECK_SUCCESS(mpio_result);
+
+ vrfy_elements(writebuf, readbuf, write_size, rank);
+
+ mpio_result = MPI_File_close(&fh);
+ CHECK_SUCCESS(mpio_result);
+ free(writebuf);
+ free(readbuf);
+
+ return err_flag;
+
+}
+
+int posix_allwrite_allread_blocks(int numprocs, int rank, int write_size)
+{
+ int ret;
+ int amode, i;
+ int offset = rank*write_size*sizeof(int);
+ int* writebuf = (int*)malloc(write_size*sizeof(int));
+ int* readbuf = (int*)malloc (write_size*sizeof(int));
+ FILE* file = NULL;
+
+ for(i=0; i<write_size; i++)
+ writebuf[i] = i;
+
+ if(rank==0)
+ file = fopen(testfile, "w+");
+ MPI_Barrier(MPI_COMM_WORLD);
+ if(rank != 0)
+ file = fopen(testfile, "r+");
+
+ if(file == NULL)
+ {
+ fprintf(stderr, "Could not create testfile\n");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ ret = fseek(file, offset, SEEK_SET);
+ if(ret == -1)
+ {
+ perror("fseek");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+
+ ret = fwrite(writebuf, sizeof(int), write_size, file);
+ if(ret != write_size)
+ {
+ perror("fwrite");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ offset = ( (rank+(numprocs-1)) % numprocs)*write_size*sizeof(int);
+
+ ret = fseek(file, offset, SEEK_SET);
+ if(ret == -1)
+ {
+ perror("fseek");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ ret = fread(readbuf, sizeof(int), write_size, file);
+ if( (ret == 0) && feof(file))
+ printf("Process %d: Error. Prematurely reached end of file\n", rank);
+ else if( (ret != write_size) && ferror(file))
+ {
+ perror("Error encountered in fread");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ vrfy_elements(writebuf, readbuf, write_size, rank);
+
+ fclose(file);
+
+ MPI_Barrier(MPI_COMM_WORLD);
+ if(rank == 0)
+ unlink(testfile);
+
+ free(writebuf);
+ free(readbuf);
+ return err_flag;
+
+}
+
+int posix_onewrite_allread_blocks(int numprocs, int rank, int write_size)
+{
+ int ret;
+ int amode, i;
+ int offset = rank*write_size*sizeof(int);
+ int* writebuf = (int*)malloc(write_size*sizeof(int));
+ int* readbuf = (int*)malloc (write_size*sizeof(int));
+ FILE* file = NULL;
+
+ for(i=0; i<write_size; i++)
+ writebuf[i] = i;
+
+ if(rank==0)
+ file = fopen(testfile, "w+");
+ MPI_Barrier(MPI_COMM_WORLD);
+ if(rank != 0)
+ file = fopen(testfile, "r+");
+
+ if(file == NULL)
+ {
+ fprintf(stderr, "Could not create testfile\n");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ if(rank == 0)
+ {
+ for(offset = 0; offset<numprocs*write_size*sizeof(int); offset+=(write_size*sizeof(int)))
+ {
+ ret = fseek(file, offset, SEEK_SET);
+ if(ret == -1)
+ {
+ perror("fseek");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+
+ ret = fwrite(writebuf, sizeof(int), write_size, file);
+ if(ret != write_size)
+ {
+ perror("fwrite");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+ }
+
+ }
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ offset = rank*write_size*sizeof(int);
+
+ ret = fseek(file, offset, SEEK_SET);
+ if(ret == -1)
+ {
+ perror("fseek");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ ret = fread(readbuf, sizeof(int), write_size, file);
+ if( (ret == 0) && feof(file))
+ printf("Process %d: Error. Prematurely reached end of file\n", rank);
+ else if( (ret != write_size) && ferror(file))
+ {
+ perror("Error encountered in fread");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ vrfy_elements(writebuf, readbuf, write_size, rank);
+
+ fclose(file);
+
+ MPI_Barrier(MPI_COMM_WORLD);
+ if(rank == 0)
+ unlink(testfile);
+
+ free(writebuf);
+ free(readbuf);
+ return err_flag;
+
+}
+
+int posix_onewrite_allread_interlaced(int numprocs, int rank, int write_size)
+{
+ int ret;
+ int amode, i, fill, index;
+ int offset = rank*write_size*sizeof(int);
+ int* writebuf = (int*)malloc(write_size*sizeof(int));
+ int* readbuf = (int*)malloc (write_size*sizeof(int));
+ FILE* file = NULL;
+
+ if(rank==0)
+ file = fopen(testfile, "w+");
+ MPI_Barrier(MPI_COMM_WORLD);
+ if(rank != 0)
+ file = fopen(testfile, "r+");
+
+ if(file == NULL)
+ {
+ fprintf(stderr, "Could not create testfile\n");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ if(rank == 0)
+ {
+ for(offset = 0; offset<numprocs*write_size*sizeof(int); offset+=(numprocs*sizeof(int)))
+ {
+ ret = fseek(file, offset, SEEK_SET);
+ if(ret == -1)
+ {
+ perror("fseek");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ fill = offset / (numprocs*sizeof(int));
+ for(i=0; i<numprocs; i++)
+ writebuf[i] = fill;
+
+
+ ret = fwrite(writebuf, sizeof(int), numprocs, file);
+ if(ret != numprocs)
+ {
+ perror("fwrite");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+ }
+
+ }
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ index = 0;
+ for(offset = rank*sizeof(int); offset<numprocs*write_size*sizeof(int); offset+=(numprocs*sizeof(int)))
+ {
+
+ ret = fseek(file, offset, SEEK_SET);
+ if(ret == -1)
+ {
+ perror("fseek");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ ret = fread(readbuf+index, sizeof(int), 1, file);
+ if( (ret == 0) && feof(file))
+ printf("Process %d: Error. Prematurely reached end of file\n", rank);
+ else if( (ret != 1) && ferror(file))
+ {
+ perror("Error encountered in fread");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ index++;
+ }
+
+ for(i=0; i<write_size; i++)
+ writebuf[i] = i;
+
+ vrfy_elements(writebuf, readbuf, write_size, rank);
+
+ fclose(file);
+
+ MPI_Barrier(MPI_COMM_WORLD);
+ if(rank == 0)
+ unlink(testfile);
+
+ free(writebuf);
+ free(readbuf);
+ return err_flag;
+
+}
+/* Each proc wites out 0 1 2 3 with displacement i, so file contents are:
+ * 0000 1111 2222 3333 etc. (with 4 procs)
+ *
+ * Each proc then reads in the whole file and verifies that the data is what it is supposed to be*/
+
+int allwrite_allread_interlaced(int numprocs, int rank, int write_size)
+{
+ MPI_File fh = MPI_FILE_NULL;
+ int mpio_result;
+ int amode, i, counter = 0;
+ MPI_Info hints_to_test = MPI_INFO_NULL;
+ MPI_Datatype filetype, contig;
+ MPI_Status Status;
+ int* writebuf = (int*)malloc(write_size*sizeof(int));
+ int* readbuf = (int*) malloc(numprocs*sizeof(int));
+ int offset=0;
+
+ for(i=0; i<write_size; i++)
+ writebuf[i] = i;
+
+
+ amode = MPI_MODE_CREATE | MPI_MODE_RDWR | MPI_MODE_DELETE_ON_CLOSE;
+ mpio_result = MPI_File_open(MPI_COMM_WORLD, testfile, amode, MPI_INFO_NULL, &fh);
+ CHECK_SUCCESS(mpio_result);
+
+ mpio_result = MPI_Type_vector(write_size, 1, numprocs, MPI_INT, &filetype);
+ CHECK_SUCCESS(mpio_result);
+
+ mpio_result = MPI_Type_commit(&filetype);
+ CHECK_SUCCESS(mpio_result);
+
+ mpio_result = MPI_File_set_view(fh, rank*sizeof(int), MPI_INT, filetype, "native", MPI_INFO_NULL);
+ CHECK_SUCCESS(mpio_result);
+
+ mpio_result = MPI_File_write(fh, writebuf, write_size, MPI_INT, &Status);
+ CHECK_SUCCESS(mpio_result);
+
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ mpio_result = MPI_File_set_view(fh, 0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL);
+ CHECK_SUCCESS(mpio_result);
+
+ for(offset = 0; offset<(write_size*numprocs*sizeof(int)); offset+=(numprocs*sizeof(int)))
+ {
+ mpio_result = MPI_File_read_at(fh, offset, readbuf, numprocs, MPI_INT, &Status);
+ CHECK_SUCCESS(mpio_result);
+
+ for(i=0; i<numprocs; i++)
+ {
+ if(writebuf[offset/(numprocs*sizeof(int))] != readbuf[i])
+ {
+ if( (rank == 0) && (counter == 0))
+ printf("\n");
+ if(counter++ < max_err_print)
+ fprintf(stderr, "Arrays do not match! Prcoess %d, element %d: [%d, %d]\n", rank, i, writebuf[offset/(numprocs*sizeof(int))], readbuf[i]);
+ else if(counter++ == max_err_print+1)
+ fprintf(stderr, "Printed %d errors. Omitting the rest\n", max_err_print);
+ err_flag = -1;
+ }
+
+ }
+ }
+ mpio_result = MPI_File_close(&fh);
+ CHECK_SUCCESS(mpio_result);
+
+ free(writebuf);
+ free(readbuf);
+ return err_flag;
+
+
+}
+
+/* Overlapping pattern works as follows (this test requires at least 2 procs:
+ * Writes:
+ * Task 0: 0 2 4 6 etc...
+ * Task 1: 1 3 5 7 etc...
+ * Task 2: 0 3 6 etc..
+ * Task 3: 0 4 8 etc...
+ *
+ * The above describes only the pattern of the elements being written. The actual
+ * number of elements written is going to be:
+ *
+ * Task i where i=(numprocs-1) writes write_size elements. All other tasks do:
+ * x = ((write_size-1)*numprocs)
+ * Task i's write_size is the smallest multiple of i<=x divided by i, with the exception
+ * of tasks 0 and 1, for whom i is 2, since they are writing the even and odd multiples.
+ *
+ * So, if there are 5 tasks with write_size=4, the resulting pattern of writes is:
+ *
+ * Task 0: 0 2 4 6 8 10 12 14
+ * Task 1: 1 3 5 7 9 11 13 15
+ * Task 2: 0 3 6 9 12 15
+ * Task 3: 0 4 8 12
+ * Task 4: 0 5 10 15
+ *
+ *
+ *
+ * * * All the entires that overlap will therefore be writing the same value
+ *
+ * At the end, all tasks read in the file and verify that it is correct should be
+ * (1,2...((numprocs-1)*WRTE_SIZE).
+ * */
+
+int allwrite_allread_overlap(int numprocs, int rank, int write_size)
+{
+
+ MPI_File fh = MPI_FILE_NULL;
+ int mpio_result;
+ int amode, i, counter = 0;
+ MPI_Info hints_to_test = MPI_INFO_NULL;
+ MPI_Datatype filetype, contig;
+ MPI_Status Status;
+ int* writebuf = (int*) malloc(write_size*(numprocs-1)*sizeof(int)); /* An upper bound...not all the elements will be written */
+ int* readbuf = (int*) malloc(write_size*(numprocs-1)*sizeof(int));
+
+ if(numprocs < 2)
+ {
+ fprintf(stderr, "The allwrite_allread_overlap test requires at least 2 procs\n");
+ return -1;
+ }
+
+ if(rank == 0)
+ {
+ for(i=0; i<write_size*(numprocs-1); i++)
+ writebuf[i] = 2*i;
+ }
+ else if(rank == 1)
+ {
+ for(i=0; i<write_size*(numprocs-1); i++)
+ writebuf[i] = (2*i)+1;
+ }
+ else
+ {
+ for(i=0; i<write_size*(numprocs-1); i++)
+ writebuf[i] = (rank+1)*i;
+ }
+
+ amode = MPI_MODE_CREATE | MPI_MODE_RDWR | MPI_MODE_DELETE_ON_CLOSE;
+ mpio_result = MPI_File_open(MPI_COMM_WORLD, testfile, amode, MPI_INFO_NULL, &fh);
+ CHECK_SUCCESS(mpio_result);
+
+ if( (rank == 0) || (rank == 1) )
+ mpio_result = MPI_Type_vector(write_size*(numprocs-1), 1, 2, MPI_INT, &filetype);
+ else
+ mpio_result = MPI_Type_vector(write_size*(numprocs-1), 1, rank+1, MPI_INT, &filetype);
+ CHECK_SUCCESS(mpio_result);
+
+ mpio_result = MPI_Type_commit(&filetype);
+ CHECK_SUCCESS(mpio_result);
+
+ if( rank == 1)
+ mpio_result = MPI_File_set_view(fh, sizeof(int), MPI_INT, filetype, "native", MPI_INFO_NULL);
+ else
+ mpio_result = MPI_File_set_view(fh, 0, MPI_INT, filetype, "native", MPI_INFO_NULL);
+ CHECK_SUCCESS(mpio_result);
+
+ if( rank == (numprocs - 1))
+ mpio_result = MPI_File_write(fh, writebuf, write_size, MPI_INT, &Status);
+ else
+ mpio_result = MPI_File_write(fh, writebuf, find_writesize(rank, numprocs, write_size), MPI_INT, &Status);
+
+ CHECK_SUCCESS(mpio_result);
+
+ MPI_Barrier(MPI_COMM_WORLD);
+ mpio_result = MPI_File_set_view(fh, 0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL);
+ CHECK_SUCCESS(mpio_result);
+
+ mpio_result = MPI_File_read_at(fh, 0, readbuf, write_size*(numprocs-1), MPI_INT, &Status);
+ CHECK_SUCCESS(mpio_result);
+
+ for(i=0; i<write_size*(numprocs-1); i++)
+ {
+ if(i != readbuf[i])
+ {
+ if( (rank == 0) && (counter == 0))
+ printf("\n");
+ if(counter++ < max_err_print)
+ fprintf(stderr, "Arrays do not match! Prcoess %d, element %d: [%d, %d]\n", rank, i, i, readbuf[i]);
+ else if(counter++ == max_err_print+1)
+ fprintf(stderr, "Printed %d errors. Omitting the rest\n", max_err_print);
+ err_flag = -1;
+ }
+ }
+
+ mpio_result = MPI_File_close(&fh);
+ CHECK_SUCCESS(mpio_result);
+ free(writebuf);
+ free(readbuf);
+
+ return err_flag;
+
+}
+
+/* A random process writes out the following to the file:
+ * 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 (assuming write_size=5, and numprocs=3)
+ *
+ * Process i read's in write_size bytes at offset=i*write_size
+ */
+int onewrite_allread_blocks(int numprocs, int rank, int write_size)
+{
+ MPI_File fh = MPI_FILE_NULL;
+ int mpio_result;
+ int amode, i;
+ MPI_Info hints_to_test = MPI_INFO_NULL;
+ MPI_Offset offset = rank*write_size*sizeof(int);
+ MPI_Status Status;
+ int* writebuf = (int*)malloc(write_size*sizeof(int));
+ int* readbuf = (int*)malloc (write_size*sizeof(int));
+
+ for(i=0; i<write_size; i++)
+ writebuf[i] = i;
+
+ amode = MPI_MODE_CREATE | MPI_MODE_RDWR | MPI_MODE_DELETE_ON_CLOSE;
+
+ mpio_result = MPI_File_open(MPI_COMM_WORLD, testfile, amode,
+ MPI_INFO_NULL, &fh);
+ CHECK_SUCCESS(mpio_result);
+
+ /* A random process writes out all the data */
+ if(rank == (rand() % numprocs))
+ {
+ for(i=0; i<numprocs; i++)
+ {
+ mpio_result = MPI_File_write_at(fh, write_size*i*sizeof(int), writebuf, write_size, MPI_INT, &Status);
+ CHECK_SUCCESS(mpio_result);
+ }
+ }
+
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ mpio_result = MPI_File_read_at(fh, write_size*rank*sizeof(int), readbuf, write_size, MPI_INT, &Status);
+ CHECK_SUCCESS(mpio_result);
+
+ vrfy_elements(writebuf, readbuf, write_size, rank);
+
+ mpio_result = MPI_File_close(&fh);
+ CHECK_SUCCESS(mpio_result);
+ free(writebuf);
+ free(readbuf);
+
+ return err_flag;
+
+
+
+}
+
+/* Process zero writes out:
+ * 0000 1111 2222 3333 etc. (with 4 procs)
+ *
+ * Each proc reads out 0 1 2 3 starting at displacement i */
+int onewrite_allread_interlaced(int numprocs, int rank, int write_size)
+{
+ MPI_File fh = MPI_FILE_NULL;
+ int mpio_result;
+ int amode, i;
+ MPI_Info hints_to_test = MPI_INFO_NULL;
+ MPI_Datatype filetype, contig;
+ MPI_Status Status;
+ int* writebuf = (int*) malloc(numprocs*write_size*sizeof(int)); /* Upper bound, not all used */
+ int* readbuf = (int*)malloc (write_size*sizeof(int));
+
+
+ amode = MPI_MODE_CREATE | MPI_MODE_RDWR;
+ amode = MPI_MODE_CREATE | MPI_MODE_RDWR | MPI_MODE_DELETE_ON_CLOSE;
+ mpio_result = MPI_File_open(MPI_COMM_WORLD, testfile, amode, MPI_INFO_NULL, &fh);
+ CHECK_SUCCESS(mpio_result);
+
+ mpio_result = MPI_Type_vector(write_size, 1, numprocs, MPI_INT, &filetype);
+ CHECK_SUCCESS(mpio_result);
+
+ mpio_result = MPI_Type_commit(&filetype);
+ CHECK_SUCCESS(mpio_result);
+
+ if(rank == (rand() % numprocs))
+ {
+ for(i=0; i<write_size; i++)
+ {
+ int j;
+ for(j=0; j<numprocs; j++)
+ writebuf[j] = i;
+
+ mpio_result = MPI_File_write_at(fh, i*numprocs*sizeof(int), writebuf, numprocs, MPI_INT, &Status);
+ CHECK_SUCCESS(mpio_result);
+ }
+ }
+
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ mpio_result = MPI_File_set_view(fh, rank*sizeof(int), MPI_INT, filetype, "native", MPI_INFO_NULL);
+ CHECK_SUCCESS(mpio_result);
+
+ mpio_result = MPI_File_read_at(fh, 0, readbuf, write_size, MPI_INT, &Status);
+ CHECK_SUCCESS(mpio_result);
+
+ for(i=0; i<write_size; i++)
+ writebuf[i] = i;
+
+ vrfy_elements(writebuf, readbuf, write_size, rank);
+
+ mpio_result = MPI_File_close(&fh);
+ CHECK_SUCCESS(mpio_result);
+ free(writebuf);
+ free(readbuf);
+
+ return err_flag;
+
+}
+
+main(int argc, char* argv[])
+{
+
+ int numprocs, rank, opt, mpi_tests=1, posix_tests=1;
+ int lb, ub, inc;
+ err_flag = 0;
+ int write_size = 0;
+ char optstring[] = "h x m p: s: v:";
+
+ err_flag = 0;
+ testfile = (char*) malloc(strlen("posix_test")+1);
+ memset(testfile, 0, strlen("posix_test")+1);
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ while((opt = getopt(argc, argv, optstring)) != -1)
+ {
+ switch(opt)
+ {
+ case 'h':
+ if(rank == 0)
+ printf("Usage: %s [options]\n"
+ "-h prints this help message\n"
+ "-x run the posix i/o tests ONLY (default: posix and MPI)\n"
+ "-m run the mpi i/o tests ONLY (default: posix and MPI)\n"
+ "-s size Run the test for the specific size. Default is 1024, 4096, 16384, ..., 1048576\n"
+ "-p path specifies path for test file. Default is current directory\n"
+ "-v num Specifies number of unmatching entries to print (default 10, pass -1 for all)\n", argv[0]);
+ goto done;
+ case 'x':
+ mpi_tests = 0;
+ posix_tests = 1;
+ break;
+ case 'm':
+ mpi_tests = 1;
+ posix_tests = 1;
+ break;
+ case 'p':
+ testfile = (char*) realloc(testfile, strlen(optarg) + 1 + strlen("posix_test"));
+ strcpy(testfile, optarg);
+ /* Append a / just in case they didn't end their path with one */
+ strcat(testfile, "/");
+ break;
+ case 's':
+ write_size = atoi(optarg);
+ break;
+ case 'v':
+ max_err_print = atoi(optarg);
+ break;
+ }
+ }
+
+ strcat(testfile, "posix_test");
+
+ if( (optind < argc) && (rank == 0))
+ fprintf(stderr, "Unkown command-line argument passed. Continuing anyway...\n");
+
+ if(write_size == 0)
+ {
+ lb = 1024;
+ ub = 1024*1024;
+ inc = 4;
+ }
+ else
+ {
+ lb = write_size;
+ ub = write_size+1;
+ inc = 2;
+ }
+
+ for(write_size = lb; write_size <= ub; write_size*=inc)
+ {
+ if(rank == 0)
+ printf("\nTesting size %d\n", write_size);
+
+ if(mpi_tests)
+ {
+ if(rank == 0)
+ printf("Testing allwrite_allread_blocks with MPI IO\t\t"); fflush(stdout);
+ allwrite_allread_blocks(numprocs, rank, write_size/(numprocs*sizeof(int)));
+ PRINT_RESULT();
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ if(rank == 0)
+ printf("Testing allwrite_allread_interlaced with MPI IO\t\t"); fflush(stdout);
+ allwrite_allread_interlaced(numprocs, rank, write_size/(numprocs*sizeof(int)));
+ PRINT_RESULT();
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ if(rank == 0)
+ printf("Testing allwrite_allread_overlap with MPI IO\t\t"); fflush(stdout);
+ allwrite_allread_overlap(numprocs, rank, write_size);
+ PRINT_RESULT();
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ if(rank == 0)
+ printf("Testing onewrite_allread_blocks with MPI IO\t\t"); fflush(stdout);
+ onewrite_allread_blocks(numprocs, rank, write_size/(numprocs*sizeof(int)));
+ PRINT_RESULT();
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ if(rank == 0)
+ printf("Testing onewrite_allread_interlaced with MPI IO\t\t"); fflush(stdout);
+ onewrite_allread_interlaced(numprocs, rank, write_size/(numprocs*sizeof(int)));
+ PRINT_RESULT();
+ MPI_Barrier(MPI_COMM_WORLD);
+ }
+
+ if(posix_tests)
+ {
+ if(rank == 0)
+ printf("Testing allwrite_allread_blocks with POSIX IO\t\t"); fflush(stdout);
+ posix_allwrite_allread_blocks(numprocs, rank, write_size/(numprocs*sizeof(int)));
+ PRINT_RESULT();
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ if(rank == 0)
+ printf("Testing onewrite_allread_blocks with POSIX IO\t\t"); fflush(stdout);
+ posix_onewrite_allread_blocks(numprocs, rank, write_size/(numprocs*sizeof(int)));
+ PRINT_RESULT();
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ if(rank == 0)
+ printf("Testing onewrite_allread_interlaced with POSIX IO\t"); fflush(stdout);
+ posix_onewrite_allread_interlaced(numprocs, rank, write_size/(numprocs*sizeof(int)));
+ PRINT_RESULT();
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ /* if(rank == 0)
+ printf("Testing allwrite_allread_overlap with POSIX IO\t\t"); fflush(stdout);
+ posix_allwrite_allread_overlap(numprocs, rank, write_size);
+ PRINT_RESULT();
+ MPI_Barrier(MPI_COMM_WORLD);
+*/
+ }
+ }
+done:
+ MPI_Barrier(MPI_COMM_WORLD);
+ MPI_Finalize();
+
+ return err_flag;
+}
+
+
+
+int find_writesize(int rank, int numprocs, int size)
+{
+ /* Largest number in the file */
+ int tmp = (size-1)*numprocs;
+ int x = 0;
+ int write_size = 0;
+
+ /* Find largest multiple not greater than tmp */
+ while(x <= tmp)
+ {
+ if( (rank == 0) || (rank == 1) )
+ x+=2;
+ else
+ x += (rank+1);
+
+ write_size++;
+ }
+
+ return write_size;
+}
+
+void vrfy_elements(int* a, int* b, int size, int rank)
+{
+ int i, counter = 0;
+
+ for(i=0; i<size; i++)
+ {
+ if(a[i] != b[i])
+ {
+ if( (rank == 0) && (counter == 0))
+ printf("\n");
+ if(counter++ < max_err_print)
+ fprintf(stderr, "Arrays do not match! Prcoess %d, element %d: [%d, %d]\n", rank, i, a[i], b[i]);
+ else if(counter++ == max_err_print+1)
+ fprintf(stderr, "Printed %d errors. Omitting the rest\n", max_err_print);
+ err_flag = -1;
+ }
+ }
+ fflush(stderr);
+ fflush(stdout);
+}