Moved generic IOR information to "hint" structure. Backends should only use the "hints" if set.

master
Julian M. Kunkel 2020-05-31 12:50:03 +01:00
parent 8098c3740a
commit 5663593919
8 changed files with 186 additions and 155 deletions

View File

@ -82,7 +82,7 @@
/**************************** P R O T O T Y P E S *****************************/ /**************************** P R O T O T Y P E S *****************************/
static IOR_offset_t SeekOffset(void *, IOR_offset_t, aiori_mod_opt_t *); static IOR_offset_t SeekOffset(void *, IOR_offset_t, aiori_mod_opt_t *);
static void SetupDataSet(void *, aiori_mod_opt_t *); static void SetupDataSet(void *, int flags, aiori_mod_opt_t *);
static aiori_fd_t *HDF5_Create(char *, int flags, aiori_mod_opt_t *); static aiori_fd_t *HDF5_Create(char *, int flags, aiori_mod_opt_t *);
static aiori_fd_t *HDF5_Open(char *, int flags, aiori_mod_opt_t *); static aiori_fd_t *HDF5_Open(char *, int flags, aiori_mod_opt_t *);
static IOR_offset_t HDF5_Xfer(int, aiori_fd_t *, IOR_size_t *, static IOR_offset_t HDF5_Xfer(int, aiori_fd_t *, IOR_size_t *,
@ -93,7 +93,7 @@ static char* HDF5_GetVersion();
static void HDF5_Fsync(aiori_fd_t *, aiori_mod_opt_t *); static void HDF5_Fsync(aiori_fd_t *, aiori_mod_opt_t *);
static IOR_offset_t HDF5_GetFileSize(aiori_mod_opt_t *, MPI_Comm, char *); static IOR_offset_t HDF5_GetFileSize(aiori_mod_opt_t *, MPI_Comm, char *);
static int HDF5_Access(const char *, int, aiori_mod_opt_t *); static int HDF5_Access(const char *, int, aiori_mod_opt_t *);
static void HDF5_init_xfer_options(IOR_param_t * params); static void HDF5_init_xfer_options(aiori_xfer_hint_t * params);
static int HDF5_check_params(aiori_mod_opt_t * options); static int HDF5_check_params(aiori_mod_opt_t * options);
/************************** O P T I O N S *****************************/ /************************** O P T I O N S *****************************/
@ -147,7 +147,7 @@ ior_aiori_t hdf5_aiori = {
.close = HDF5_Close, .close = HDF5_Close,
.delete = HDF5_Delete, .delete = HDF5_Delete,
.get_version = HDF5_GetVersion, .get_version = HDF5_GetVersion,
.init_xfer_options = HDF5_init_xfer_options, .xfer_hints = HDF5_init_xfer_options,
.fsync = HDF5_Fsync, .fsync = HDF5_Fsync,
.get_file_size = HDF5_GetFileSize, .get_file_size = HDF5_GetFileSize,
.statfs = aiori_posix_statfs, .statfs = aiori_posix_statfs,
@ -167,10 +167,10 @@ hid_t memDataSpace; /* memory data space id */
int newlyOpenedFile; /* newly opened file */ int newlyOpenedFile; /* newly opened file */
/***************************** F U N C T I O N S ******************************/ /***************************** F U N C T I O N S ******************************/
static IOR_param_t * ior_param = NULL; static aiori_xfer_hint_t * hints = NULL;
static void HDF5_init_xfer_options(IOR_param_t * params){ static void HDF5_init_xfer_options(aiori_xfer_hint_t * params){
ior_param = params; hints = params;
} }
static int HDF5_check_params(aiori_mod_opt_t * options){ static int HDF5_check_params(aiori_mod_opt_t * options){
@ -265,7 +265,7 @@ static aiori_fd_t *HDF5_Open(char *testFileName, int flags, aiori_mod_opt_t * pa
* someday HDF5 implementation will allow subsets of MPI_COMM_WORLD * someday HDF5 implementation will allow subsets of MPI_COMM_WORLD
*/ */
/* store MPI communicator info for the file access property list */ /* store MPI communicator info for the file access property list */
if (ior_param->filePerProc) { if (hints->filePerProc) {
comm = MPI_COMM_SELF; comm = MPI_COMM_SELF;
} else { } else {
comm = testComm; comm = testComm;
@ -304,8 +304,8 @@ static aiori_fd_t *HDF5_Open(char *testFileName, int flags, aiori_mod_opt_t * pa
#endif #endif
/* open file */ /* open file */
if(! ior_param->dryRun){ if(! hints->dryRun){
if (ior_param->open == WRITE) { /* WRITE */ if (flags & IOR_CREAT) { /* WRITE */
*fd = H5Fcreate(testFileName, H5F_ACC_TRUNC, createPropList, accessPropList); *fd = H5Fcreate(testFileName, H5F_ACC_TRUNC, createPropList, accessPropList);
HDF5_CHECK(*fd, "cannot create file"); HDF5_CHECK(*fd, "cannot create file");
} else { /* READ or CHECK */ } else { /* READ or CHECK */
@ -365,7 +365,7 @@ static aiori_fd_t *HDF5_Open(char *testFileName, int flags, aiori_mod_opt_t * pa
HDF5_CHECK(xferPropList, "cannot create transfer property list"); HDF5_CHECK(xferPropList, "cannot create transfer property list");
/* set data transfer mode */ /* set data transfer mode */
if (ior_param->collective) { if (hints->collective) {
HDF5_CHECK(H5Pset_dxpl_mpio(xferPropList, H5FD_MPIO_COLLECTIVE), HDF5_CHECK(H5Pset_dxpl_mpio(xferPropList, H5FD_MPIO_COLLECTIVE),
"cannot set collective data transfer mode"); "cannot set collective data transfer mode");
} else { } else {
@ -377,9 +377,9 @@ static aiori_fd_t *HDF5_Open(char *testFileName, int flags, aiori_mod_opt_t * pa
/* set up memory data space for transfer */ /* set up memory data space for transfer */
memStart[0] = (hsize_t) 0; memStart[0] = (hsize_t) 0;
memCount[0] = (hsize_t) 1; memCount[0] = (hsize_t) 1;
memStride[0] = (hsize_t) (ior_param->transferSize / sizeof(IOR_size_t)); memStride[0] = (hsize_t) (hints->transferSize / sizeof(IOR_size_t));
memBlock[0] = (hsize_t) (ior_param->transferSize / sizeof(IOR_size_t)); memBlock[0] = (hsize_t) (hints->transferSize / sizeof(IOR_size_t));
memDataSpaceDims[0] = (hsize_t) ior_param->transferSize; memDataSpaceDims[0] = (hsize_t) hints->transferSize;
memDataSpace = H5Screate_simple(NUM_DIMS, memDataSpaceDims, NULL); memDataSpace = H5Screate_simple(NUM_DIMS, memDataSpaceDims, NULL);
HDF5_CHECK(memDataSpace, "cannot create simple memory data space"); HDF5_CHECK(memDataSpace, "cannot create simple memory data space");
@ -389,7 +389,7 @@ static aiori_fd_t *HDF5_Open(char *testFileName, int flags, aiori_mod_opt_t * pa
memBlock), "cannot create hyperslab"); memBlock), "cannot create hyperslab");
/* set up parameters for fpp or different dataset count */ /* set up parameters for fpp or different dataset count */
if (ior_param->filePerProc) { if (hints->filePerProc) {
tasksPerDataSet = 1; tasksPerDataSet = 1;
} else { } else {
if (o->individualDataSets) { if (o->individualDataSets) {
@ -397,10 +397,10 @@ static aiori_fd_t *HDF5_Open(char *testFileName, int flags, aiori_mod_opt_t * pa
tasksPerDataSet = 1; tasksPerDataSet = 1;
} else { } else {
/* share single data set across all tasks in segment */ /* share single data set across all tasks in segment */
tasksPerDataSet = ior_param->numTasks; tasksPerDataSet = hints->numTasks;
} }
} }
dataSetDims[0] = (hsize_t) ((ior_param->blockSize / sizeof(IOR_size_t)) dataSetDims[0] = (hsize_t) ((hints->blockSize / sizeof(IOR_size_t))
* tasksPerDataSet); * tasksPerDataSet);
/* create a simple data space containing information on size /* create a simple data space containing information on size
@ -436,16 +436,16 @@ static IOR_offset_t HDF5_Xfer(int access, aiori_fd_t *fd, IOR_size_t * buffer,
} }
/* determine by offset if need to start new data set */ /* determine by offset if need to start new data set */
if (ior_param->filePerProc == TRUE) { if (hints->filePerProc == TRUE) {
segmentPosition = (IOR_offset_t) 0; segmentPosition = (IOR_offset_t) 0;
segmentSize = ior_param->blockSize; segmentSize = hints->blockSize;
} else { } else {
segmentPosition = segmentPosition =
(IOR_offset_t) ((rank + rankOffset) % ior_param->numTasks) (IOR_offset_t) ((rank + rankOffset) % hints->numTasks)
* ior_param->blockSize; * hints->blockSize;
segmentSize = (IOR_offset_t) (ior_param->numTasks) * ior_param->blockSize; segmentSize = (IOR_offset_t) (hints->numTasks) * hints->blockSize;
} }
if ((IOR_offset_t) ((ior_param->offset - segmentPosition) % segmentSize) == if ((IOR_offset_t) ((hints->offset - segmentPosition) % segmentSize) ==
0) { 0) {
/* /*
* ordinarily start a new data set, unless this is the * ordinarily start a new data set, unless this is the
@ -457,7 +457,7 @@ static IOR_offset_t HDF5_Xfer(int access, aiori_fd_t *fd, IOR_size_t * buffer,
} }
} }
if(ior_param->dryRun) if(hints->dryRun)
return length; return length;
/* create new data set */ /* create new data set */
@ -468,10 +468,10 @@ static IOR_offset_t HDF5_Xfer(int access, aiori_fd_t *fd, IOR_size_t * buffer,
HDF5_CHECK(H5Sclose(fileDataSpace), HDF5_CHECK(H5Sclose(fileDataSpace),
"cannot close file data space"); "cannot close file data space");
} }
SetupDataSet(fd, param); SetupDataSet(fd, access == WRITE ? IOR_CREAT : IOR_RDWR, param);
} }
SeekOffset(fd, ior_param->offset, param); SeekOffset(fd, hints->offset, param);
/* this is necessary to reset variables for reaccessing file */ /* this is necessary to reset variables for reaccessing file */
startNewDataSet = FALSE; startNewDataSet = FALSE;
@ -504,9 +504,9 @@ static void HDF5_Fsync(aiori_fd_t *fd, aiori_mod_opt_t * param)
*/ */
static void HDF5_Close(aiori_fd_t *fd, aiori_mod_opt_t * param) static void HDF5_Close(aiori_fd_t *fd, aiori_mod_opt_t * param)
{ {
if(ior_param->dryRun) if(hints->dryRun)
return; return;
//if (ior_param->fd_fppReadCheck == NULL) { //if (hints->fd_fppReadCheck == NULL) {
HDF5_CHECK(H5Dclose(dataSet), "cannot close data set"); HDF5_CHECK(H5Dclose(dataSet), "cannot close data set");
HDF5_CHECK(H5Sclose(dataSpace), "cannot close data space"); HDF5_CHECK(H5Sclose(dataSpace), "cannot close data space");
HDF5_CHECK(H5Sclose(fileDataSpace), HDF5_CHECK(H5Sclose(fileDataSpace),
@ -525,7 +525,7 @@ static void HDF5_Close(aiori_fd_t *fd, aiori_mod_opt_t * param)
*/ */
static void HDF5_Delete(char *testFileName, aiori_mod_opt_t * param) static void HDF5_Delete(char *testFileName, aiori_mod_opt_t * param)
{ {
if(ior_param->dryRun) if(hints->dryRun)
return return
MPIIO_Delete(testFileName, param); MPIIO_Delete(testFileName, param);
return; return;
@ -564,17 +564,17 @@ static IOR_offset_t SeekOffset(void *fd, IOR_offset_t offset,
hsize_t hsStride[NUM_DIMS], hsCount[NUM_DIMS], hsBlock[NUM_DIMS]; hsize_t hsStride[NUM_DIMS], hsCount[NUM_DIMS], hsBlock[NUM_DIMS];
hsize_t hsStart[NUM_DIMS]; hsize_t hsStart[NUM_DIMS];
if (ior_param->filePerProc == TRUE) { if (hints->filePerProc == TRUE) {
segmentSize = (IOR_offset_t) ior_param->blockSize; segmentSize = (IOR_offset_t) hints->blockSize;
} else { } else {
segmentSize = segmentSize =
(IOR_offset_t) (ior_param->numTasks) * ior_param->blockSize; (IOR_offset_t) (hints->numTasks) * hints->blockSize;
} }
/* create a hyperslab representing the file data space */ /* create a hyperslab representing the file data space */
if (o->individualDataSets) { if (o->individualDataSets) {
/* start at zero offset if not */ /* start at zero offset if not */
hsStart[0] = (hsize_t) ((offset % ior_param->blockSize) hsStart[0] = (hsize_t) ((offset % hints->blockSize)
/ sizeof(IOR_size_t)); / sizeof(IOR_size_t));
} else { } else {
/* start at a unique offset if shared */ /* start at a unique offset if shared */
@ -582,8 +582,8 @@ static IOR_offset_t SeekOffset(void *fd, IOR_offset_t offset,
(hsize_t) ((offset % segmentSize) / sizeof(IOR_size_t)); (hsize_t) ((offset % segmentSize) / sizeof(IOR_size_t));
} }
hsCount[0] = (hsize_t) 1; hsCount[0] = (hsize_t) 1;
hsStride[0] = (hsize_t) (ior_param->transferSize / sizeof(IOR_size_t)); hsStride[0] = (hsize_t) (hints->transferSize / sizeof(IOR_size_t));
hsBlock[0] = (hsize_t) (ior_param->transferSize / sizeof(IOR_size_t)); hsBlock[0] = (hsize_t) (hints->transferSize / sizeof(IOR_size_t));
/* retrieve data space from data set for hyperslab */ /* retrieve data space from data set for hyperslab */
fileDataSpace = H5Dget_space(dataSet); fileDataSpace = H5Dget_space(dataSet);
@ -597,7 +597,7 @@ static IOR_offset_t SeekOffset(void *fd, IOR_offset_t offset,
/* /*
* Create HDF5 data set. * Create HDF5 data set.
*/ */
static void SetupDataSet(void *fd, aiori_mod_opt_t * param) static void SetupDataSet(void *fd, int flags, aiori_mod_opt_t * param)
{ {
HDF5_options_t *o = (HDF5_options_t*) param; HDF5_options_t *o = (HDF5_options_t*) param;
char dataSetName[MAX_STR]; char dataSetName[MAX_STR];
@ -614,7 +614,7 @@ static void SetupDataSet(void *fd, aiori_mod_opt_t * param)
/* may want to use individual access to each data set someday */ /* may want to use individual access to each data set someday */
if (o->individualDataSets) { if (o->individualDataSets) {
dataSetID = (rank + rankOffset) % ior_param->numTasks; dataSetID = (rank + rankOffset) % hints->numTasks;
} else { } else {
dataSetID = 0; dataSetID = 0;
} }
@ -622,7 +622,7 @@ static void SetupDataSet(void *fd, aiori_mod_opt_t * param)
sprintf(dataSetName, "%s-%04d.%04d", "Dataset", dataSetID, sprintf(dataSetName, "%s-%04d.%04d", "Dataset", dataSetID,
dataSetSuffix++); dataSetSuffix++);
if (ior_param->open == WRITE) { /* WRITE */ if (flags & IOR_CREAT) { /* WRITE */
/* create data set */ /* create data set */
dataSetPropList = H5Pcreate(H5P_DATASET_CREATE); dataSetPropList = H5Pcreate(H5P_DATASET_CREATE);
/* check if hdf5 available */ /* check if hdf5 available */
@ -662,7 +662,7 @@ static void SetupDataSet(void *fd, aiori_mod_opt_t * param)
static IOR_offset_t static IOR_offset_t
HDF5_GetFileSize(aiori_mod_opt_t * test, MPI_Comm testComm, char *testFileName) HDF5_GetFileSize(aiori_mod_opt_t * test, MPI_Comm testComm, char *testFileName)
{ {
if(ior_param->dryRun) if(hints->dryRun)
return 0; return 0;
return(MPIIO_GetFileSize(test, testComm, testFileName)); return(MPIIO_GetFileSize(test, testComm, testFileName));
} }
@ -672,7 +672,7 @@ HDF5_GetFileSize(aiori_mod_opt_t * test, MPI_Comm testComm, char *testFileName)
*/ */
static int HDF5_Access(const char *path, int mode, aiori_mod_opt_t *param) static int HDF5_Access(const char *path, int mode, aiori_mod_opt_t *param)
{ {
if(ior_param->dryRun) if(hints->dryRun)
return 0; return 0;
return(MPIIO_Access(path, mode, param)); return(MPIIO_Access(path, mode, param));
} }

View File

@ -33,7 +33,7 @@ static IOR_offset_t MMAP_Xfer(int, aiori_fd_t *, IOR_size_t *,
static void MMAP_Close(aiori_fd_t *, aiori_mod_opt_t *); static void MMAP_Close(aiori_fd_t *, aiori_mod_opt_t *);
static void MMAP_Fsync(aiori_fd_t *, aiori_mod_opt_t *); static void MMAP_Fsync(aiori_fd_t *, aiori_mod_opt_t *);
static option_help * MMAP_options(aiori_mod_opt_t ** init_backend_options, aiori_mod_opt_t * init_values); static option_help * MMAP_options(aiori_mod_opt_t ** init_backend_options, aiori_mod_opt_t * init_values);
static void MMAP_init_xfer_options(IOR_param_t * params); static void MMAP_xfer_hints(aiori_xfer_hint_t * params);
static int MMAP_check_params(aiori_mod_opt_t * options); static int MMAP_check_params(aiori_mod_opt_t * options);
/************************** D E C L A R A T I O N S ***************************/ /************************** D E C L A R A T I O N S ***************************/
@ -44,7 +44,7 @@ ior_aiori_t mmap_aiori = {
.xfer = MMAP_Xfer, .xfer = MMAP_Xfer,
.close = MMAP_Close, .close = MMAP_Close,
.delete = POSIX_Delete, .delete = POSIX_Delete,
.init_xfer_options = MMAP_init_xfer_options, .xfer_hints = MMAP_xfer_hints,
.get_version = aiori_get_version, .get_version = aiori_get_version,
.fsync = MMAP_Fsync, .fsync = MMAP_Fsync,
.get_file_size = POSIX_GetFileSize, .get_file_size = POSIX_GetFileSize,
@ -82,15 +82,15 @@ static option_help * MMAP_options(aiori_mod_opt_t ** init_backend_options, aiori
return help; return help;
} }
static IOR_param_t * ior_param = NULL; static aiori_xfer_hint_t * hints = NULL;
static void MMAP_init_xfer_options(IOR_param_t * params){ static void MMAP_xfer_hints(aiori_xfer_hint_t * params){
ior_param = params; hints = params;
aiori_posix_init_xfer_options(params); aiori_posix_xfer_hints(params);
} }
static int MMAP_check_params(aiori_mod_opt_t * options){ static int MMAP_check_params(aiori_mod_opt_t * options){
if (ior_param->fsyncPerWrite && (ior_param->transferSize & (sysconf(_SC_PAGESIZE) - 1))) if (hints->fsyncPerWrite && (hints->transferSize & (sysconf(_SC_PAGESIZE) - 1)))
ERR("transfer size must be aligned with PAGESIZE for MMAP with fsyncPerWrite"); ERR("transfer size must be aligned with PAGESIZE for MMAP with fsyncPerWrite");
return 0; return 0;
} }
@ -98,7 +98,7 @@ static int MMAP_check_params(aiori_mod_opt_t * options){
static void ior_mmap_file(int *file, int mflags, void *param) static void ior_mmap_file(int *file, int mflags, void *param)
{ {
int flags = PROT_READ; int flags = PROT_READ;
IOR_offset_t size = ior_param->expectedAggFileSize; IOR_offset_t size = hints->expectedAggFileSize;
if (mflags & IOR_WRONLY || mflags & IOR_RDWR) if (mflags & IOR_WRONLY || mflags & IOR_RDWR)
flags |= PROT_WRITE; flags |= PROT_WRITE;
@ -109,7 +109,7 @@ static void ior_mmap_file(int *file, int mflags, void *param)
if (o->mmap_ptr == MAP_FAILED) if (o->mmap_ptr == MAP_FAILED)
ERR("mmap() failed"); ERR("mmap() failed");
if (ior_param->randomOffset) if (hints->randomOffset)
flags = POSIX_MADV_RANDOM; flags = POSIX_MADV_RANDOM;
else else
flags = POSIX_MADV_SEQUENTIAL; flags = POSIX_MADV_SEQUENTIAL;
@ -135,7 +135,7 @@ static aiori_fd_t *MMAP_Create(char *testFileName, int flags, aiori_mod_opt_t *
int *fd; int *fd;
fd = (int*) POSIX_Create(testFileName, flags, param); fd = (int*) POSIX_Create(testFileName, flags, param);
if (ftruncate(*fd, ior_param->expectedAggFileSize) != 0) if (ftruncate(*fd, hints->expectedAggFileSize) != 0)
ERR("ftruncate() failed"); ERR("ftruncate() failed");
ior_mmap_file(fd, flags, param); ior_mmap_file(fd, flags, param);
return ((aiori_fd_t *)fd); return ((aiori_fd_t *)fd);
@ -160,15 +160,15 @@ static IOR_offset_t MMAP_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer,
{ {
mmap_options_t *o = (mmap_options_t*) param; mmap_options_t *o = (mmap_options_t*) param;
if (access == WRITE) { if (access == WRITE) {
memcpy(o->mmap_ptr + ior_param->offset, buffer, length); memcpy(o->mmap_ptr + hints->offset, buffer, length);
} else { } else {
memcpy(buffer, o->mmap_ptr + ior_param->offset, length); memcpy(buffer, o->mmap_ptr + hints->offset, length);
} }
if (ior_param->fsyncPerWrite == TRUE) { if (hints->fsyncPerWrite == TRUE) {
if (msync(o->mmap_ptr + ior_param->offset, length, MS_SYNC) != 0) if (msync(o->mmap_ptr + hints->offset, length, MS_SYNC) != 0)
ERR("msync() failed"); ERR("msync() failed");
if (posix_madvise(o->mmap_ptr + ior_param->offset, length, if (posix_madvise(o->mmap_ptr + hints->offset, length,
POSIX_MADV_DONTNEED) != 0) POSIX_MADV_DONTNEED) != 0)
ERR("madvise() failed"); ERR("madvise() failed");
} }
@ -181,7 +181,7 @@ static IOR_offset_t MMAP_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer,
static void MMAP_Fsync(aiori_fd_t *fd, aiori_mod_opt_t * param) static void MMAP_Fsync(aiori_fd_t *fd, aiori_mod_opt_t * param)
{ {
mmap_options_t *o = (mmap_options_t*) param; mmap_options_t *o = (mmap_options_t*) param;
if (msync(o->mmap_ptr, ior_param->expectedAggFileSize, MS_SYNC) != 0) if (msync(o->mmap_ptr, hints->expectedAggFileSize, MS_SYNC) != 0)
EWARN("msync() failed"); EWARN("msync() failed");
} }
@ -191,7 +191,7 @@ static void MMAP_Fsync(aiori_fd_t *fd, aiori_mod_opt_t * param)
static void MMAP_Close(aiori_fd_t *fd, aiori_mod_opt_t * param) static void MMAP_Close(aiori_fd_t *fd, aiori_mod_opt_t * param)
{ {
mmap_options_t *o = (mmap_options_t*) param; mmap_options_t *o = (mmap_options_t*) param;
if (munmap(o->mmap_ptr, ior_param->expectedAggFileSize) != 0) if (munmap(o->mmap_ptr, hints->expectedAggFileSize) != 0)
ERR("munmap failed"); ERR("munmap failed");
o->mmap_ptr = NULL; o->mmap_ptr = NULL;
POSIX_Close(fd, param); POSIX_Close(fd, param);

View File

@ -40,7 +40,7 @@ static IOR_offset_t MPIIO_Xfer(int, aiori_fd_t *, IOR_size_t *,
static void MPIIO_Close(aiori_fd_t *, aiori_mod_opt_t *); static void MPIIO_Close(aiori_fd_t *, aiori_mod_opt_t *);
static char* MPIIO_GetVersion(); static char* MPIIO_GetVersion();
static void MPIIO_Fsync(aiori_fd_t *, aiori_mod_opt_t *); static void MPIIO_Fsync(aiori_fd_t *, aiori_mod_opt_t *);
static void MPIIO_init_xfer_options(IOR_param_t * params); static void MPIIO_xfer_hints(aiori_xfer_hint_t * params);
static int MPIIO_check_params(aiori_mod_opt_t * options); static int MPIIO_check_params(aiori_mod_opt_t * options);
/************************** D E C L A R A T I O N S ***************************/ /************************** D E C L A R A T I O N S ***************************/
@ -52,7 +52,6 @@ typedef struct{
} mpiio_fd_t; } mpiio_fd_t;
typedef struct { typedef struct {
int dry_run;
int showHints; /* show hints */ int showHints; /* show hints */
int useFileView; /* use MPI_File_set_view */ int useFileView; /* use MPI_File_set_view */
int preallocate; /* preallocate file size */ int preallocate; /* preallocate file size */
@ -71,7 +70,6 @@ static option_help * MPIIO_options(aiori_mod_opt_t ** init_backend_options, aior
*init_backend_options = (aiori_mod_opt_t*) o; *init_backend_options = (aiori_mod_opt_t*) o;
option_help h [] = { option_help h [] = {
{0, "mpiio.dryRun", "Dry run, disable actual IO", OPTION_FLAG, 'd', & o->dry_run},
{0, "mpiio.hintsFileName","Full name for hints file", OPTION_OPTIONAL_ARGUMENT, 's', & o->hintsFileName}, {0, "mpiio.hintsFileName","Full name for hints file", OPTION_OPTIONAL_ARGUMENT, 's', & o->hintsFileName},
{0, "mpiio.showHints", "Show MPI hints", OPTION_FLAG, 'd', & o->showHints}, {0, "mpiio.showHints", "Show MPI hints", OPTION_FLAG, 'd', & o->showHints},
{0, "mpiio.preallocate", "Preallocate file size", OPTION_FLAG, 'd', & o->preallocate}, {0, "mpiio.preallocate", "Preallocate file size", OPTION_FLAG, 'd', & o->preallocate},
@ -91,7 +89,7 @@ ior_aiori_t mpiio_aiori = {
.name_legacy = NULL, .name_legacy = NULL,
.create = MPIIO_Create, .create = MPIIO_Create,
.get_options = MPIIO_options, .get_options = MPIIO_options,
.init_xfer_options = MPIIO_init_xfer_options, .xfer_hints = MPIIO_xfer_hints,
.open = MPIIO_Open, .open = MPIIO_Open,
.xfer = MPIIO_Xfer, .xfer = MPIIO_Xfer,
.close = MPIIO_Close, .close = MPIIO_Close,
@ -108,30 +106,30 @@ ior_aiori_t mpiio_aiori = {
}; };
/***************************** F U N C T I O N S ******************************/ /***************************** F U N C T I O N S ******************************/
static IOR_param_t * ior_param = NULL; static aiori_xfer_hint_t * hints = NULL;
static void MPIIO_init_xfer_options(IOR_param_t * params){ static void MPIIO_xfer_hints(aiori_xfer_hint_t * params){
ior_param = params; hints = params;
} }
static int MPIIO_check_params(aiori_mod_opt_t * module_options){ static int MPIIO_check_params(aiori_mod_opt_t * module_options){
mpiio_options_t * param = (mpiio_options_t*) module_options; mpiio_options_t * param = (mpiio_options_t*) module_options;
if ((param->useFileView == TRUE) if ((param->useFileView == TRUE)
&& (sizeof(MPI_Aint) < 8) /* used for 64-bit datatypes */ && (sizeof(MPI_Aint) < 8) /* used for 64-bit datatypes */
&&((ior_param->numTasks * ior_param->blockSize) > &&((hints->numTasks * hints->blockSize) >
(2 * (IOR_offset_t) GIBIBYTE))) (2 * (IOR_offset_t) GIBIBYTE)))
ERR("segment size must be < 2GiB"); ERR("segment size must be < 2GiB");
if (param->useSharedFilePointer) if (param->useSharedFilePointer)
ERR("shared file pointer not implemented"); ERR("shared file pointer not implemented");
if (param->useStridedDatatype) if (param->useStridedDatatype)
ERR("strided datatype not implemented"); ERR("strided datatype not implemented");
if (param->useStridedDatatype && (ior_param->blockSize < sizeof(IOR_size_t) if (param->useStridedDatatype && (hints->blockSize < sizeof(IOR_size_t)
|| ior_param->transferSize < || hints->transferSize <
sizeof(IOR_size_t))) sizeof(IOR_size_t)))
ERR("need larger file size for strided datatype in MPIIO"); ERR("need larger file size for strided datatype in MPIIO");
if (ior_param->randomOffset && ior_param->collective) if (hints->randomOffset && hints->collective)
ERR("random offset not available with collective MPIIO"); ERR("random offset not available with collective MPIIO");
if (ior_param->randomOffset && param->useFileView) if (hints->randomOffset && param->useFileView)
ERR("random offset not available with MPIIO fileviews"); ERR("random offset not available with MPIIO fileviews");
return 0; return 0;
@ -143,7 +141,7 @@ static int MPIIO_check_params(aiori_mod_opt_t * module_options){
int MPIIO_Access(const char *path, int mode, aiori_mod_opt_t *module_options) int MPIIO_Access(const char *path, int mode, aiori_mod_opt_t *module_options)
{ {
mpiio_options_t * param = (mpiio_options_t*) module_options; mpiio_options_t * param = (mpiio_options_t*) module_options;
if(param->dry_run){ if(hints->dryRun){
return MPI_SUCCESS; return MPI_SUCCESS;
} }
MPI_File fd; MPI_File fd;
@ -186,7 +184,7 @@ static aiori_fd_t *MPIIO_Open(char *testFileName, int flags, aiori_mod_opt_t * m
int fd_mode = (int)0, int fd_mode = (int)0,
offsetFactor, offsetFactor,
tasksPerFile, tasksPerFile,
transfersPerBlock = ior_param->blockSize / ior_param->transferSize; transfersPerBlock = hints->blockSize / hints->transferSize;
struct fileTypeStruct { struct fileTypeStruct {
int globalSizes[2], localSizes[2], startIndices[2]; int globalSizes[2], localSizes[2], startIndices[2];
} fileTypeStruct; } fileTypeStruct;
@ -227,7 +225,7 @@ static aiori_fd_t *MPIIO_Open(char *testFileName, int flags, aiori_mod_opt_t * m
*/ */
fd_mode |= MPI_MODE_UNIQUE_OPEN; fd_mode |= MPI_MODE_UNIQUE_OPEN;
if (ior_param->filePerProc) { if (hints->filePerProc) {
comm = MPI_COMM_SELF; comm = MPI_COMM_SELF;
} else { } else {
comm = testComm; comm = testComm;
@ -246,7 +244,7 @@ static aiori_fd_t *MPIIO_Open(char *testFileName, int flags, aiori_mod_opt_t * m
ShowHints(&mpiHints); ShowHints(&mpiHints);
fprintf(stdout, "}\n"); fprintf(stdout, "}\n");
} }
if(! param->dry_run){ if(! hints->dryRun){
MPI_CHECKF(MPI_File_open(comm, testFileName, fd_mode, mpiHints, & mfd->fd), MPI_CHECKF(MPI_File_open(comm, testFileName, fd_mode, mpiHints, & mfd->fd),
"cannot open file: %s", testFileName); "cannot open file: %s", testFileName);
if (flags & IOR_TRUNC) { if (flags & IOR_TRUNC) {
@ -255,7 +253,7 @@ static aiori_fd_t *MPIIO_Open(char *testFileName, int flags, aiori_mod_opt_t * m
} }
/* show hints actually attached to file handle */ /* show hints actually attached to file handle */
if (rank == 0 && param->showHints && ! param->dry_run) { if (rank == 0 && param->showHints && ! hints->dryRun) {
if (mpiHints != MPI_INFO_NULL) if (mpiHints != MPI_INFO_NULL)
MPI_CHECK(MPI_Info_free(&mpiHints), "MPI_Info_free failed"); MPI_CHECK(MPI_Info_free(&mpiHints), "MPI_Info_free failed");
MPI_CHECK(MPI_File_get_info(mfd->fd, &mpiHints), MPI_CHECK(MPI_File_get_info(mfd->fd, &mpiHints),
@ -266,29 +264,29 @@ static aiori_fd_t *MPIIO_Open(char *testFileName, int flags, aiori_mod_opt_t * m
} }
/* preallocate space for file */ /* preallocate space for file */
if (param->preallocate && ior_param->open == WRITE && ! param->dry_run) { if (param->preallocate && flags & IOR_CREAT && ! hints->dryRun) {
MPI_CHECK(MPI_File_preallocate(mfd->fd, MPI_CHECK(MPI_File_preallocate(mfd->fd,
(MPI_Offset) (ior_param->segmentCount (MPI_Offset) (hints->segmentCount
* *
ior_param->blockSize * hints->blockSize *
ior_param->numTasks)), hints->numTasks)),
"cannot preallocate file"); "cannot preallocate file");
} }
/* create file view */ /* create file view */
if (param->useFileView) { if (param->useFileView) {
/* create contiguous transfer datatype */ /* create contiguous transfer datatype */
MPI_CHECK(MPI_Type_contiguous MPI_CHECK(MPI_Type_contiguous
(ior_param->transferSize / sizeof(IOR_size_t), (hints->transferSize / sizeof(IOR_size_t),
MPI_LONG_LONG_INT, & mfd->transferType), MPI_LONG_LONG_INT, & mfd->transferType),
"cannot create contiguous datatype"); "cannot create contiguous datatype");
MPI_CHECK(MPI_Type_commit(& mfd->transferType), MPI_CHECK(MPI_Type_commit(& mfd->transferType),
"cannot commit datatype"); "cannot commit datatype");
if (ior_param->filePerProc) { if (hints->filePerProc) {
offsetFactor = 0; offsetFactor = 0;
tasksPerFile = 1; tasksPerFile = 1;
} else { } else {
offsetFactor = (rank + rankOffset) % ior_param->numTasks; offsetFactor = (rank + rankOffset) % hints->numTasks;
tasksPerFile = ior_param->numTasks; tasksPerFile = hints->numTasks;
} }
/* /*
@ -312,7 +310,7 @@ static aiori_fd_t *MPIIO_Open(char *testFileName, int flags, aiori_mod_opt_t * m
MPI_CHECK(MPI_Type_commit(& mfd->fileType), MPI_CHECK(MPI_Type_commit(& mfd->fileType),
"cannot commit datatype"); "cannot commit datatype");
if(! param->dry_run){ if(! hints->dryRun){
MPI_CHECK(MPI_File_set_view(mfd->fd, (MPI_Offset) 0, MPI_CHECK(MPI_File_set_view(mfd->fd, (MPI_Offset) 0,
mfd->transferType, mfd->transferType,
mfd->fileType, "native", mfd->fileType, "native",
@ -336,7 +334,7 @@ static IOR_offset_t MPIIO_Xfer(int access, aiori_fd_t * fdp, IOR_size_t * buffer
will get "assignment from incompatible pointer-type" warnings, will get "assignment from incompatible pointer-type" warnings,
if we only use this one set of signatures. */ if we only use this one set of signatures. */
mpiio_options_t * param = (mpiio_options_t*) module_options; mpiio_options_t * param = (mpiio_options_t*) module_options;
if(param->dry_run) if(hints->dryRun)
return length; return length;
mpiio_fd_t * mfd = (mpiio_fd_t*) fdp; mpiio_fd_t * mfd = (mpiio_fd_t*) fdp;
@ -388,7 +386,7 @@ static IOR_offset_t MPIIO_Xfer(int access, aiori_fd_t * fdp, IOR_size_t * buffer
*/ */
if (param->useFileView) { if (param->useFileView) {
/* find offset in file */ /* find offset in file */
if (SeekOffset(mfd->fd, ior_param->offset, module_options) < if (SeekOffset(mfd->fd, hints->offset, module_options) <
0) { 0) {
/* if unsuccessful */ /* if unsuccessful */
length = -1; length = -1;
@ -400,11 +398,11 @@ static IOR_offset_t MPIIO_Xfer(int access, aiori_fd_t * fdp, IOR_size_t * buffer
* e.g., 'IOR -s 2 -b 32K -t 32K -a MPIIO -S' * e.g., 'IOR -s 2 -b 32K -t 32K -a MPIIO -S'
*/ */
if (param->useStridedDatatype) { if (param->useStridedDatatype) {
length = ior_param->segmentCount; length = hints->segmentCount;
} else { } else {
length = 1; length = 1;
} }
if (ior_param->collective) { if (hints->collective) {
/* individual, collective call */ /* individual, collective call */
MPI_CHECK(Access_all MPI_CHECK(Access_all
(mfd->fd, buffer, length, (mfd->fd, buffer, length,
@ -417,7 +415,7 @@ static IOR_offset_t MPIIO_Xfer(int access, aiori_fd_t * fdp, IOR_size_t * buffer
mfd->transferType, &status), mfd->transferType, &status),
"cannot access noncollective"); "cannot access noncollective");
} }
length *= ior_param->transferSize; /* for return value in bytes */ length *= hints->transferSize; /* for return value in bytes */
} }
} else { } else {
/* /*
@ -427,7 +425,7 @@ static IOR_offset_t MPIIO_Xfer(int access, aiori_fd_t * fdp, IOR_size_t * buffer
if (param->useSharedFilePointer) { if (param->useSharedFilePointer) {
/* find offset in file */ /* find offset in file */
if (SeekOffset if (SeekOffset
(mfd->fd, ior_param->offset, module_options) < 0) { (mfd->fd, hints->offset, module_options) < 0) {
/* if unsuccessful */ /* if unsuccessful */
length = -1; length = -1;
} else { } else {
@ -443,16 +441,16 @@ static IOR_offset_t MPIIO_Xfer(int access, aiori_fd_t * fdp, IOR_size_t * buffer
"useSharedFilePointer not implemented\n"); "useSharedFilePointer not implemented\n");
} }
} else { } else {
if (ior_param->collective) { if (hints->collective) {
/* explicit, collective call */ /* explicit, collective call */
MPI_CHECK(Access_at_all MPI_CHECK(Access_at_all
(mfd->fd, ior_param->offset, (mfd->fd, hints->offset,
buffer, length, MPI_BYTE, &status), buffer, length, MPI_BYTE, &status),
"cannot access explicit, collective"); "cannot access explicit, collective");
} else { } else {
/* explicit, noncollective call */ /* explicit, noncollective call */
MPI_CHECK(Access_at MPI_CHECK(Access_at
(mfd->fd, ior_param->offset, (mfd->fd, hints->offset,
buffer, length, MPI_BYTE, &status), buffer, length, MPI_BYTE, &status),
"cannot access explicit, noncollective"); "cannot access explicit, noncollective");
} }
@ -467,7 +465,7 @@ static IOR_offset_t MPIIO_Xfer(int access, aiori_fd_t * fdp, IOR_size_t * buffer
static void MPIIO_Fsync(aiori_fd_t *fdp, aiori_mod_opt_t * module_options) static void MPIIO_Fsync(aiori_fd_t *fdp, aiori_mod_opt_t * module_options)
{ {
mpiio_options_t * param = (mpiio_options_t*) module_options; mpiio_options_t * param = (mpiio_options_t*) module_options;
if(param->dry_run) if(hints->dryRun)
return; return;
mpiio_fd_t * mfd = (mpiio_fd_t*) fdp; mpiio_fd_t * mfd = (mpiio_fd_t*) fdp;
if (MPI_File_sync(mfd->fd) != MPI_SUCCESS) if (MPI_File_sync(mfd->fd) != MPI_SUCCESS)
@ -481,7 +479,7 @@ static void MPIIO_Close(aiori_fd_t *fdp, aiori_mod_opt_t * module_options)
{ {
mpiio_options_t * param = (mpiio_options_t*) module_options; mpiio_options_t * param = (mpiio_options_t*) module_options;
mpiio_fd_t * mfd = (mpiio_fd_t*) fdp; mpiio_fd_t * mfd = (mpiio_fd_t*) fdp;
if(! param->dry_run){ if(! hints->dryRun){
MPI_CHECK(MPI_File_close(& mfd->fd), "cannot close file"); MPI_CHECK(MPI_File_close(& mfd->fd), "cannot close file");
} }
if (param->useFileView == TRUE) { if (param->useFileView == TRUE) {
@ -500,7 +498,7 @@ static void MPIIO_Close(aiori_fd_t *fdp, aiori_mod_opt_t * module_options)
void MPIIO_Delete(char *testFileName, aiori_mod_opt_t * module_options) void MPIIO_Delete(char *testFileName, aiori_mod_opt_t * module_options)
{ {
mpiio_options_t * param = (mpiio_options_t*) module_options; mpiio_options_t * param = (mpiio_options_t*) module_options;
if(param->dry_run) if(hints->dryRun)
return; return;
MPI_CHECKF(MPI_File_delete(testFileName, (MPI_Info) MPI_INFO_NULL), MPI_CHECKF(MPI_File_delete(testFileName, (MPI_Info) MPI_INFO_NULL),
"cannot delete file: %s", testFileName); "cannot delete file: %s", testFileName);
@ -530,29 +528,29 @@ static IOR_offset_t SeekOffset(MPI_File fd, IOR_offset_t offset,
tempOffset = offset; tempOffset = offset;
if (ior_param->filePerProc) { if (hints->filePerProc) {
offsetFactor = 0; offsetFactor = 0;
tasksPerFile = 1; tasksPerFile = 1;
} else { } else {
offsetFactor = (rank + rankOffset) % ior_param->numTasks; offsetFactor = (rank + rankOffset) % hints->numTasks;
tasksPerFile = ior_param->numTasks; tasksPerFile = hints->numTasks;
} }
if (param->useFileView) { if (param->useFileView) {
/* recall that offsets in a file view are /* recall that offsets in a file view are
counted in units of transfer size */ counted in units of transfer size */
if (ior_param->filePerProc) { if (hints->filePerProc) {
tempOffset = tempOffset / ior_param->transferSize; tempOffset = tempOffset / hints->transferSize;
} else { } else {
/* /*
* this formula finds a file view offset for a task * this formula finds a file view offset for a task
* from an absolute offset * from an absolute offset
*/ */
tempOffset = ((ior_param->blockSize / ior_param->transferSize) tempOffset = ((hints->blockSize / hints->transferSize)
* (tempOffset / * (tempOffset /
(ior_param->blockSize * tasksPerFile))) (hints->blockSize * tasksPerFile)))
+ (((tempOffset % (ior_param->blockSize * tasksPerFile)) + (((tempOffset % (hints->blockSize * tasksPerFile))
- (offsetFactor * ior_param->blockSize)) - (offsetFactor * hints->blockSize))
/ ior_param->transferSize); / hints->transferSize);
} }
} }
MPI_CHECK(MPI_File_seek(fd, tempOffset, MPI_SEEK_SET), MPI_CHECK(MPI_File_seek(fd, tempOffset, MPI_SEEK_SET),
@ -568,14 +566,14 @@ IOR_offset_t MPIIO_GetFileSize(aiori_mod_opt_t * module_options, MPI_Comm testCo
char *testFileName) char *testFileName)
{ {
mpiio_options_t * test = (mpiio_options_t*) module_options; mpiio_options_t * test = (mpiio_options_t*) module_options;
if(test->dry_run) if(hints->dryRun)
return 0; return 0;
IOR_offset_t aggFileSizeFromStat, tmpMin, tmpMax, tmpSum; IOR_offset_t aggFileSizeFromStat, tmpMin, tmpMax, tmpSum;
MPI_File fd; MPI_File fd;
MPI_Comm comm; MPI_Comm comm;
MPI_Info mpiHints = MPI_INFO_NULL; MPI_Info mpiHints = MPI_INFO_NULL;
if (ior_param->filePerProc == TRUE) { if (hints->filePerProc == TRUE) {
comm = MPI_COMM_SELF; comm = MPI_COMM_SELF;
} else { } else {
comm = testComm; comm = testComm;
@ -591,7 +589,7 @@ IOR_offset_t MPIIO_GetFileSize(aiori_mod_opt_t * module_options, MPI_Comm testCo
if (mpiHints != MPI_INFO_NULL) if (mpiHints != MPI_INFO_NULL)
MPI_CHECK(MPI_Info_free(&mpiHints), "MPI_Info_free failed"); MPI_CHECK(MPI_Info_free(&mpiHints), "MPI_Info_free failed");
if (ior_param->filePerProc == TRUE) { if (hints->filePerProc == TRUE) {
MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpSum, 1, MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpSum, 1,
MPI_LONG_LONG_INT, MPI_SUM, testComm), MPI_LONG_LONG_INT, MPI_SUM, testComm),
"cannot total data moved"); "cannot total data moved");

View File

@ -149,7 +149,7 @@ ior_aiori_t posix_aiori = {
.xfer = POSIX_Xfer, .xfer = POSIX_Xfer,
.close = POSIX_Close, .close = POSIX_Close,
.delete = POSIX_Delete, .delete = POSIX_Delete,
.init_xfer_options = aiori_posix_init_xfer_options, .xfer_hints = aiori_posix_xfer_hints,
.get_version = aiori_get_version, .get_version = aiori_get_version,
.fsync = POSIX_Fsync, .fsync = POSIX_Fsync,
.get_file_size = POSIX_GetFileSize, .get_file_size = POSIX_GetFileSize,
@ -166,16 +166,14 @@ ior_aiori_t posix_aiori = {
/***************************** F U N C T I O N S ******************************/ /***************************** F U N C T I O N S ******************************/
static IOR_param_t * ior_param = NULL; static aiori_xfer_hint_t * hints = NULL;
void aiori_posix_init_xfer_options(IOR_param_t * params){ void aiori_posix_xfer_hints(aiori_xfer_hint_t * params){
ior_param = params; hints = params;
} }
static int POSIX_check_params(aiori_mod_opt_t * param){ static int POSIX_check_params(aiori_mod_opt_t * param){
posix_options_t * o = (posix_options_t*) param; posix_options_t * o = (posix_options_t*) param;
if (ior_param->useExistingTestFile && o->lustre_set_striping)
ERR("Lustre stripe options are incompatible with useExistingTestFile");
if (o->beegfs_chunkSize != -1 && (!ISPOWEROFTWO(o->beegfs_chunkSize) || o->beegfs_chunkSize < (1<<16))) if (o->beegfs_chunkSize != -1 && (!ISPOWEROFTWO(o->beegfs_chunkSize) || o->beegfs_chunkSize < (1<<16)))
ERR("beegfsChunkSize must be a power of two and >64k"); ERR("beegfsChunkSize must be a power of two and >64k");
if(o->lustre_stripe_count != -1 || o->lustre_stripe_size != 0) if(o->lustre_stripe_count != -1 || o->lustre_stripe_size != 0)
@ -219,7 +217,7 @@ void gpfs_access_start(int fd, IOR_offset_t length, int access)
take_locks.access.structLen = sizeof(take_locks.access); take_locks.access.structLen = sizeof(take_locks.access);
take_locks.access.structType = GPFS_ACCESS_RANGE; take_locks.access.structType = GPFS_ACCESS_RANGE;
take_locks.access.start = ior_param->offset; take_locks.access.start = hints->offset;
take_locks.access.length = length; take_locks.access.length = length;
take_locks.access.isWrite = (access == WRITE); take_locks.access.isWrite = (access == WRITE);
@ -244,7 +242,7 @@ void gpfs_access_end(int fd, IOR_offset_t length, int access)
free_locks.free.structLen = sizeof(free_locks.free); free_locks.free.structLen = sizeof(free_locks.free);
free_locks.free.structType = GPFS_FREE_RANGE; free_locks.free.structType = GPFS_FREE_RANGE;
free_locks.free.start = ior_param->offset; free_locks.free.start = hints->offset;
free_locks.free.length = length; free_locks.free.length = length;
rc = gpfs_fcntl(fd, &free_locks); rc = gpfs_fcntl(fd, &free_locks);
@ -386,7 +384,7 @@ aiori_fd_t *POSIX_Create(char *testFileName, int flags, aiori_mod_opt_t * param)
set_o_direct_flag(&fd_oflag); set_o_direct_flag(&fd_oflag);
} }
if(ior_param->dryRun) if(hints->dryRun)
return (aiori_fd_t*) 0; return (aiori_fd_t*) 0;
#ifdef HAVE_LUSTRE_LUSTRE_USER_H #ifdef HAVE_LUSTRE_LUSTRE_USER_H
@ -399,7 +397,7 @@ aiori_fd_t *POSIX_Create(char *testFileName, int flags, aiori_mod_opt_t * param)
/* In the single-shared-file case, task 0 has to creat the /* In the single-shared-file case, task 0 has to creat the
file with the Lustre striping options before any other processes file with the Lustre striping options before any other processes
open the file */ open the file */
if (!ior_param->filePerProc && rank != 0) { if (!hints->filePerProc && rank != 0) {
MPI_CHECK(MPI_Barrier(testComm), "barrier error"); MPI_CHECK(MPI_Barrier(testComm), "barrier error");
fd_oflag |= O_RDWR; fd_oflag |= O_RDWR;
*fd = open64(testFileName, fd_oflag, mode); *fd = open64(testFileName, fd_oflag, mode);
@ -436,7 +434,7 @@ aiori_fd_t *POSIX_Create(char *testFileName, int flags, aiori_mod_opt_t * param)
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1),
"MPI_Abort() error"); "MPI_Abort() error");
} }
if (!ior_param->filePerProc) if (!hints->filePerProc)
MPI_CHECK(MPI_Barrier(testComm), MPI_CHECK(MPI_Barrier(testComm),
"barrier error"); "barrier error");
} }
@ -518,7 +516,7 @@ aiori_fd_t *POSIX_Open(char *testFileName, int flags, aiori_mod_opt_t * param)
fd_oflag |= O_RDWR; fd_oflag |= O_RDWR;
if(ior_param->dryRun) if(hints->dryRun)
return (aiori_fd_t*) 0; return (aiori_fd_t*) 0;
*fd = open64(testFileName, fd_oflag); *fd = open64(testFileName, fd_oflag);
@ -558,7 +556,7 @@ static IOR_offset_t POSIX_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer
int fd; int fd;
posix_options_t * o = (posix_options_t*) param; posix_options_t * o = (posix_options_t*) param;
if(ior_param->dryRun) if(hints->dryRun)
return length; return length;
fd = *(int *)file; fd = *(int *)file;
@ -571,8 +569,8 @@ static IOR_offset_t POSIX_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer
/* seek to offset */ /* seek to offset */
if (lseek64(fd, ior_param->offset, SEEK_SET) == -1) if (lseek64(fd, hints->offset, SEEK_SET) == -1)
ERRF("lseek64(%d, %lld, SEEK_SET) failed", fd, ior_param->offset); ERRF("lseek64(%d, %lld, SEEK_SET) failed", fd, hints->offset);
while (remaining > 0) { while (remaining > 0) {
/* write/read file */ /* write/read file */
@ -581,13 +579,13 @@ static IOR_offset_t POSIX_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer
fprintf(stdout, fprintf(stdout,
"task %d writing to offset %lld\n", "task %d writing to offset %lld\n",
rank, rank,
ior_param->offset + length - remaining); hints->offset + length - remaining);
} }
rc = write(fd, ptr, remaining); rc = write(fd, ptr, remaining);
if (rc == -1) if (rc == -1)
ERRF("write(%d, %p, %lld) failed", ERRF("write(%d, %p, %lld) failed",
fd, (void*)ptr, remaining); fd, (void*)ptr, remaining);
if (ior_param->fsyncPerWrite == TRUE){ if (hints->fsyncPerWrite == TRUE){
POSIX_Fsync((aiori_fd_t*) &fd, param); POSIX_Fsync((aiori_fd_t*) &fd, param);
} }
} else { /* READ or CHECK */ } else { /* READ or CHECK */
@ -595,7 +593,7 @@ static IOR_offset_t POSIX_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer
fprintf(stdout, fprintf(stdout,
"task %d reading from offset %lld\n", "task %d reading from offset %lld\n",
rank, rank,
ior_param->offset + length - remaining); hints->offset + length - remaining);
} }
rc = read(fd, ptr, remaining); rc = read(fd, ptr, remaining);
if (rc == 0) if (rc == 0)
@ -611,8 +609,8 @@ static IOR_offset_t POSIX_Xfer(int access, aiori_fd_t *file, IOR_size_t * buffer
rank, rank,
access == WRITE ? "write()" : "read()", access == WRITE ? "write()" : "read()",
rc, remaining, rc, remaining,
ior_param->offset + length - remaining); hints->offset + length - remaining);
if (ior_param->singleXferAttempt == TRUE) if (hints->singleXferAttempt == TRUE)
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1),
"barrier error"); "barrier error");
if (xferRetries > MAX_RETRY) if (xferRetries > MAX_RETRY)
@ -656,7 +654,7 @@ static void POSIX_Sync(aiori_mod_opt_t * param)
*/ */
void POSIX_Close(aiori_fd_t *fd, aiori_mod_opt_t * param) void POSIX_Close(aiori_fd_t *fd, aiori_mod_opt_t * param)
{ {
if(ior_param->dryRun) if(hints->dryRun)
return; return;
if (close(*(int *)fd) != 0) if (close(*(int *)fd) != 0)
ERRF("close(%d) failed", *(int *)fd); ERRF("close(%d) failed", *(int *)fd);
@ -668,7 +666,7 @@ void POSIX_Close(aiori_fd_t *fd, aiori_mod_opt_t * param)
*/ */
void POSIX_Delete(char *testFileName, aiori_mod_opt_t * param) void POSIX_Delete(char *testFileName, aiori_mod_opt_t * param)
{ {
if(ior_param->dryRun) if(hints->dryRun)
return; return;
if (unlink(testFileName) != 0){ if (unlink(testFileName) != 0){
EWARNF("[RANK %03d]: unlink() of file \"%s\" failed\n", EWARNF("[RANK %03d]: unlink() of file \"%s\" failed\n",
@ -682,7 +680,7 @@ void POSIX_Delete(char *testFileName, aiori_mod_opt_t * param)
IOR_offset_t POSIX_GetFileSize(aiori_mod_opt_t * test, MPI_Comm testComm, IOR_offset_t POSIX_GetFileSize(aiori_mod_opt_t * test, MPI_Comm testComm,
char *testFileName) char *testFileName)
{ {
if(ior_param->dryRun) if(hints->dryRun)
return 0; return 0;
struct stat stat_buf; struct stat stat_buf;
IOR_offset_t aggFileSizeFromStat, tmpMin, tmpMax, tmpSum; IOR_offset_t aggFileSizeFromStat, tmpMin, tmpMax, tmpSum;
@ -692,7 +690,7 @@ IOR_offset_t POSIX_GetFileSize(aiori_mod_opt_t * test, MPI_Comm testComm,
} }
aggFileSizeFromStat = stat_buf.st_size; aggFileSizeFromStat = stat_buf.st_size;
if (ior_param->filePerProc == TRUE) { if (hints->filePerProc == TRUE) {
MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpSum, 1, MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpSum, 1,
MPI_LONG_LONG_INT, MPI_SUM, testComm), MPI_LONG_LONG_INT, MPI_SUM, testComm),
"cannot total data moved"); "cannot total data moved");

View File

@ -24,7 +24,6 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <stdbool.h> #include <stdbool.h>
#include "ior.h"
#include "iordef.h" /* IOR Definitions */ #include "iordef.h" /* IOR Definitions */
#include "option.h" #include "option.h"
@ -63,8 +62,23 @@ typedef struct ior_aiori_statfs {
uint64_t f_ffree; uint64_t f_ffree;
} ior_aiori_statfs_t; } ior_aiori_statfs_t;
/*
This structure contains information about the expected IO pattern that may be used to optimize data access. Optimally, it should be stored for each file descriptor, at the moment it can only be set globally per aiori backend module.
*/
typedef struct aiori_xfer_hint_t{ typedef struct aiori_xfer_hint_t{
int dryRun; /* do not perform any I/Os just run evtl. inputs print dummy output */
int filePerProc; /* single file or file-per-process */
int collective; /* collective I/O */
int numTasks; /* number of tasks for test */
int numNodes; /* number of nodes for test */
int randomOffset; /* access is to random offsets */
int fsyncPerWrite; /* fsync() after each write */
IOR_offset_t segmentCount; /* number of segments (or HDF5 datasets) */
IOR_offset_t blockSize; /* contiguous bytes to write per task */
IOR_offset_t transferSize; /* size of transfer in bytes */
IOR_offset_t offset; /* offset for read/write */
IOR_offset_t expectedAggFileSize; /* calculated aggregate file size */
int singleXferAttempt; /* do not retry transfer if incomplete */
} aiori_xfer_hint_t; } aiori_xfer_hint_t;
/* this is a dummy structure to create some type safety */ /* this is a dummy structure to create some type safety */
@ -85,7 +99,7 @@ typedef struct ior_aiori {
/* /*
Allow to set generic transfer options that shall be applied to any subsequent IO call. Allow to set generic transfer options that shall be applied to any subsequent IO call.
*/ */
void (*init_xfer_options)(IOR_param_t * params); void (*xfer_hints)(aiori_xfer_hint_t * params);
IOR_offset_t (*xfer)(int, aiori_fd_t *, IOR_size_t *, IOR_offset_t (*xfer)(int, aiori_fd_t *, IOR_size_t *,
IOR_offset_t, aiori_mod_opt_t *); IOR_offset_t, aiori_mod_opt_t *);
void (*close)(aiori_fd_t *, aiori_mod_opt_t *); void (*close)(aiori_fd_t *, aiori_mod_opt_t *);
@ -144,7 +158,7 @@ int aiori_posix_mkdir (const char *path, mode_t mode, aiori_mod_opt_t * module_o
int aiori_posix_rmdir (const char *path, aiori_mod_opt_t * module_options); int aiori_posix_rmdir (const char *path, aiori_mod_opt_t * module_options);
int aiori_posix_access (const char *path, int mode, aiori_mod_opt_t * module_options); int aiori_posix_access (const char *path, int mode, aiori_mod_opt_t * module_options);
int aiori_posix_stat (const char *path, struct stat *buf, aiori_mod_opt_t * module_options); int aiori_posix_stat (const char *path, struct stat *buf, aiori_mod_opt_t * module_options);
void aiori_posix_init_xfer_options(IOR_param_t * params); void aiori_posix_xfer_hints(aiori_xfer_hint_t * params);
aiori_fd_t *POSIX_Create(char *testFileName, int flags, aiori_mod_opt_t * module_options); aiori_fd_t *POSIX_Create(char *testFileName, int flags, aiori_mod_opt_t * module_options);
int POSIX_Mknod(char *testFileName); int POSIX_Mknod(char *testFileName);

View File

@ -58,6 +58,27 @@ static IOR_offset_t WriteOrRead(IOR_param_t *test, IOR_results_t *results,
aiori_fd_t *fd, const int access, aiori_fd_t *fd, const int access,
IOR_io_buffers *ioBuffers); IOR_io_buffers *ioBuffers);
static void ior_set_xfer_hints(IOR_param_t * p){
aiori_xfer_hint_t * hints = & p->hints;
hints->dryRun = p->dryRun;
hints->filePerProc = p->filePerProc;
hints->collective = p->collective;
hints->numTasks = p->numTasks;
hints->numNodes = p->numNodes;
hints->randomOffset = p->randomOffset;
hints->fsyncPerWrite = p->fsyncPerWrite;
hints->segmentCount = p->segmentCount;
hints->blockSize = p->blockSize;
hints->transferSize = p->transferSize;
hints->offset = p->offset;
hints->expectedAggFileSize = p->expectedAggFileSize;
hints->singleXferAttempt = p->singleXferAttempt;
if(backend->xfer_hints){
backend->xfer_hints(hints);
}
}
static void test_initialize(IOR_test_t * test){ static void test_initialize(IOR_test_t * test){
verbose = test->params.verbose; verbose = test->params.verbose;
backend = test->params.backend; backend = test->params.backend;
@ -67,9 +88,7 @@ static void test_initialize(IOR_test_t * test){
if(backend->initialize){ if(backend->initialize){
backend->initialize(test->params.backend_options); backend->initialize(test->params.backend_options);
} }
if(backend->init_xfer_options){ ior_set_xfer_hints(& test->params);
backend->init_xfer_options(& test->params);
}
} }
static void test_finalize(IOR_test_t * test){ static void test_finalize(IOR_test_t * test){
@ -1643,9 +1662,8 @@ static void ValidateTests(IOR_param_t * test)
if ((strcasecmp(test->api, "NCMPI") == 0) && test->filePerProc) if ((strcasecmp(test->api, "NCMPI") == 0) && test->filePerProc)
ERR("file-per-proc not available in current NCMPI"); ERR("file-per-proc not available in current NCMPI");
if(test->backend->init_xfer_options){ backend = test->backend;
test->backend->init_xfer_options(test); ior_set_xfer_hints(test);
}
/* allow the backend to validate the options */ /* allow the backend to validate the options */
if(test->backend->check_params){ if(test->backend->check_params){
int check = test->backend->check_params(test->backend_options); int check = test->backend->check_params(test->backend_options);

View File

@ -37,6 +37,7 @@
#endif #endif
#include "option.h" #include "option.h"
#include "iordef.h" #include "iordef.h"
#include "aiori.h"
#define ISPOWEROFTWO(x) ((x != 0) && !(x & (x - 1))) #define ISPOWEROFTWO(x) ((x != 0) && !(x & (x - 1)))
/******************** DATA Packet Type ***************************************/ /******************** DATA Packet Type ***************************************/
@ -79,8 +80,6 @@ typedef struct IO_BUFFERS
* USER_GUIDE * USER_GUIDE
*/ */
struct ior_aiori;
typedef struct typedef struct
{ {
const struct ior_aiori * backend; const struct ior_aiori * backend;
@ -177,6 +176,8 @@ typedef struct
int id; /* test's unique ID */ int id; /* test's unique ID */
int intraTestBarriers; /* barriers between open/op and op/close */ int intraTestBarriers; /* barriers between open/op and op/close */
aiori_xfer_hint_t hints;
} IOR_param_t; } IOR_param_t;
/* each pointer for a single test */ /* each pointer for a single test */

View File

@ -167,8 +167,8 @@ static uid_t uid;
/* Use the POSIX backend by default */ /* Use the POSIX backend by default */
static const ior_aiori_t *backend; static const ior_aiori_t *backend;
static void * backend_options; static void * backend_options;
static aiori_xfer_hint_t hints;
static IOR_param_t param; static char * api = NULL;
/* This structure describes the processing status for stonewalling */ /* This structure describes the processing status for stonewalling */
typedef struct{ typedef struct{
@ -376,7 +376,7 @@ static void create_file (const char *path, uint64_t itemNum) {
* !collective_creates * !collective_creates
*/ */
} else { } else {
param.filePerProc = !shared_file; hints.filePerProc = !shared_file;
VERBOSE(3,5,"create_remove_items_helper (non-collective, shared): open..." ); VERBOSE(3,5,"create_remove_items_helper (non-collective, shared): open..." );
aiori_fh = backend->create (curr_item, IOR_WRONLY | IOR_CREAT, backend_options); aiori_fh = backend->create (curr_item, IOR_WRONLY | IOR_CREAT, backend_options);
@ -391,8 +391,8 @@ static void create_file (const char *path, uint64_t itemNum) {
* According to Bill Loewe, writes are only done one time, so they are always at * According to Bill Loewe, writes are only done one time, so they are always at
* offset 0 (zero). * offset 0 (zero).
*/ */
param.offset = 0; hints.offset = 0;
param.fsyncPerWrite = sync_file; hints.fsyncPerWrite = sync_file;
if ( write_bytes != (size_t) backend->xfer (WRITE, aiori_fh, (IOR_size_t *) write_buffer, write_bytes, backend_options)) { if ( write_bytes != (size_t) backend->xfer (WRITE, aiori_fh, (IOR_size_t *) write_buffer, write_bytes, backend_options)) {
FAIL("unable to write file %s", curr_item); FAIL("unable to write file %s", curr_item);
} }
@ -1906,9 +1906,10 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE *
aiori_supported_apis(APIs, APIs_legacy, MDTEST); aiori_supported_apis(APIs, APIs_legacy, MDTEST);
char apiStr[1024]; char apiStr[1024];
sprintf(apiStr, "API for I/O [%s]", APIs); sprintf(apiStr, "API for I/O [%s]", APIs);
memset(& hints, 0, sizeof(hints));
option_help options [] = { option_help options [] = {
{'a', NULL, apiStr, OPTION_OPTIONAL_ARGUMENT, 's', & param.api}, {'a', NULL, apiStr, OPTION_OPTIONAL_ARGUMENT, 's', & api},
{'b', NULL, "branching factor of hierarchical directory structure", OPTION_OPTIONAL_ARGUMENT, 'd', & branch_factor}, {'b', NULL, "branching factor of hierarchical directory structure", OPTION_OPTIONAL_ARGUMENT, 'd', & branch_factor},
{'d', NULL, "the directory in which the tests will run", OPTION_OPTIONAL_ARGUMENT, 's', & path}, {'d', NULL, "the directory in which the tests will run", OPTION_OPTIONAL_ARGUMENT, 's', & path},
{'B', NULL, "no barriers between phases", OPTION_OPTIONAL_ARGUMENT, 'd', & no_barriers}, {'B', NULL, "no barriers between phases", OPTION_OPTIONAL_ARGUMENT, 'd', & no_barriers},
@ -1953,12 +1954,13 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE *
}; };
options_all_t * global_options = airoi_create_all_module_options(options); options_all_t * global_options = airoi_create_all_module_options(options);
option_parse(argc, argv, global_options); option_parse(argc, argv, global_options);
updateParsedOptions(& param, global_options); backend = aiori_select(api);
backend_options = param.backend_options; if (backend == NULL)
ERR("Unrecognized I/O API");
backend_options = airoi_update_module_options(backend, global_options);
free(global_options->modules); free(global_options->modules);
free(global_options); free(global_options);
backend = param.backend;
MPI_Comm_rank(testComm, &rank); MPI_Comm_rank(testComm, &rank);
MPI_Comm_size(testComm, &size); MPI_Comm_size(testComm, &size);
@ -1966,8 +1968,8 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE *
if (backend->initialize){ if (backend->initialize){
backend->initialize(backend_options); backend->initialize(backend_options);
} }
if(backend->init_xfer_options){ if(backend->xfer_hints){
backend->init_xfer_options(& param); backend->xfer_hints(& hints);
} }
if(backend->check_params){ if(backend->check_params){
backend->check_params(backend_options); backend->check_params(backend_options);
@ -2011,7 +2013,7 @@ mdtest_results_t * mdtest_run(int argc, char **argv, MPI_Comm world_com, FILE *
valid_tests(); valid_tests();
// option_print_current(options); // option_print_current(options);
VERBOSE(1,-1, "api : %s", param.api); VERBOSE(1,-1, "api : %s", api);
VERBOSE(1,-1, "barriers : %s", ( barriers ? "True" : "False" )); VERBOSE(1,-1, "barriers : %s", ( barriers ? "True" : "False" ));
VERBOSE(1,-1, "collective_creates : %s", ( collective_creates ? "True" : "False" )); VERBOSE(1,-1, "collective_creates : %s", ( collective_creates ? "True" : "False" ));
VERBOSE(1,-1, "create_only : %s", ( create_only ? "True" : "False" )); VERBOSE(1,-1, "create_only : %s", ( create_only ? "True" : "False" ));