mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-27 02:10:55 +08:00
[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:
This commit is contained in:
parent
88c15b1617
commit
5e58d47b98
847
testpar/t_posix_compliant.c
Normal file
847
testpar/t_posix_compliant.c
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user