From 240e5ce93f1566367e6f71ab11ddc6fb8ba85457 Mon Sep 17 00:00:00 2001 From: "Christopher J. Morrone" Date: Fri, 11 Nov 2011 14:22:17 -0800 Subject: [PATCH] Change the the One True Formatting (Linux style) Ran the main ior code through "indent -linux --no-tabs". --- src/aiori-HDF5.c | 812 ++++---- src/aiori-MPIIO.c | 714 ++++--- src/aiori-NCMPI.c | 497 +++-- src/aiori-POSIX.c | 493 +++-- src/ior.c | 4411 ++++++++++++++++++++++--------------------- src/parse_options.c | 771 ++++---- src/utilities.c | 727 ++++--- 7 files changed, 4276 insertions(+), 4149 deletions(-) diff --git a/src/aiori-HDF5.c b/src/aiori-HDF5.c index 741b842..f53d024 100644 --- a/src/aiori-HDF5.c +++ b/src/aiori-HDF5.c @@ -9,14 +9,14 @@ * \******************************************************************************/ -#include "aiori.h" /* abstract IOR interface */ -#include /* sys_errlist */ -#include /* only for fprintf() */ +#include "aiori.h" /* abstract IOR interface */ +#include /* sys_errlist */ +#include /* only for fprintf() */ #include #include #include -#define NUM_DIMS 1 /* number of dimensions to data set */ +#define NUM_DIMS 1 /* number of dimensions to data set */ /******************************************************************************/ /* @@ -50,7 +50,7 @@ exit(-1); \ } \ } while(0) -#else /* ! (H5_VERS_MAJOR > 1 && H5_VERS_MINOR > 6) */ +#else /* ! (H5_VERS_MAJOR > 1 && H5_VERS_MINOR > 6) */ #define HDF5_CHECK(HDF5_RETURN, MSG) do { \ char resultString[1024]; \ \ @@ -66,258 +66,264 @@ exit(-1); \ } \ } while(0) -#endif /* H5_VERS_MAJOR > 1 && H5_VERS_MINOR > 6 */ +#endif /* H5_VERS_MAJOR > 1 && H5_VERS_MINOR > 6 */ /**************************** P R O T O T Y P E S *****************************/ -IOR_offset_t SeekOffset_HDF5 (void *, IOR_offset_t, IOR_param_t *); -void SetHints (MPI_Info *, char *); -void SetupDataSet_HDF5(void *, IOR_param_t *); -void ShowHints (MPI_Info *); +IOR_offset_t SeekOffset_HDF5(void *, IOR_offset_t, IOR_param_t *); +void SetHints(MPI_Info *, char *); +void SetupDataSet_HDF5(void *, IOR_param_t *); +void ShowHints(MPI_Info *); -void * IOR_Create_HDF5 (char *, IOR_param_t *); -void * IOR_Open_HDF5 (char *, IOR_param_t *); -IOR_offset_t IOR_Xfer_HDF5 (int, void *, IOR_size_t *, - IOR_offset_t, IOR_param_t *); -void IOR_Close_HDF5 (void *, IOR_param_t *); -void IOR_Delete_HDF5 (char *, IOR_param_t *); -void IOR_SetVersion_HDF5 (IOR_param_t *); -void IOR_Fsync_HDF5 (void *, IOR_param_t *); -IOR_offset_t IOR_GetFileSize_HDF5 (IOR_param_t *, MPI_Comm, char *); +void *IOR_Create_HDF5(char *, IOR_param_t *); +void *IOR_Open_HDF5(char *, IOR_param_t *); +IOR_offset_t IOR_Xfer_HDF5(int, void *, IOR_size_t *, + IOR_offset_t, IOR_param_t *); +void IOR_Close_HDF5(void *, IOR_param_t *); +void IOR_Delete_HDF5(char *, IOR_param_t *); +void IOR_SetVersion_HDF5(IOR_param_t *); +void IOR_Fsync_HDF5(void *, IOR_param_t *); +IOR_offset_t IOR_GetFileSize_HDF5(IOR_param_t *, MPI_Comm, char *); /************************** D E C L A R A T I O N S ***************************/ ior_aiori_t hdf5_aiori = { - "HDF5", - IOR_Create_HDF5, - IOR_Open_HDF5, - IOR_Xfer_HDF5, - IOR_Close_HDF5, - IOR_Delete_HDF5, - IOR_SetVersion_HDF5, - IOR_Fsync_HDF5, - IOR_GetFileSize_HDF5 + "HDF5", + IOR_Create_HDF5, + IOR_Open_HDF5, + IOR_Xfer_HDF5, + IOR_Close_HDF5, + IOR_Delete_HDF5, + IOR_SetVersion_HDF5, + IOR_Fsync_HDF5, + IOR_GetFileSize_HDF5 }; -extern int errno, /* error number */ - rank, - rankOffset, - verbose; /* verbose output */ +extern int errno, /* error number */ + rank, rankOffset, verbose; /* verbose output */ extern MPI_Comm testComm; -static hid_t xferPropList; /* xfer property list */ -hid_t dataSet; /* data set id */ -hid_t dataSpace; /* data space id */ -hid_t fileDataSpace; /* file data space id */ -hid_t memDataSpace; /* memory data space id */ -int newlyOpenedFile; /* newly opened file */ +static hid_t xferPropList; /* xfer property list */ +hid_t dataSet; /* data set id */ +hid_t dataSpace; /* data space id */ +hid_t fileDataSpace; /* file data space id */ +hid_t memDataSpace; /* memory data space id */ +int newlyOpenedFile; /* newly opened file */ /***************************** F U N C T I O N S ******************************/ - /******************************************************************************/ /* * Create and open a file through the HDF5 interface. */ -void * -IOR_Create_HDF5(char * testFileName, - IOR_param_t * param) +void *IOR_Create_HDF5(char *testFileName, IOR_param_t * param) { - return IOR_Open_HDF5(testFileName, param); -} /* IOR_Create_HDF5() */ - + return IOR_Open_HDF5(testFileName, param); +} /* IOR_Create_HDF5() */ /******************************************************************************/ /* * Open a file through the HDF5 interface. */ -void * -IOR_Open_HDF5(char * testFileName, - IOR_param_t * param) +void *IOR_Open_HDF5(char *testFileName, IOR_param_t * param) { - hid_t accessPropList, - createPropList; - hsize_t memStart[NUM_DIMS], - dataSetDims[NUM_DIMS], - memStride[NUM_DIMS], - memCount[NUM_DIMS], - memBlock[NUM_DIMS], - memDataSpaceDims[NUM_DIMS]; - int tasksPerDataSet; - unsigned fd_mode = (unsigned)0; - hid_t *fd; - MPI_Comm comm; - MPI_Info mpiHints = MPI_INFO_NULL; + hid_t accessPropList, createPropList; + hsize_t memStart[NUM_DIMS], + dataSetDims[NUM_DIMS], + memStride[NUM_DIMS], + memCount[NUM_DIMS], memBlock[NUM_DIMS], memDataSpaceDims[NUM_DIMS]; + int tasksPerDataSet; + unsigned fd_mode = (unsigned)0; + hid_t *fd; + MPI_Comm comm; + MPI_Info mpiHints = MPI_INFO_NULL; - fd = (hid_t *)malloc(sizeof(hid_t)); - if (fd == NULL) - ERR("malloc() failed"); - /* - * HDF5 uses different flags than those for POSIX/MPIIO - */ - if (param->open == WRITE) { /* WRITE flags */ - param->openFlags = IOR_TRUNC; - } else { /* READ or check WRITE/READ flags */ - param->openFlags = IOR_RDONLY; - } - - /* set IOR file flags to HDF5 flags */ - /* -- file open flags -- */ - if (param->openFlags & IOR_RDONLY) {fd_mode |= H5F_ACC_RDONLY;} - if (param->openFlags & IOR_WRONLY) { - fprintf(stdout, "File write only not implemented in HDF5\n"); - } - if (param->openFlags & IOR_RDWR) {fd_mode |= H5F_ACC_RDWR;} - if (param->openFlags & IOR_APPEND) { - fprintf(stdout, "File append not implemented in HDF5\n"); - } - if (param->openFlags & IOR_CREAT) {fd_mode |= H5F_ACC_CREAT;} - if (param->openFlags & IOR_EXCL) {fd_mode |= H5F_ACC_EXCL;} - if (param->openFlags & IOR_TRUNC) {fd_mode |= H5F_ACC_TRUNC;} - if (param->openFlags & IOR_DIRECT) { - fprintf(stdout, "O_DIRECT not implemented in HDF5\n"); - } - - /* set up file creation property list */ - createPropList = H5Pcreate(H5P_FILE_CREATE); - HDF5_CHECK(createPropList, "cannot create file creation property list"); - /* set size of offset and length used to address HDF5 objects */ - HDF5_CHECK(H5Pset_sizes(createPropList, sizeof(hsize_t), sizeof(hsize_t)), - "cannot set property list properly"); - - /* set up file access property list */ - accessPropList = H5Pcreate(H5P_FILE_ACCESS); - HDF5_CHECK(accessPropList, "cannot create file access property list"); - - /* - * someday HDF5 implementation will allow subsets of MPI_COMM_WORLD - */ - /* store MPI communicator info for the file access property list */ - if (param->filePerProc) { - comm = MPI_COMM_SELF; - } else { - comm = testComm; - } - - SetHints(&mpiHints, param->hintsFileName); - /* - * note that with MP_HINTS_FILTERED=no, all key/value pairs will - * be in the info object. The info object that is attached to - * the file during MPI_File_open() will only contain those pairs - * deemed valid by the implementation. - */ - /* show hints passed to file */ - if (rank == 0 && param->showHints) { - fprintf(stdout, "\nhints passed to access property list {\n"); - ShowHints(&mpiHints); - fprintf(stdout, "}\n"); - } - HDF5_CHECK(H5Pset_fapl_mpio(accessPropList, comm, mpiHints), - "cannot set file access property list"); - - /* set alignment */ - HDF5_CHECK(H5Pset_alignment(accessPropList, param->setAlignment, - param->setAlignment), "cannot set alignment"); - - /* open file */ - if (param->open == WRITE) { /* WRITE */ - *fd = H5Fcreate(testFileName, fd_mode, - createPropList, accessPropList); - HDF5_CHECK(*fd, "cannot create file"); - } else { /* READ or CHECK */ - *fd = H5Fopen(testFileName, fd_mode, accessPropList); - HDF5_CHECK(*fd, "cannot open file"); - } - - /* show hints actually attached to file handle */ - if (param->showHints || (1) /* WEL - this needs fixing */) { - if (rank == 0 && (param->showHints) /* WEL - this needs fixing */) { - WARN("showHints not working for HDF5"); + fd = (hid_t *) malloc(sizeof(hid_t)); + if (fd == NULL) + ERR("malloc() failed"); + /* + * HDF5 uses different flags than those for POSIX/MPIIO + */ + if (param->open == WRITE) { /* WRITE flags */ + param->openFlags = IOR_TRUNC; + } else { /* READ or check WRITE/READ flags */ + param->openFlags = IOR_RDONLY; } - } else { - MPI_Info mpiHintsCheck = MPI_INFO_NULL; - hid_t apl; - apl = H5Fget_access_plist(*fd); - HDF5_CHECK(H5Pget_fapl_mpio(apl, &comm, &mpiHintsCheck), - "cannot get info object through HDF5"); - if (rank == 0) { - fprintf(stdout, - "\nhints returned from opened file (HDF5) {\n"); - ShowHints(&mpiHintsCheck); - fprintf(stdout, "}\n"); - if (1 == 1) { /* request the MPIIO file handle and its hints */ - MPI_File * fd_mpiio; - HDF5_CHECK(H5Fget_vfd_handle(*fd, apl, (void **)&fd_mpiio), - "cannot get MPIIO file handle"); - MPI_CHECK(MPI_File_get_info(*fd_mpiio, &mpiHintsCheck), - "cannot get info object through MPIIO"); - fprintf(stdout, - "\nhints returned from opened file (MPIIO) {\n"); - ShowHints(&mpiHintsCheck); - fprintf(stdout, "}\n"); - } + + /* set IOR file flags to HDF5 flags */ + /* -- file open flags -- */ + if (param->openFlags & IOR_RDONLY) { + fd_mode |= H5F_ACC_RDONLY; + } + if (param->openFlags & IOR_WRONLY) { + fprintf(stdout, "File write only not implemented in HDF5\n"); + } + if (param->openFlags & IOR_RDWR) { + fd_mode |= H5F_ACC_RDWR; + } + if (param->openFlags & IOR_APPEND) { + fprintf(stdout, "File append not implemented in HDF5\n"); + } + if (param->openFlags & IOR_CREAT) { + fd_mode |= H5F_ACC_CREAT; + } + if (param->openFlags & IOR_EXCL) { + fd_mode |= H5F_ACC_EXCL; + } + if (param->openFlags & IOR_TRUNC) { + fd_mode |= H5F_ACC_TRUNC; + } + if (param->openFlags & IOR_DIRECT) { + fprintf(stdout, "O_DIRECT not implemented in HDF5\n"); } - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - } - /* this is necessary for resetting various parameters - needed for reopening and checking the file */ - newlyOpenedFile = TRUE; + /* set up file creation property list */ + createPropList = H5Pcreate(H5P_FILE_CREATE); + HDF5_CHECK(createPropList, "cannot create file creation property list"); + /* set size of offset and length used to address HDF5 objects */ + HDF5_CHECK(H5Pset_sizes + (createPropList, sizeof(hsize_t), sizeof(hsize_t)), + "cannot set property list properly"); - HDF5_CHECK(H5Pclose(createPropList), "cannot close creation property list"); - HDF5_CHECK(H5Pclose(accessPropList), "cannot close access property list"); + /* set up file access property list */ + accessPropList = H5Pcreate(H5P_FILE_ACCESS); + HDF5_CHECK(accessPropList, "cannot create file access property list"); - /* create property list for serial/parallel access */ - xferPropList = H5Pcreate(H5P_DATASET_XFER); - HDF5_CHECK(xferPropList, "cannot create transfer property list"); - - /* set data transfer mode */ - if (param->collective) { - HDF5_CHECK(H5Pset_dxpl_mpio(xferPropList, H5FD_MPIO_COLLECTIVE), - "cannot set collective data transfer mode"); - } else { - HDF5_CHECK(H5Pset_dxpl_mpio(xferPropList, H5FD_MPIO_INDEPENDENT), - "cannot set independent data transfer mode"); - } - - /* set up memory data space for transfer */ - memStart[0] = (hsize_t)0; - memCount[0] = (hsize_t)1; - memStride[0] = (hsize_t)(param->transferSize / sizeof(IOR_size_t)); - memBlock[0] = (hsize_t)(param->transferSize / sizeof(IOR_size_t)); - memDataSpaceDims[0] = (hsize_t)param->transferSize; - memDataSpace = H5Screate_simple(NUM_DIMS, memDataSpaceDims, NULL); - HDF5_CHECK(memDataSpace, "cannot create simple memory data space"); - - /* define hyperslab for memory data space */ - HDF5_CHECK(H5Sselect_hyperslab(memDataSpace, H5S_SELECT_SET, - memStart, memStride, memCount, memBlock), - "cannot create hyperslab"); - - /* set up parameters for fpp or different dataset count */ - if (param->filePerProc) { - tasksPerDataSet = 1; - } else { - if (param->individualDataSets) { - /* each task in segment has single data set */ - tasksPerDataSet = 1; + /* + * someday HDF5 implementation will allow subsets of MPI_COMM_WORLD + */ + /* store MPI communicator info for the file access property list */ + if (param->filePerProc) { + comm = MPI_COMM_SELF; } else { - /* share single data set across all tasks in segment */ - tasksPerDataSet = param->numTasks; + comm = testComm; } - } - dataSetDims[0] = (hsize_t)((param->blockSize / sizeof(IOR_size_t)) - * tasksPerDataSet); - /* create a simple data space containing information on size - and shape of data set, and open it for access */ - dataSpace = H5Screate_simple(NUM_DIMS, dataSetDims, NULL); - HDF5_CHECK(dataSpace, "cannot create simple data space"); - - return(fd); -} /* IOR_Open_HDF5() */ + SetHints(&mpiHints, param->hintsFileName); + /* + * note that with MP_HINTS_FILTERED=no, all key/value pairs will + * be in the info object. The info object that is attached to + * the file during MPI_File_open() will only contain those pairs + * deemed valid by the implementation. + */ + /* show hints passed to file */ + if (rank == 0 && param->showHints) { + fprintf(stdout, "\nhints passed to access property list {\n"); + ShowHints(&mpiHints); + fprintf(stdout, "}\n"); + } + HDF5_CHECK(H5Pset_fapl_mpio(accessPropList, comm, mpiHints), + "cannot set file access property list"); + /* set alignment */ + HDF5_CHECK(H5Pset_alignment(accessPropList, param->setAlignment, + param->setAlignment), + "cannot set alignment"); + + /* open file */ + if (param->open == WRITE) { /* WRITE */ + *fd = H5Fcreate(testFileName, fd_mode, + createPropList, accessPropList); + HDF5_CHECK(*fd, "cannot create file"); + } else { /* READ or CHECK */ + *fd = H5Fopen(testFileName, fd_mode, accessPropList); + HDF5_CHECK(*fd, "cannot open file"); + } + + /* show hints actually attached to file handle */ + if (param->showHints || (1) /* WEL - this needs fixing */ ) { + if (rank == 0 + && (param->showHints) /* WEL - this needs fixing */ ) { + WARN("showHints not working for HDF5"); + } + } else { + MPI_Info mpiHintsCheck = MPI_INFO_NULL; + hid_t apl; + apl = H5Fget_access_plist(*fd); + HDF5_CHECK(H5Pget_fapl_mpio(apl, &comm, &mpiHintsCheck), + "cannot get info object through HDF5"); + if (rank == 0) { + fprintf(stdout, + "\nhints returned from opened file (HDF5) {\n"); + ShowHints(&mpiHintsCheck); + fprintf(stdout, "}\n"); + if (1 == 1) { /* request the MPIIO file handle and its hints */ + MPI_File *fd_mpiio; + HDF5_CHECK(H5Fget_vfd_handle + (*fd, apl, (void **)&fd_mpiio), + "cannot get MPIIO file handle"); + MPI_CHECK(MPI_File_get_info + (*fd_mpiio, &mpiHintsCheck), + "cannot get info object through MPIIO"); + fprintf(stdout, + "\nhints returned from opened file (MPIIO) {\n"); + ShowHints(&mpiHintsCheck); + fprintf(stdout, "}\n"); + } + } + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + } + + /* this is necessary for resetting various parameters + needed for reopening and checking the file */ + newlyOpenedFile = TRUE; + + HDF5_CHECK(H5Pclose(createPropList), + "cannot close creation property list"); + HDF5_CHECK(H5Pclose(accessPropList), + "cannot close access property list"); + + /* create property list for serial/parallel access */ + xferPropList = H5Pcreate(H5P_DATASET_XFER); + HDF5_CHECK(xferPropList, "cannot create transfer property list"); + + /* set data transfer mode */ + if (param->collective) { + HDF5_CHECK(H5Pset_dxpl_mpio(xferPropList, H5FD_MPIO_COLLECTIVE), + "cannot set collective data transfer mode"); + } else { + HDF5_CHECK(H5Pset_dxpl_mpio + (xferPropList, H5FD_MPIO_INDEPENDENT), + "cannot set independent data transfer mode"); + } + + /* set up memory data space for transfer */ + memStart[0] = (hsize_t) 0; + memCount[0] = (hsize_t) 1; + memStride[0] = (hsize_t) (param->transferSize / sizeof(IOR_size_t)); + memBlock[0] = (hsize_t) (param->transferSize / sizeof(IOR_size_t)); + memDataSpaceDims[0] = (hsize_t) param->transferSize; + memDataSpace = H5Screate_simple(NUM_DIMS, memDataSpaceDims, NULL); + HDF5_CHECK(memDataSpace, "cannot create simple memory data space"); + + /* define hyperslab for memory data space */ + HDF5_CHECK(H5Sselect_hyperslab(memDataSpace, H5S_SELECT_SET, + memStart, memStride, memCount, + memBlock), "cannot create hyperslab"); + + /* set up parameters for fpp or different dataset count */ + if (param->filePerProc) { + tasksPerDataSet = 1; + } else { + if (param->individualDataSets) { + /* each task in segment has single data set */ + tasksPerDataSet = 1; + } else { + /* share single data set across all tasks in segment */ + tasksPerDataSet = param->numTasks; + } + } + dataSetDims[0] = (hsize_t) ((param->blockSize / sizeof(IOR_size_t)) + * tasksPerDataSet); + + /* create a simple data space containing information on size + and shape of data set, and open it for access */ + dataSpace = H5Screate_simple(NUM_DIMS, dataSetDims, NULL); + HDF5_CHECK(dataSpace, "cannot create simple data space"); + + return (fd); +} /* IOR_Open_HDF5() */ /******************************************************************************/ /* @@ -325,151 +331,143 @@ IOR_Open_HDF5(char * testFileName, */ IOR_offset_t -IOR_Xfer_HDF5(int access, - void * fd, - IOR_size_t * buffer, - IOR_offset_t length, - IOR_param_t * param) +IOR_Xfer_HDF5(int access, + void *fd, + IOR_size_t * buffer, IOR_offset_t length, IOR_param_t * param) { - static int firstReadCheck = FALSE, - startNewDataSet; - IOR_offset_t segmentPosition, - segmentSize; + static int firstReadCheck = FALSE, startNewDataSet; + IOR_offset_t segmentPosition, segmentSize; - /* - * this toggle is for the read check operation, which passes through - * this function twice; note that this function will open a data set - * only on the first read check and close only on the second - */ - if (access == READCHECK) { - if (firstReadCheck == TRUE) { - firstReadCheck = FALSE; - } else { - firstReadCheck = TRUE; - } - } - - /* determine by offset if need to start new data set */ - if (param->filePerProc == TRUE) { - segmentPosition = (IOR_offset_t)0; - segmentSize = param->blockSize; - } else { - segmentPosition = (IOR_offset_t)((rank + rankOffset) % param->numTasks) - * param->blockSize; - segmentSize = (IOR_offset_t)(param->numTasks) * param->blockSize; - } - if ((IOR_offset_t)((param->offset - segmentPosition) % segmentSize) == 0) { /* - * ordinarily start a new data set, unless this is the - * second pass through during a read check + * this toggle is for the read check operation, which passes through + * this function twice; note that this function will open a data set + * only on the first read check and close only on the second */ - startNewDataSet = TRUE; - if (access == READCHECK && firstReadCheck != TRUE) { - startNewDataSet = FALSE; + if (access == READCHECK) { + if (firstReadCheck == TRUE) { + firstReadCheck = FALSE; + } else { + firstReadCheck = TRUE; + } } - } - /* create new data set */ - if (startNewDataSet == TRUE) { - /* if just opened this file, no data set to close yet */ - if (newlyOpenedFile != TRUE) { - HDF5_CHECK(H5Dclose(dataSet), "cannot close data set"); - HDF5_CHECK(H5Sclose(fileDataSpace), - "cannot close file data space"); + /* determine by offset if need to start new data set */ + if (param->filePerProc == TRUE) { + segmentPosition = (IOR_offset_t) 0; + segmentSize = param->blockSize; + } else { + segmentPosition = + (IOR_offset_t) ((rank + rankOffset) % param->numTasks) + * param->blockSize; + segmentSize = + (IOR_offset_t) (param->numTasks) * param->blockSize; + } + if ((IOR_offset_t) ((param->offset - segmentPosition) % segmentSize) == + 0) { + /* + * ordinarily start a new data set, unless this is the + * second pass through during a read check + */ + startNewDataSet = TRUE; + if (access == READCHECK && firstReadCheck != TRUE) { + startNewDataSet = FALSE; + } } - SetupDataSet_HDF5(fd, param); - } - SeekOffset_HDF5(fd, param->offset, param); + /* create new data set */ + if (startNewDataSet == TRUE) { + /* if just opened this file, no data set to close yet */ + if (newlyOpenedFile != TRUE) { + HDF5_CHECK(H5Dclose(dataSet), "cannot close data set"); + HDF5_CHECK(H5Sclose(fileDataSpace), + "cannot close file data space"); + } + SetupDataSet_HDF5(fd, param); + } - /* this is necessary to reset variables for reaccessing file */ - startNewDataSet = FALSE; - newlyOpenedFile = FALSE; + SeekOffset_HDF5(fd, param->offset, param); - /* access the file */ - if (access == WRITE) { /* WRITE */ - HDF5_CHECK(H5Dwrite(dataSet, H5T_NATIVE_LLONG, - memDataSpace, fileDataSpace, - xferPropList, buffer), - "cannot write to data set"); - } else { /* READ or CHECK */ - HDF5_CHECK(H5Dread(dataSet, H5T_NATIVE_LLONG, - memDataSpace, fileDataSpace, - xferPropList, buffer), - "cannot read from data set"); - } - return(length); -} /* IOR_Xfer_HDF5() */ + /* this is necessary to reset variables for reaccessing file */ + startNewDataSet = FALSE; + newlyOpenedFile = FALSE; + /* access the file */ + if (access == WRITE) { /* WRITE */ + HDF5_CHECK(H5Dwrite(dataSet, H5T_NATIVE_LLONG, + memDataSpace, fileDataSpace, + xferPropList, buffer), + "cannot write to data set"); + } else { /* READ or CHECK */ + HDF5_CHECK(H5Dread(dataSet, H5T_NATIVE_LLONG, + memDataSpace, fileDataSpace, + xferPropList, buffer), + "cannot read from data set"); + } + return (length); +} /* IOR_Xfer_HDF5() */ /******************************************************************************/ /* * Perform fsync(). */ -void -IOR_Fsync_HDF5(void * fd, IOR_param_t * param) +void IOR_Fsync_HDF5(void *fd, IOR_param_t * param) { - ; -} /* IOR_Fsync_HDF5() */ - + ; +} /* IOR_Fsync_HDF5() */ /******************************************************************************/ /* * Close a file through the HDF5 interface. */ -void -IOR_Close_HDF5(void * fd, - IOR_param_t * param) +void IOR_Close_HDF5(void *fd, IOR_param_t * param) { - if (param->fd_fppReadCheck == NULL) { - HDF5_CHECK(H5Dclose(dataSet), "cannot close data set"); - HDF5_CHECK(H5Sclose(dataSpace), "cannot close data space"); - HDF5_CHECK(H5Sclose(fileDataSpace), "cannot close file data space"); - HDF5_CHECK(H5Sclose(memDataSpace), "cannot close memory data space"); - HDF5_CHECK(H5Pclose(xferPropList), - " cannot close transfer property list"); - } - HDF5_CHECK(H5Fclose(*(hid_t *)fd), "cannot close file"); - free(fd); -} /* IOR_Close_HDF5() */ - + if (param->fd_fppReadCheck == NULL) { + HDF5_CHECK(H5Dclose(dataSet), "cannot close data set"); + HDF5_CHECK(H5Sclose(dataSpace), "cannot close data space"); + HDF5_CHECK(H5Sclose(fileDataSpace), + "cannot close file data space"); + HDF5_CHECK(H5Sclose(memDataSpace), + "cannot close memory data space"); + HDF5_CHECK(H5Pclose(xferPropList), + " cannot close transfer property list"); + } + HDF5_CHECK(H5Fclose(*(hid_t *) fd), "cannot close file"); + free(fd); +} /* IOR_Close_HDF5() */ /******************************************************************************/ /* * Delete a file through the HDF5 interface. */ -void -IOR_Delete_HDF5(char * testFileName, IOR_param_t * param) +void IOR_Delete_HDF5(char *testFileName, IOR_param_t * param) { - if (unlink(testFileName) != 0) WARN("cannot delete file"); -} /* IOR_Delete_HDF5() */ - + if (unlink(testFileName) != 0) + WARN("cannot delete file"); +} /* IOR_Delete_HDF5() */ /******************************************************************************/ /* * Determine api version. */ -void -IOR_SetVersion_HDF5(IOR_param_t *test) +void IOR_SetVersion_HDF5(IOR_param_t * test) { - unsigned major, minor, release; - if (H5get_libversion(&major, &minor, &release) < 0) { - WARN("cannot get HDF5 library version"); - } else { - sprintf(test->apiVersion, "%s-%u.%u.%u", - test->api, major, minor, release); - } + unsigned major, minor, release; + if (H5get_libversion(&major, &minor, &release) < 0) { + WARN("cannot get HDF5 library version"); + } else { + sprintf(test->apiVersion, "%s-%u.%u.%u", + test->api, major, minor, release); + } #ifndef H5_HAVE_PARALLEL - strcat(test->apiVersion, " (Serial)"); -#else /* H5_HAVE_PARALLEL */ - strcat(test->apiVersion, " (Parallel)"); -#endif /* not H5_HAVE_PARALLEL */ -} /* IOR_SetVersion_HDF5() */ - + strcat(test->apiVersion, " (Serial)"); +#else /* H5_HAVE_PARALLEL */ + strcat(test->apiVersion, " (Parallel)"); +#endif /* not H5_HAVE_PARALLEL */ +} /* IOR_SetVersion_HDF5() */ /************************ L O C A L F U N C T I O N S ***********************/ @@ -478,109 +476,105 @@ IOR_SetVersion_HDF5(IOR_param_t *test) * Seek to offset in file using the HDF5 interface and set up hyperslab. */ -IOR_offset_t -SeekOffset_HDF5(void *fd, - IOR_offset_t offset, - IOR_param_t * param) +IOR_offset_t SeekOffset_HDF5(void *fd, IOR_offset_t offset, IOR_param_t * param) { - IOR_offset_t segmentSize; - hsize_t hsStride[NUM_DIMS], - hsCount[NUM_DIMS], - hsBlock[NUM_DIMS]; - hsize_t hsStart[NUM_DIMS]; + IOR_offset_t segmentSize; + hsize_t hsStride[NUM_DIMS], hsCount[NUM_DIMS], hsBlock[NUM_DIMS]; + hsize_t hsStart[NUM_DIMS]; - if (param->filePerProc == TRUE) { - segmentSize = (IOR_offset_t)param->blockSize; - } else { - segmentSize = (IOR_offset_t)(param->numTasks) * param->blockSize; - } + if (param->filePerProc == TRUE) { + segmentSize = (IOR_offset_t) param->blockSize; + } else { + segmentSize = + (IOR_offset_t) (param->numTasks) * param->blockSize; + } - /* create a hyperslab representing the file data space */ - if (param->individualDataSets) { - /* start at zero offset if not */ - hsStart[0] = (hsize_t)((offset % param->blockSize) - / sizeof(IOR_size_t)); - } else { - /* start at a unique offset if shared */ - hsStart[0] = (hsize_t)((offset % segmentSize) / sizeof(IOR_size_t)); - } - hsCount[0] = (hsize_t)1; - hsStride[0] = (hsize_t)(param->transferSize / sizeof(IOR_size_t)); - hsBlock[0] = (hsize_t)(param->transferSize / sizeof(IOR_size_t)); - - /* retrieve data space from data set for hyperslab */ - fileDataSpace = H5Dget_space(dataSet); - HDF5_CHECK(fileDataSpace, "cannot get data space from data set"); - HDF5_CHECK(H5Sselect_hyperslab(fileDataSpace, H5S_SELECT_SET, - hsStart, hsStride, hsCount, hsBlock), - "cannot select hyperslab"); - return(offset); -} /* SeekOffset_HDF5() */ + /* create a hyperslab representing the file data space */ + if (param->individualDataSets) { + /* start at zero offset if not */ + hsStart[0] = (hsize_t) ((offset % param->blockSize) + / sizeof(IOR_size_t)); + } else { + /* start at a unique offset if shared */ + hsStart[0] = + (hsize_t) ((offset % segmentSize) / sizeof(IOR_size_t)); + } + hsCount[0] = (hsize_t) 1; + hsStride[0] = (hsize_t) (param->transferSize / sizeof(IOR_size_t)); + hsBlock[0] = (hsize_t) (param->transferSize / sizeof(IOR_size_t)); + /* retrieve data space from data set for hyperslab */ + fileDataSpace = H5Dget_space(dataSet); + HDF5_CHECK(fileDataSpace, "cannot get data space from data set"); + HDF5_CHECK(H5Sselect_hyperslab(fileDataSpace, H5S_SELECT_SET, + hsStart, hsStride, hsCount, hsBlock), + "cannot select hyperslab"); + return (offset); +} /* SeekOffset_HDF5() */ /******************************************************************************/ /* * Create HDF5 data set. */ -void -SetupDataSet_HDF5(void * fd, - IOR_param_t * param) +void SetupDataSet_HDF5(void *fd, IOR_param_t * param) { - char dataSetName[MAX_STR]; - hid_t dataSetPropList; - int dataSetID; - static int dataSetSuffix = 0; + char dataSetName[MAX_STR]; + hid_t dataSetPropList; + int dataSetID; + static int dataSetSuffix = 0; - /* may want to use an extendable dataset (H5S_UNLIMITED) someday */ - /* may want to use a chunked dataset (H5S_CHUNKED) someday */ + /* may want to use an extendable dataset (H5S_UNLIMITED) someday */ + /* may want to use a chunked dataset (H5S_CHUNKED) someday */ - /* need to reset suffix counter if newly-opened file */ - if (newlyOpenedFile) dataSetSuffix = 0; + /* need to reset suffix counter if newly-opened file */ + if (newlyOpenedFile) + dataSetSuffix = 0; - /* may want to use individual access to each data set someday */ - if (param->individualDataSets) { - dataSetID = (rank + rankOffset) % param->numTasks; - } else { - dataSetID = 0; - } + /* may want to use individual access to each data set someday */ + if (param->individualDataSets) { + dataSetID = (rank + rankOffset) % param->numTasks; + } else { + dataSetID = 0; + } - sprintf(dataSetName, "%s-%04d.%04d", "Dataset", dataSetID, dataSetSuffix++); + sprintf(dataSetName, "%s-%04d.%04d", "Dataset", dataSetID, + dataSetSuffix++); - if (param->open == WRITE) { /* WRITE */ - /* create data set */ - dataSetPropList = H5Pcreate(H5P_DATASET_CREATE); - /* check if hdf5 available */ - #if defined (H5_VERS_MAJOR) && defined (H5_VERS_MINOR) - /* no-fill option not available until hdf5-1.6.x */ - #if (H5_VERS_MAJOR > 0 && H5_VERS_MINOR > 5) + if (param->open == WRITE) { /* WRITE */ + /* create data set */ + dataSetPropList = H5Pcreate(H5P_DATASET_CREATE); + /* check if hdf5 available */ +#if defined (H5_VERS_MAJOR) && defined (H5_VERS_MINOR) + /* no-fill option not available until hdf5-1.6.x */ +#if (H5_VERS_MAJOR > 0 && H5_VERS_MINOR > 5) if (param->noFill == TRUE) { - if (rank == 0 && verbose >= VERBOSE_1) { - fprintf(stdout, "\nusing 'no fill' option\n"); - } - HDF5_CHECK(H5Pset_fill_time(dataSetPropList, - H5D_FILL_TIME_NEVER), - "cannot set fill time for property list"); + if (rank == 0 && verbose >= VERBOSE_1) { + fprintf(stdout, "\nusing 'no fill' option\n"); + } + HDF5_CHECK(H5Pset_fill_time(dataSetPropList, + H5D_FILL_TIME_NEVER), + "cannot set fill time for property list"); } - #else +#else char errorString[MAX_STR]; sprintf(errorString, "'no fill' option not available in %s", test->apiVersion); ERR(errorString); - #endif - #else - WARN("unable to determine HDF5 version for 'no fill' usage"); - #endif - dataSet = H5Dcreate(*(hid_t *)fd, dataSetName, H5T_NATIVE_LLONG, - dataSpace, dataSetPropList); - HDF5_CHECK(dataSet, "cannot create data set"); - } else { /* READ or CHECK */ - dataSet = H5Dopen(*(hid_t *)fd, dataSetName); - HDF5_CHECK(dataSet, "cannot create data set"); - } - -} /* SetupDataSet_HDF5() */ +#endif +#else + WARN("unable to determine HDF5 version for 'no fill' usage"); +#endif + dataSet = + H5Dcreate(*(hid_t *) fd, dataSetName, H5T_NATIVE_LLONG, + dataSpace, dataSetPropList); + HDF5_CHECK(dataSet, "cannot create data set"); + } else { /* READ or CHECK */ + dataSet = H5Dopen(*(hid_t *) fd, dataSetName); + HDF5_CHECK(dataSet, "cannot create data set"); + } +} /* SetupDataSet_HDF5() */ /******************************************************************************/ /* @@ -588,9 +582,7 @@ SetupDataSet_HDF5(void * fd, */ IOR_offset_t -IOR_GetFileSize_HDF5(IOR_param_t * test, - MPI_Comm testComm, - char * testFileName) +IOR_GetFileSize_HDF5(IOR_param_t * test, MPI_Comm testComm, char *testFileName) { - return(IOR_GetFileSize_MPIIO(test, testComm, testFileName)); -} /* IOR_GetFileSize_HDF5() */ + return (IOR_GetFileSize_MPIIO(test, testComm, testFileName)); +} /* IOR_GetFileSize_HDF5() */ diff --git a/src/aiori-MPIIO.c b/src/aiori-MPIIO.c index b1b430f..b6ebe9a 100644 --- a/src/aiori-MPIIO.c +++ b/src/aiori-MPIIO.c @@ -9,53 +9,51 @@ * \******************************************************************************/ -#include "aiori.h" /* abstract IOR interface */ -#include /* sys_errlist */ -#include /* only for fprintf() */ +#include "aiori.h" /* abstract IOR interface */ +#include /* sys_errlist */ +#include /* only for fprintf() */ #include #include #include #ifndef MPIAPI -# define MPIAPI /* defined as __stdcall on Windows */ +#define MPIAPI /* defined as __stdcall on Windows */ #endif - /**************************** P R O T O T Y P E S *****************************/ -static IOR_offset_t SeekOffset_MPIIO (MPI_File, IOR_offset_t, - IOR_param_t *); -void SetHints (MPI_Info *, char *); -void ShowHints (MPI_Info *); +static IOR_offset_t SeekOffset_MPIIO(MPI_File, IOR_offset_t, IOR_param_t *); +void SetHints(MPI_Info *, char *); +void ShowHints(MPI_Info *); -void * IOR_Create_MPIIO (char *, IOR_param_t *); -void * IOR_Open_MPIIO (char *, IOR_param_t *); -IOR_offset_t IOR_Xfer_MPIIO (int, void *, IOR_size_t *, - IOR_offset_t, IOR_param_t *); -void IOR_Close_MPIIO (void *, IOR_param_t *); -void IOR_Delete_MPIIO (char *, IOR_param_t *); -void IOR_SetVersion_MPIIO (IOR_param_t *); -void IOR_Fsync_MPIIO (void *, IOR_param_t *); -IOR_offset_t IOR_GetFileSize_MPIIO (IOR_param_t *, MPI_Comm, char *); +void *IOR_Create_MPIIO(char *, IOR_param_t *); +void *IOR_Open_MPIIO(char *, IOR_param_t *); +IOR_offset_t IOR_Xfer_MPIIO(int, void *, IOR_size_t *, + IOR_offset_t, IOR_param_t *); +void IOR_Close_MPIIO(void *, IOR_param_t *); +void IOR_Delete_MPIIO(char *, IOR_param_t *); +void IOR_SetVersion_MPIIO(IOR_param_t *); +void IOR_Fsync_MPIIO(void *, IOR_param_t *); +IOR_offset_t IOR_GetFileSize_MPIIO(IOR_param_t *, MPI_Comm, char *); /************************** D E C L A R A T I O N S ***************************/ -extern int errno; -extern int rank; -extern int rankOffset; -extern int verbose; +extern int errno; +extern int rank; +extern int rankOffset; +extern int verbose; extern MPI_Comm testComm; ior_aiori_t mpiio_aiori = { - "MPIIO", - IOR_Create_MPIIO, - IOR_Open_MPIIO, - IOR_Xfer_MPIIO, - IOR_Close_MPIIO, - IOR_Delete_MPIIO, - IOR_SetVersion_MPIIO, - IOR_Fsync_MPIIO, - IOR_GetFileSize_MPIIO + "MPIIO", + IOR_Create_MPIIO, + IOR_Open_MPIIO, + IOR_Xfer_MPIIO, + IOR_Close_MPIIO, + IOR_Delete_MPIIO, + IOR_SetVersion_MPIIO, + IOR_Fsync_MPIIO, + IOR_GetFileSize_MPIIO }; /***************************** F U N C T I O N S ******************************/ @@ -65,144 +63,155 @@ ior_aiori_t mpiio_aiori = { * Create and open a file through the MPIIO interface. */ -void * -IOR_Create_MPIIO(char * testFileName, - IOR_param_t * param) +void *IOR_Create_MPIIO(char *testFileName, IOR_param_t * param) { - return IOR_Open_MPIIO(testFileName, param); -} /* IOR_Create_MPIIO() */ - + return IOR_Open_MPIIO(testFileName, param); +} /* IOR_Create_MPIIO() */ /******************************************************************************/ /* * Open a file through the MPIIO interface. Setup file view. */ -void * -IOR_Open_MPIIO(char * testFileName, - IOR_param_t * param) +void *IOR_Open_MPIIO(char *testFileName, IOR_param_t * param) { - int fd_mode = (int)0, - offsetFactor, - tasksPerFile, - transfersPerBlock = param->blockSize - / param->transferSize; - struct fileTypeStruct { - int globalSizes[2], - localSizes[2], - startIndices[2]; - } fileTypeStruct; - MPI_File * fd; - MPI_Comm comm; - MPI_Info mpiHints = MPI_INFO_NULL; + int fd_mode = (int)0, + offsetFactor, + tasksPerFile, + transfersPerBlock = param->blockSize / param->transferSize; + struct fileTypeStruct { + int globalSizes[2], localSizes[2], startIndices[2]; + } fileTypeStruct; + MPI_File *fd; + MPI_Comm comm; + MPI_Info mpiHints = MPI_INFO_NULL; - fd = (MPI_File *)malloc(sizeof(MPI_File)); - if (fd == NULL) - ERR("malloc failed()"); + fd = (MPI_File *) malloc(sizeof(MPI_File)); + if (fd == NULL) + ERR("malloc failed()"); - *fd = 0; + *fd = 0; - /* set IOR file flags to MPIIO flags */ - /* -- file open flags -- */ - if (param->openFlags & IOR_RDONLY) {fd_mode |= MPI_MODE_RDONLY;} - if (param->openFlags & IOR_WRONLY) {fd_mode |= MPI_MODE_WRONLY;} - if (param->openFlags & IOR_RDWR) {fd_mode |= MPI_MODE_RDWR;} - if (param->openFlags & IOR_APPEND) {fd_mode |= MPI_MODE_APPEND;} - if (param->openFlags & IOR_CREAT) {fd_mode |= MPI_MODE_CREATE;} - if (param->openFlags & IOR_EXCL) {fd_mode |= MPI_MODE_EXCL;} - if (param->openFlags & IOR_TRUNC) { - fprintf(stdout, "File truncation not implemented in MPIIO\n"); - } - if (param->openFlags & IOR_DIRECT) { - fprintf(stdout, "O_DIRECT not implemented in MPIIO\n"); - } - - /* - * MPI_MODE_UNIQUE_OPEN mode optimization eliminates the overhead of file - * locking. Only open a file in this mode when the file will not be con- - * currently opened elsewhere, either inside or outside the MPI environment. - */ - fd_mode |= MPI_MODE_UNIQUE_OPEN; - - if (param->filePerProc) { - comm = MPI_COMM_SELF; - } else { - comm = testComm; - } - - SetHints(&mpiHints, param->hintsFileName); - /* - * note that with MP_HINTS_FILTERED=no, all key/value pairs will - * be in the info object. The info object that is attached to - * the file during MPI_File_open() will only contain those pairs - * deemed valid by the implementation. - */ - /* show hints passed to file */ - if (rank == 0 && param->showHints) { - fprintf(stdout, "\nhints passed to MPI_File_open() {\n"); - ShowHints(&mpiHints); - fprintf(stdout, "}\n"); - } - MPI_CHECK(MPI_File_open(comm, testFileName, fd_mode, mpiHints, fd), - "cannot open file"); - - /* show hints actually attached to file handle */ - if (rank == 0 && param->showHints) { - MPI_CHECK(MPI_File_get_info(*fd, &mpiHints), - "cannot get file info"); - fprintf(stdout, "\nhints returned from opened file {\n"); - ShowHints(&mpiHints); - fprintf(stdout, "}\n"); - } - - /* preallocate space for file */ - if (param->preallocate && param->open == WRITE) { - MPI_CHECK(MPI_File_preallocate(*fd, - (MPI_Offset)(param->segmentCount*param->blockSize*param->numTasks)), - "cannot preallocate file"); - } - /* create file view */ - if (param->useFileView) { - /* create contiguous transfer datatype */ - MPI_CHECK(MPI_Type_contiguous(param->transferSize / sizeof(IOR_size_t), - MPI_LONG_LONG_INT, ¶m->transferType), - "cannot create contiguous datatype"); - MPI_CHECK(MPI_Type_commit(¶m->transferType), - "cannot commit datatype"); - if (param->filePerProc) { - offsetFactor = 0; - tasksPerFile = 1; - } else { - offsetFactor = (rank + rankOffset) % param->numTasks; - tasksPerFile = param->numTasks; + /* set IOR file flags to MPIIO flags */ + /* -- file open flags -- */ + if (param->openFlags & IOR_RDONLY) { + fd_mode |= MPI_MODE_RDONLY; + } + if (param->openFlags & IOR_WRONLY) { + fd_mode |= MPI_MODE_WRONLY; + } + if (param->openFlags & IOR_RDWR) { + fd_mode |= MPI_MODE_RDWR; + } + if (param->openFlags & IOR_APPEND) { + fd_mode |= MPI_MODE_APPEND; + } + if (param->openFlags & IOR_CREAT) { + fd_mode |= MPI_MODE_CREATE; + } + if (param->openFlags & IOR_EXCL) { + fd_mode |= MPI_MODE_EXCL; + } + if (param->openFlags & IOR_TRUNC) { + fprintf(stdout, "File truncation not implemented in MPIIO\n"); + } + if (param->openFlags & IOR_DIRECT) { + fprintf(stdout, "O_DIRECT not implemented in MPIIO\n"); } /* - * create file type using subarray + * MPI_MODE_UNIQUE_OPEN mode optimization eliminates the overhead of file + * locking. Only open a file in this mode when the file will not be con- + * currently opened elsewhere, either inside or outside the MPI environment. */ - fileTypeStruct.globalSizes[0] = 1; - fileTypeStruct.globalSizes[1] = transfersPerBlock * tasksPerFile; - fileTypeStruct.localSizes[0] = 1; - fileTypeStruct.localSizes[1] = transfersPerBlock; - fileTypeStruct.startIndices[0] = 0; - fileTypeStruct.startIndices[1] = transfersPerBlock * offsetFactor; + fd_mode |= MPI_MODE_UNIQUE_OPEN; - MPI_CHECK(MPI_Type_create_subarray(2, fileTypeStruct.globalSizes, - fileTypeStruct.localSizes, - fileTypeStruct.startIndices, - MPI_ORDER_C, param->transferType, - ¶m->fileType), - "cannot create subarray"); - MPI_CHECK(MPI_Type_commit(¶m->fileType), "cannot commit datatype"); + if (param->filePerProc) { + comm = MPI_COMM_SELF; + } else { + comm = testComm; + } - MPI_CHECK(MPI_File_set_view(*fd, (MPI_Offset)0, - param->transferType, param->fileType, - "native", (MPI_Info)MPI_INFO_NULL), - "cannot set file view"); - } - return((void *)fd); -} /* IOR_Open_MPIIO() */ + SetHints(&mpiHints, param->hintsFileName); + /* + * note that with MP_HINTS_FILTERED=no, all key/value pairs will + * be in the info object. The info object that is attached to + * the file during MPI_File_open() will only contain those pairs + * deemed valid by the implementation. + */ + /* show hints passed to file */ + if (rank == 0 && param->showHints) { + fprintf(stdout, "\nhints passed to MPI_File_open() {\n"); + ShowHints(&mpiHints); + fprintf(stdout, "}\n"); + } + MPI_CHECK(MPI_File_open(comm, testFileName, fd_mode, mpiHints, fd), + "cannot open file"); + /* show hints actually attached to file handle */ + if (rank == 0 && param->showHints) { + MPI_CHECK(MPI_File_get_info(*fd, &mpiHints), + "cannot get file info"); + fprintf(stdout, "\nhints returned from opened file {\n"); + ShowHints(&mpiHints); + fprintf(stdout, "}\n"); + } + + /* preallocate space for file */ + if (param->preallocate && param->open == WRITE) { + MPI_CHECK(MPI_File_preallocate(*fd, + (MPI_Offset) (param->segmentCount + * + param->blockSize * + param->numTasks)), + "cannot preallocate file"); + } + /* create file view */ + if (param->useFileView) { + /* create contiguous transfer datatype */ + MPI_CHECK(MPI_Type_contiguous + (param->transferSize / sizeof(IOR_size_t), + MPI_LONG_LONG_INT, ¶m->transferType), + "cannot create contiguous datatype"); + MPI_CHECK(MPI_Type_commit(¶m->transferType), + "cannot commit datatype"); + if (param->filePerProc) { + offsetFactor = 0; + tasksPerFile = 1; + } else { + offsetFactor = (rank + rankOffset) % param->numTasks; + tasksPerFile = param->numTasks; + } + + /* + * create file type using subarray + */ + fileTypeStruct.globalSizes[0] = 1; + fileTypeStruct.globalSizes[1] = + transfersPerBlock * tasksPerFile; + fileTypeStruct.localSizes[0] = 1; + fileTypeStruct.localSizes[1] = transfersPerBlock; + fileTypeStruct.startIndices[0] = 0; + fileTypeStruct.startIndices[1] = + transfersPerBlock * offsetFactor; + + MPI_CHECK(MPI_Type_create_subarray + (2, fileTypeStruct.globalSizes, + fileTypeStruct.localSizes, + fileTypeStruct.startIndices, MPI_ORDER_C, + param->transferType, ¶m->fileType), + "cannot create subarray"); + MPI_CHECK(MPI_Type_commit(¶m->fileType), + "cannot commit datatype"); + + MPI_CHECK(MPI_File_set_view(*fd, (MPI_Offset) 0, + param->transferType, + param->fileType, "native", + (MPI_Info) MPI_INFO_NULL), + "cannot set file view"); + } + return ((void *)fd); +} /* IOR_Open_MPIIO() */ /******************************************************************************/ /* @@ -210,186 +219,181 @@ IOR_Open_MPIIO(char * testFileName, */ IOR_offset_t -IOR_Xfer_MPIIO(int access, - void * fd, - IOR_size_t * buffer, - IOR_offset_t length, - IOR_param_t * param) +IOR_Xfer_MPIIO(int access, + void *fd, + IOR_size_t * buffer, IOR_offset_t length, IOR_param_t * param) { - int (MPIAPI *Access) (MPI_File, void *, int, - MPI_Datatype, MPI_Status *); - int (MPIAPI *Access_at) (MPI_File, MPI_Offset, void *, int, - MPI_Datatype,MPI_Status *); - int (MPIAPI *Access_all) (MPI_File, void *, int, - MPI_Datatype, MPI_Status *); - int (MPIAPI *Access_at_all) (MPI_File, MPI_Offset, void *, int, - MPI_Datatype, MPI_Status *); - /* - * this needs to be properly implemented: - * - * int (*Access_ordered)(MPI_File, void *, int, - * MPI_Datatype, MPI_Status *); - */ - MPI_Status status; - - /* point functions to appropriate MPIIO calls */ - if (access == WRITE) { /* WRITE */ - Access = MPI_File_write; - Access_at = MPI_File_write_at; - Access_all = MPI_File_write_all; - Access_at_all = MPI_File_write_at_all; + int (MPIAPI * Access) (MPI_File, void *, int, + MPI_Datatype, MPI_Status *); + int (MPIAPI * Access_at) (MPI_File, MPI_Offset, void *, int, + MPI_Datatype, MPI_Status *); + int (MPIAPI * Access_all) (MPI_File, void *, int, + MPI_Datatype, MPI_Status *); + int (MPIAPI * Access_at_all) (MPI_File, MPI_Offset, void *, int, + MPI_Datatype, MPI_Status *); /* * this needs to be properly implemented: * - * Access_ordered = MPI_File_write_ordered; + * int (*Access_ordered)(MPI_File, void *, int, + * MPI_Datatype, MPI_Status *); */ - } else { /* READ or CHECK */ - Access = MPI_File_read; - Access_at = MPI_File_read_at; - Access_all = MPI_File_read_all; - Access_at_all = MPI_File_read_at_all; - /* - * this needs to be properly implemented: - * - * Access_ordered = MPI_File_read_ordered; - */ - } + MPI_Status status; - /* - * 'useFileView' uses derived datatypes and individual file pointers - */ - if (param->useFileView) { - /* find offset in file */ - if (SeekOffset_MPIIO(*(MPI_File *)fd, param->offset, param) < 0) { - /* if unsuccessful */ - length = -1; - } else { - /* - * 'useStridedDatatype' fits multi-strided pattern into a datatype; - * must use 'length' to determine repetitions (fix this for - * multi-segments someday, WEL): - * e.g., 'IOR -s 2 -b 32K -t 32K -a MPIIO -S' - */ - if (param->useStridedDatatype) { - length = param->segmentCount; - } else { - length = 1; - } - if (param->collective) { - /* individual, collective call */ - MPI_CHECK(Access_all(*(MPI_File *)fd, buffer, length, - param->transferType, &status), - "cannot access collective"); - } else { - /* individual, noncollective call */ - MPI_CHECK(Access(*(MPI_File *)fd, buffer, length, - param->transferType, &status), - "cannot access noncollective"); - } - length *= param->transferSize; /* for return value in bytes */ - } - } else { - /* - * !useFileView does not use derived datatypes, but it uses either - * shared or explicit file pointers - */ - if (param->useSharedFilePointer) { - /* find offset in file */ - if (SeekOffset_MPIIO(*(MPI_File *)fd, param->offset, param) < 0) { - /* if unsuccessful */ - length = -1; - } else { - /* shared, collective call */ + /* point functions to appropriate MPIIO calls */ + if (access == WRITE) { /* WRITE */ + Access = MPI_File_write; + Access_at = MPI_File_write_at; + Access_all = MPI_File_write_all; + Access_at_all = MPI_File_write_at_all; /* * this needs to be properly implemented: * - * MPI_CHECK(Access_ordered(fd.MPIIO, buffer, length, - * MPI_BYTE, &status), - * "cannot access shared, collective"); + * Access_ordered = MPI_File_write_ordered; + */ + } else { /* READ or CHECK */ + Access = MPI_File_read; + Access_at = MPI_File_read_at; + Access_all = MPI_File_read_all; + Access_at_all = MPI_File_read_at_all; + /* + * this needs to be properly implemented: + * + * Access_ordered = MPI_File_read_ordered; */ - fprintf(stdout, "useSharedFilePointer not implemented\n"); - } - } else { - if (param->collective) { - /* explicit, collective call */ - MPI_CHECK(Access_at_all(*(MPI_File *)fd, param->offset, - buffer, length, MPI_BYTE, &status), - "cannot access explicit, collective"); - } else { - /* explicit, noncollective call */ - MPI_CHECK(Access_at(*(MPI_File *)fd, param->offset, buffer, - length, MPI_BYTE, &status), - "cannot access explicit, noncollective"); - } } - } - return(length); -} /* IOR_Xfer_MPIIO() */ - + + /* + * 'useFileView' uses derived datatypes and individual file pointers + */ + if (param->useFileView) { + /* find offset in file */ + if (SeekOffset_MPIIO(*(MPI_File *) fd, param->offset, param) < + 0) { + /* if unsuccessful */ + length = -1; + } else { + /* + * 'useStridedDatatype' fits multi-strided pattern into a datatype; + * must use 'length' to determine repetitions (fix this for + * multi-segments someday, WEL): + * e.g., 'IOR -s 2 -b 32K -t 32K -a MPIIO -S' + */ + if (param->useStridedDatatype) { + length = param->segmentCount; + } else { + length = 1; + } + if (param->collective) { + /* individual, collective call */ + MPI_CHECK(Access_all + (*(MPI_File *) fd, buffer, length, + param->transferType, &status), + "cannot access collective"); + } else { + /* individual, noncollective call */ + MPI_CHECK(Access + (*(MPI_File *) fd, buffer, length, + param->transferType, &status), + "cannot access noncollective"); + } + length *= param->transferSize; /* for return value in bytes */ + } + } else { + /* + * !useFileView does not use derived datatypes, but it uses either + * shared or explicit file pointers + */ + if (param->useSharedFilePointer) { + /* find offset in file */ + if (SeekOffset_MPIIO + (*(MPI_File *) fd, param->offset, param) < 0) { + /* if unsuccessful */ + length = -1; + } else { + /* shared, collective call */ + /* + * this needs to be properly implemented: + * + * MPI_CHECK(Access_ordered(fd.MPIIO, buffer, length, + * MPI_BYTE, &status), + * "cannot access shared, collective"); + */ + fprintf(stdout, + "useSharedFilePointer not implemented\n"); + } + } else { + if (param->collective) { + /* explicit, collective call */ + MPI_CHECK(Access_at_all + (*(MPI_File *) fd, param->offset, + buffer, length, MPI_BYTE, &status), + "cannot access explicit, collective"); + } else { + /* explicit, noncollective call */ + MPI_CHECK(Access_at + (*(MPI_File *) fd, param->offset, + buffer, length, MPI_BYTE, &status), + "cannot access explicit, noncollective"); + } + } + } + return (length); +} /* IOR_Xfer_MPIIO() */ /******************************************************************************/ /* * Perform fsync(). */ -void -IOR_Fsync_MPIIO(void * fd, IOR_param_t * param) +void IOR_Fsync_MPIIO(void *fd, IOR_param_t * param) { - ; -} /* IOR_Fsync_MPIIO() */ + ; +} /* IOR_Fsync_MPIIO() */ - /******************************************************************************/ /* * Close a file through the MPIIO interface. */ -void -IOR_Close_MPIIO(void * fd, - IOR_param_t * param) +void IOR_Close_MPIIO(void *fd, IOR_param_t * param) { - MPI_CHECK(MPI_File_close((MPI_File *)fd), "cannot close file"); - if ((param->useFileView == TRUE) && (param->fd_fppReadCheck == NULL)) { - /* - * need to free the datatype, so done in the close process - */ - MPI_CHECK(MPI_Type_free(¶m->fileType), - "cannot free MPI file datatype"); - MPI_CHECK(MPI_Type_free(¶m->transferType), - "cannot free MPI transfer datatype"); - } - free(fd); -} /* IOR_Close_MPIIO() */ - + MPI_CHECK(MPI_File_close((MPI_File *) fd), "cannot close file"); + if ((param->useFileView == TRUE) && (param->fd_fppReadCheck == NULL)) { + /* + * need to free the datatype, so done in the close process + */ + MPI_CHECK(MPI_Type_free(¶m->fileType), + "cannot free MPI file datatype"); + MPI_CHECK(MPI_Type_free(¶m->transferType), + "cannot free MPI transfer datatype"); + } + free(fd); +} /* IOR_Close_MPIIO() */ /******************************************************************************/ /* * Delete a file through the MPIIO interface. */ -void -IOR_Delete_MPIIO(char * testFileName, IOR_param_t * param) +void IOR_Delete_MPIIO(char *testFileName, IOR_param_t * param) { - MPI_CHECK(MPI_File_delete(testFileName, (MPI_Info)MPI_INFO_NULL), - "cannot delete file"); -} /* IOR_Delete_MPIIO() */ - + MPI_CHECK(MPI_File_delete(testFileName, (MPI_Info) MPI_INFO_NULL), + "cannot delete file"); +} /* IOR_Delete_MPIIO() */ /******************************************************************************/ /* * Determine api version. */ -void -IOR_SetVersion_MPIIO(IOR_param_t *test) +void IOR_SetVersion_MPIIO(IOR_param_t * test) { - int version, subversion; - MPI_CHECK(MPI_Get_version(&version, &subversion), - "cannot get MPI version"); - sprintf(test->apiVersion, "%s (version=%d, subversion=%d)", - test->api, version, subversion); -} /* IOR_SetVersion_MPIIO() */ - + int version, subversion; + MPI_CHECK(MPI_Get_version(&version, &subversion), + "cannot get MPI version"); + sprintf(test->apiVersion, "%s (version=%d, subversion=%d)", + test->api, version, subversion); +} /* IOR_SetVersion_MPIIO() */ /************************ L O C A L F U N C T I O N S ***********************/ @@ -399,45 +403,42 @@ IOR_SetVersion_MPIIO(IOR_param_t *test) */ static IOR_offset_t -SeekOffset_MPIIO(MPI_File fd, - IOR_offset_t offset, - IOR_param_t * param) +SeekOffset_MPIIO(MPI_File fd, IOR_offset_t offset, IOR_param_t * param) { - int offsetFactor, - tasksPerFile; - IOR_offset_t tempOffset; + int offsetFactor, tasksPerFile; + IOR_offset_t tempOffset; - tempOffset = offset; + tempOffset = offset; - if (param->filePerProc) { - offsetFactor = 0; - tasksPerFile = 1; - } else { - offsetFactor = (rank + rankOffset) % param->numTasks; - tasksPerFile = param->numTasks; - } - if (param->useFileView) { - /* recall that offsets in a file view are - counted in units of transfer size */ if (param->filePerProc) { - tempOffset = tempOffset / param->transferSize; + offsetFactor = 0; + tasksPerFile = 1; } else { - /* - * this formula finds a file view offset for a task - * from an absolute offset - */ - tempOffset = ((param->blockSize / param->transferSize) - * (tempOffset / (param->blockSize * tasksPerFile))) - + (((tempOffset % (param->blockSize * tasksPerFile)) - - (offsetFactor * param->blockSize)) - / param->transferSize); + offsetFactor = (rank + rankOffset) % param->numTasks; + tasksPerFile = param->numTasks; } - } - MPI_CHECK(MPI_File_seek(fd, tempOffset, MPI_SEEK_SET), - "cannot seek offset"); - return(offset); -} /* SeekOffset_MPIIO() */ - + if (param->useFileView) { + /* recall that offsets in a file view are + counted in units of transfer size */ + if (param->filePerProc) { + tempOffset = tempOffset / param->transferSize; + } else { + /* + * this formula finds a file view offset for a task + * from an absolute offset + */ + tempOffset = ((param->blockSize / param->transferSize) + * (tempOffset / + (param->blockSize * tasksPerFile))) + + (((tempOffset % (param->blockSize * tasksPerFile)) + - (offsetFactor * param->blockSize)) + / param->transferSize); + } + } + MPI_CHECK(MPI_File_seek(fd, tempOffset, MPI_SEEK_SET), + "cannot seek offset"); + return (offset); +} /* SeekOffset_MPIIO() */ /******************************************************************************/ /* @@ -445,42 +446,39 @@ SeekOffset_MPIIO(MPI_File fd, */ IOR_offset_t -IOR_GetFileSize_MPIIO(IOR_param_t * test, - MPI_Comm testComm, - char * testFileName) +IOR_GetFileSize_MPIIO(IOR_param_t * test, MPI_Comm testComm, char *testFileName) { - IOR_offset_t aggFileSizeFromStat, - tmpMin, tmpMax, tmpSum; - MPI_File fd; + IOR_offset_t aggFileSizeFromStat, tmpMin, tmpMax, tmpSum; + MPI_File fd; - MPI_CHECK(MPI_File_open(testComm, testFileName, MPI_MODE_RDONLY, - MPI_INFO_NULL, &fd), - "cannot open file to get file size"); - MPI_CHECK(MPI_File_get_size(fd, (MPI_Offset *)&aggFileSizeFromStat), - "cannot get file size"); - MPI_CHECK(MPI_File_close(&fd), "cannot close file"); + MPI_CHECK(MPI_File_open(testComm, testFileName, MPI_MODE_RDONLY, + MPI_INFO_NULL, &fd), + "cannot open file to get file size"); + MPI_CHECK(MPI_File_get_size(fd, (MPI_Offset *) & aggFileSizeFromStat), + "cannot get file size"); + MPI_CHECK(MPI_File_close(&fd), "cannot close file"); - if (test->filePerProc == TRUE) { - MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpSum, 1, - MPI_LONG_LONG_INT, MPI_SUM, testComm), - "cannot total data moved"); - aggFileSizeFromStat = tmpSum; - } else { - MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMin, 1, - MPI_LONG_LONG_INT, MPI_MIN, testComm), - "cannot total data moved"); - MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMax, 1, - MPI_LONG_LONG_INT, MPI_MAX, testComm), - "cannot total data moved"); - if (tmpMin != tmpMax) { - if (rank == 0) { - WARN("inconsistent file size by different tasks"); - } - /* incorrect, but now consistent across tasks */ - aggFileSizeFromStat = tmpMin; + if (test->filePerProc == TRUE) { + MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpSum, 1, + MPI_LONG_LONG_INT, MPI_SUM, testComm), + "cannot total data moved"); + aggFileSizeFromStat = tmpSum; + } else { + MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMin, 1, + MPI_LONG_LONG_INT, MPI_MIN, testComm), + "cannot total data moved"); + MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMax, 1, + MPI_LONG_LONG_INT, MPI_MAX, testComm), + "cannot total data moved"); + if (tmpMin != tmpMax) { + if (rank == 0) { + WARN("inconsistent file size by different tasks"); + } + /* incorrect, but now consistent across tasks */ + aggFileSizeFromStat = tmpMin; + } } - } - return(aggFileSizeFromStat); + return (aggFileSizeFromStat); -} /* IOR_GetFileSize_MPIIO() */ +} /* IOR_GetFileSize_MPIIO() */ diff --git a/src/aiori-NCMPI.c b/src/aiori-NCMPI.c index 0a267e9..b4915c2 100644 --- a/src/aiori-NCMPI.c +++ b/src/aiori-NCMPI.c @@ -9,14 +9,14 @@ * \******************************************************************************/ -#include "aiori.h" /* abstract IOR interface */ -#include /* sys_errlist */ -#include /* only for fprintf() */ +#include "aiori.h" /* abstract IOR interface */ +#include /* sys_errlist */ +#include /* only for fprintf() */ #include #include #include -#define NUM_DIMS 3 /* number of dimensions to data set */ +#define NUM_DIMS 3 /* number of dimensions to data set */ /******************************************************************************/ /* @@ -38,39 +38,36 @@ /**************************** P R O T O T Y P E S *****************************/ -int GetFileMode(IOR_param_t *); -void SetHints (MPI_Info *, char *); -void ShowHints (MPI_Info *); +int GetFileMode(IOR_param_t *); +void SetHints(MPI_Info *, char *); +void ShowHints(MPI_Info *); -void * IOR_Create_NCMPI (char *, IOR_param_t *); -void * IOR_Open_NCMPI (char *, IOR_param_t *); -IOR_offset_t IOR_Xfer_NCMPI (int, void *, IOR_size_t *, - IOR_offset_t, IOR_param_t *); -void IOR_Close_NCMPI (void *, IOR_param_t *); -void IOR_Delete_NCMPI (char *, IOR_param_t *); -void IOR_SetVersion_NCMPI (IOR_param_t *); -void IOR_Fsync_NCMPI (void *, IOR_param_t *); -IOR_offset_t IOR_GetFileSize_NCMPI (IOR_param_t *, MPI_Comm, char *); +void *IOR_Create_NCMPI(char *, IOR_param_t *); +void *IOR_Open_NCMPI(char *, IOR_param_t *); +IOR_offset_t IOR_Xfer_NCMPI(int, void *, IOR_size_t *, + IOR_offset_t, IOR_param_t *); +void IOR_Close_NCMPI(void *, IOR_param_t *); +void IOR_Delete_NCMPI(char *, IOR_param_t *); +void IOR_SetVersion_NCMPI(IOR_param_t *); +void IOR_Fsync_NCMPI(void *, IOR_param_t *); +IOR_offset_t IOR_GetFileSize_NCMPI(IOR_param_t *, MPI_Comm, char *); /************************** D E C L A R A T I O N S ***************************/ ior_aiori_t ncmpi_aiori = { - "NCMPI", - IOR_Create_NCMPI, - IOR_Open_NCMPI, - IOR_Xfer_NCMPI, - IOR_Close_NCMPI, - IOR_Delete_NCMPI, - IOR_SetVersion_NCMPI, - IOR_Fsync_NCMPI, - IOR_GetFileSize_NCMPI + "NCMPI", + IOR_Create_NCMPI, + IOR_Open_NCMPI, + IOR_Xfer_NCMPI, + IOR_Close_NCMPI, + IOR_Delete_NCMPI, + IOR_SetVersion_NCMPI, + IOR_Fsync_NCMPI, + IOR_GetFileSize_NCMPI }; -extern int errno, /* error number */ - numTasksWorld, - rank, - rankOffset, - verbose; /* verbose output */ +extern int errno, /* error number */ + numTasksWorld, rank, rankOffset, verbose; /* verbose output */ extern MPI_Comm testComm; /***************************** F U N C T I O N S ******************************/ @@ -79,31 +76,29 @@ extern MPI_Comm testComm; * Create and open a file through the NCMPI interface. */ -void * -IOR_Create_NCMPI(char * testFileName, - IOR_param_t * param) +void *IOR_Create_NCMPI(char *testFileName, IOR_param_t * param) { - int * fd; - int fd_mode; - MPI_Info mpiHints = MPI_INFO_NULL; + int *fd; + int fd_mode; + MPI_Info mpiHints = MPI_INFO_NULL; - /* Wei-keng Liao: read and set MPI file hints from hintsFile */ - SetHints(&mpiHints, param->hintsFileName); - if (rank == 0 && param->showHints) { - fprintf(stdout, "\nhints passed to MPI_File_open() {\n"); - ShowHints(&mpiHints); - fprintf(stdout, "}\n"); - } + /* Wei-keng Liao: read and set MPI file hints from hintsFile */ + SetHints(&mpiHints, param->hintsFileName); + if (rank == 0 && param->showHints) { + fprintf(stdout, "\nhints passed to MPI_File_open() {\n"); + ShowHints(&mpiHints); + fprintf(stdout, "}\n"); + } - fd = (int *)malloc(sizeof(int)); - if (fd == NULL) - ERR("malloc() failed"); + fd = (int *)malloc(sizeof(int)); + if (fd == NULL) + ERR("malloc() failed"); - fd_mode = GetFileMode(param); - NCMPI_CHECK(ncmpi_create(testComm, testFileName, fd_mode, - mpiHints, fd), "cannot create file"); + fd_mode = GetFileMode(param); + NCMPI_CHECK(ncmpi_create(testComm, testFileName, fd_mode, + mpiHints, fd), "cannot create file"); - /* Wei-keng Liao: print the MPI file hints currently used */ + /* Wei-keng Liao: print the MPI file hints currently used */ /* WEL - add when ncmpi_get_file_info() is in current parallel-netcdf release if (rank == 0 && param->showHints) { MPI_CHECK(ncmpi_get_file_info(*fd, &mpiHints), @@ -114,46 +109,43 @@ IOR_Create_NCMPI(char * testFileName, } */ - /* Wei-keng Liao: free up the mpiHints object */ + /* Wei-keng Liao: free up the mpiHints object */ /* WEL - this needs future fix from next release of PnetCDF if (mpiHints != MPI_INFO_NULL) MPI_CHECK(MPI_Info_free(&mpiHints), "cannot free file info"); */ - return(fd); -} /* IOR_Create_NCMPI() */ - + return (fd); +} /* IOR_Create_NCMPI() */ /******************************************************************************/ /* * Open a file through the NCMPI interface. */ -void * -IOR_Open_NCMPI(char * testFileName, - IOR_param_t * param) +void *IOR_Open_NCMPI(char *testFileName, IOR_param_t * param) { - int * fd; - int fd_mode; - MPI_Info mpiHints = MPI_INFO_NULL; + int *fd; + int fd_mode; + MPI_Info mpiHints = MPI_INFO_NULL; - /* Wei-keng Liao: read and set MPI file hints from hintsFile */ - SetHints(&mpiHints, param->hintsFileName); - if (rank == 0 && param->showHints) { - fprintf(stdout, "\nhints passed to MPI_File_open() {\n"); - ShowHints(&mpiHints); - fprintf(stdout, "}\n"); - } + /* Wei-keng Liao: read and set MPI file hints from hintsFile */ + SetHints(&mpiHints, param->hintsFileName); + if (rank == 0 && param->showHints) { + fprintf(stdout, "\nhints passed to MPI_File_open() {\n"); + ShowHints(&mpiHints); + fprintf(stdout, "}\n"); + } - fd = (int *)malloc(sizeof(int)); - if (fd == NULL) - ERR("malloc() failed"); + fd = (int *)malloc(sizeof(int)); + if (fd == NULL) + ERR("malloc() failed"); - fd_mode = GetFileMode(param); - NCMPI_CHECK(ncmpi_open(testComm, testFileName, fd_mode, - mpiHints, fd), "cannot open file"); + fd_mode = GetFileMode(param); + NCMPI_CHECK(ncmpi_open(testComm, testFileName, fd_mode, + mpiHints, fd), "cannot open file"); - /* Wei-keng Liao: print the MPI file hints currently used */ + /* Wei-keng Liao: print the MPI file hints currently used */ /* WEL - add when ncmpi_get_file_info() is in current parallel-netcdf release if (rank == 0 && param->showHints) { MPI_CHECK(ncmpi_get_file_info(*fd, &mpiHints), @@ -164,15 +156,14 @@ IOR_Open_NCMPI(char * testFileName, } */ - /* Wei-keng Liao: free up the mpiHints object */ + /* Wei-keng Liao: free up the mpiHints object */ /* WEL - this needs future fix from next release of PnetCDF if (mpiHints != MPI_INFO_NULL) MPI_CHECK(MPI_Info_free(&mpiHints), "cannot free file info"); */ - return(fd); -} /* IOR_Open_NCMPI() */ - + return (fd); +} /* IOR_Open_NCMPI() */ /******************************************************************************/ /* @@ -180,195 +171,189 @@ IOR_Open_NCMPI(char * testFileName, */ IOR_offset_t -IOR_Xfer_NCMPI(int access, - void * fd, - IOR_size_t * buffer, - IOR_offset_t length, - IOR_param_t * param) +IOR_Xfer_NCMPI(int access, + void *fd, + IOR_size_t * buffer, IOR_offset_t length, IOR_param_t * param) { - char * bufferPtr = (char *)buffer; - static int firstReadCheck = FALSE, - startDataSet; - int var_id, - dim_id[NUM_DIMS]; - MPI_Offset bufSize[NUM_DIMS], - offset[NUM_DIMS]; - IOR_offset_t segmentPosition; - int segmentNum, - transferNum; + char *bufferPtr = (char *)buffer; + static int firstReadCheck = FALSE, startDataSet; + int var_id, dim_id[NUM_DIMS]; + MPI_Offset bufSize[NUM_DIMS], offset[NUM_DIMS]; + IOR_offset_t segmentPosition; + int segmentNum, transferNum; - /* Wei-keng Liao: In ior.c line 1979 says "block size must be a multiple - of transfer size." Hence, length should always == param->transferSize - below. I leave it here to double check. - */ - if (length != param->transferSize) { - char errMsg[256]; - sprintf(errMsg,"length(%lld) != param->transferSize(%lld)\n", - length, param->transferSize); - NCMPI_CHECK(-1, errMsg); - } - - /* determine by offset if need to start data set */ - if (param->filePerProc == TRUE) { - segmentPosition = (IOR_offset_t)0; - } else { - segmentPosition = (IOR_offset_t)((rank + rankOffset) % param->numTasks) - * param->blockSize; - } - if ((int)(param->offset - segmentPosition) == 0) { - startDataSet = TRUE; - /* - * this toggle is for the read check operation, which passes through - * this function twice; note that this function will open a data set - * only on the first read check and close only on the second + /* Wei-keng Liao: In ior.c line 1979 says "block size must be a multiple + of transfer size." Hence, length should always == param->transferSize + below. I leave it here to double check. */ - if (access == READCHECK) { - if (firstReadCheck == TRUE) { - firstReadCheck = FALSE; - } else { - firstReadCheck = TRUE; - } + if (length != param->transferSize) { + char errMsg[256]; + sprintf(errMsg, "length(%lld) != param->transferSize(%lld)\n", + length, param->transferSize); + NCMPI_CHECK(-1, errMsg); } - } - if (startDataSet == TRUE && - (access != READCHECK || firstReadCheck == TRUE)) { - if (access == WRITE) { - int numTransfers = param->blockSize / param->transferSize; - - /* Wei-keng Liao: change 1D array to 3D array of dimensions: - [segmentCount*numTasksWorld][numTransfers][transferSize] - Requirement: none of these dimensions should be > 4G, - */ - NCMPI_CHECK(ncmpi_def_dim(*(int *)fd, "segments_times_np", - NC_UNLIMITED, &dim_id[0]), - "cannot define data set dimensions"); - NCMPI_CHECK(ncmpi_def_dim(*(int *)fd, "number_of_transfers", - numTransfers, &dim_id[1]), - "cannot define data set dimensions"); - NCMPI_CHECK(ncmpi_def_dim(*(int *)fd, "transfer_size", - param->transferSize, &dim_id[2]), - "cannot define data set dimensions"); - NCMPI_CHECK(ncmpi_def_var(*(int *)fd, "data_var", NC_BYTE, - NUM_DIMS, dim_id, &var_id), - "cannot define data set variables"); - NCMPI_CHECK(ncmpi_enddef(*(int *)fd), - "cannot close data set define mode"); - + /* determine by offset if need to start data set */ + if (param->filePerProc == TRUE) { + segmentPosition = (IOR_offset_t) 0; } else { - NCMPI_CHECK(ncmpi_inq_varid(*(int *)fd, "data_var", &var_id), - "cannot retrieve data set variable"); + segmentPosition = + (IOR_offset_t) ((rank + rankOffset) % param->numTasks) + * param->blockSize; + } + if ((int)(param->offset - segmentPosition) == 0) { + startDataSet = TRUE; + /* + * this toggle is for the read check operation, which passes through + * this function twice; note that this function will open a data set + * only on the first read check and close only on the second + */ + if (access == READCHECK) { + if (firstReadCheck == TRUE) { + firstReadCheck = FALSE; + } else { + firstReadCheck = TRUE; + } + } } - if (param->collective == FALSE) { - NCMPI_CHECK(ncmpi_begin_indep_data(*(int *)fd), - "cannot enable independent data mode"); + if (startDataSet == TRUE && + (access != READCHECK || firstReadCheck == TRUE)) { + if (access == WRITE) { + int numTransfers = + param->blockSize / param->transferSize; + + /* Wei-keng Liao: change 1D array to 3D array of dimensions: + [segmentCount*numTasksWorld][numTransfers][transferSize] + Requirement: none of these dimensions should be > 4G, + */ + NCMPI_CHECK(ncmpi_def_dim + (*(int *)fd, "segments_times_np", + NC_UNLIMITED, &dim_id[0]), + "cannot define data set dimensions"); + NCMPI_CHECK(ncmpi_def_dim + (*(int *)fd, "number_of_transfers", + numTransfers, &dim_id[1]), + "cannot define data set dimensions"); + NCMPI_CHECK(ncmpi_def_dim + (*(int *)fd, "transfer_size", + param->transferSize, &dim_id[2]), + "cannot define data set dimensions"); + NCMPI_CHECK(ncmpi_def_var + (*(int *)fd, "data_var", NC_BYTE, NUM_DIMS, + dim_id, &var_id), + "cannot define data set variables"); + NCMPI_CHECK(ncmpi_enddef(*(int *)fd), + "cannot close data set define mode"); + + } else { + NCMPI_CHECK(ncmpi_inq_varid + (*(int *)fd, "data_var", &var_id), + "cannot retrieve data set variable"); + } + + if (param->collective == FALSE) { + NCMPI_CHECK(ncmpi_begin_indep_data(*(int *)fd), + "cannot enable independent data mode"); + } + + param->var_id = var_id; + startDataSet = FALSE; } - param->var_id = var_id; - startDataSet = FALSE; - } + var_id = param->var_id; - var_id = param->var_id; + /* Wei-keng Liao: calculate the segment number */ + segmentNum = param->offset / (param->numTasks * param->blockSize); - /* Wei-keng Liao: calculate the segment number */ - segmentNum = param->offset / (param->numTasks * param->blockSize); + /* Wei-keng Liao: calculate the transfer number in each block */ + transferNum = param->offset % param->blockSize / param->transferSize; - /* Wei-keng Liao: calculate the transfer number in each block */ - transferNum = param->offset % param->blockSize / param->transferSize; + /* Wei-keng Liao: read/write the 3rd dim of the dataset, each is of + amount param->transferSize */ + bufSize[0] = 1; + bufSize[1] = 1; + bufSize[2] = param->transferSize; - /* Wei-keng Liao: read/write the 3rd dim of the dataset, each is of - amount param->transferSize */ - bufSize[0] = 1; - bufSize[1] = 1; - bufSize[2] = param->transferSize; + offset[0] = segmentNum * numTasksWorld + rank; + offset[1] = transferNum; + offset[2] = 0; - offset[0] = segmentNum * numTasksWorld + rank; - offset[1] = transferNum; - offset[2] = 0; - - /* access the file */ - if (access == WRITE) { /* WRITE */ - if (param->collective) { - NCMPI_CHECK(ncmpi_put_vara_all(*(int *)fd, var_id, offset, bufSize, - bufferPtr, length, MPI_BYTE), - "cannot write to data set"); - } else { - NCMPI_CHECK(ncmpi_put_vara(*(int *)fd, var_id, offset, bufSize, - bufferPtr, length, MPI_BYTE), - "cannot write to data set"); + /* access the file */ + if (access == WRITE) { /* WRITE */ + if (param->collective) { + NCMPI_CHECK(ncmpi_put_vara_all + (*(int *)fd, var_id, offset, bufSize, + bufferPtr, length, MPI_BYTE), + "cannot write to data set"); + } else { + NCMPI_CHECK(ncmpi_put_vara + (*(int *)fd, var_id, offset, bufSize, + bufferPtr, length, MPI_BYTE), + "cannot write to data set"); + } + } else { /* READ or CHECK */ + if (param->collective == TRUE) { + NCMPI_CHECK(ncmpi_get_vara_all + (*(int *)fd, var_id, offset, bufSize, + bufferPtr, length, MPI_BYTE), + "cannot read from data set"); + } else { + NCMPI_CHECK(ncmpi_get_vara + (*(int *)fd, var_id, offset, bufSize, + bufferPtr, length, MPI_BYTE), + "cannot read from data set"); + } } - } else { /* READ or CHECK */ - if (param->collective == TRUE) { - NCMPI_CHECK(ncmpi_get_vara_all(*(int *)fd, var_id, offset, bufSize, - bufferPtr, length, MPI_BYTE), - "cannot read from data set"); - } else { - NCMPI_CHECK(ncmpi_get_vara(*(int *)fd, var_id, offset, bufSize, - bufferPtr, length, MPI_BYTE), - "cannot read from data set"); - } - } - - return(length); -} /* IOR_Xfer_NCMPI() */ + return (length); +} /* IOR_Xfer_NCMPI() */ /******************************************************************************/ /* * Perform fsync(). */ -void -IOR_Fsync_NCMPI(void * fd, IOR_param_t * param) +void IOR_Fsync_NCMPI(void *fd, IOR_param_t * param) { - ; -} /* IOR_Fsync_NCMPI() */ - + ; +} /* IOR_Fsync_NCMPI() */ /******************************************************************************/ /* * Close a file through the NCMPI interface. */ -void -IOR_Close_NCMPI(void * fd, - IOR_param_t * param) +void IOR_Close_NCMPI(void *fd, IOR_param_t * param) { - if (param->collective == FALSE) { - NCMPI_CHECK(ncmpi_end_indep_data(*(int *)fd), - "cannot disable independent data mode"); - } - NCMPI_CHECK(ncmpi_close(*(int *)fd), "cannot close file"); - free(fd); -} /* IOR_Close_NCMPI() */ - + if (param->collective == FALSE) { + NCMPI_CHECK(ncmpi_end_indep_data(*(int *)fd), + "cannot disable independent data mode"); + } + NCMPI_CHECK(ncmpi_close(*(int *)fd), "cannot close file"); + free(fd); +} /* IOR_Close_NCMPI() */ /******************************************************************************/ /* * Delete a file through the NCMPI interface. */ -void -IOR_Delete_NCMPI(char * testFileName, IOR_param_t * param) +void IOR_Delete_NCMPI(char *testFileName, IOR_param_t * param) { - if (unlink(testFileName) != 0) - WARN("unlink() failed"); -} /* IOR_Delete_NCMPI() */ - + if (unlink(testFileName) != 0) + WARN("unlink() failed"); +} /* IOR_Delete_NCMPI() */ /******************************************************************************/ /* * Determine api version. */ -void -IOR_SetVersion_NCMPI(IOR_param_t * test) +void IOR_SetVersion_NCMPI(IOR_param_t * test) { - sprintf(test->apiVersion, "%s (%s)", - test->api, ncmpi_inq_libvers()); -} /* IOR_SetVersion_NCMPI() */ - + sprintf(test->apiVersion, "%s (%s)", test->api, ncmpi_inq_libvers()); +} /* IOR_SetVersion_NCMPI() */ /************************ L O C A L F U N C T I O N S ***********************/ @@ -377,38 +362,42 @@ IOR_SetVersion_NCMPI(IOR_param_t * test) * Return the correct file mode for NCMPI. */ -int -GetFileMode(IOR_param_t * param) +int GetFileMode(IOR_param_t * param) { - int fd_mode = 0; + int fd_mode = 0; - /* set IOR file flags to NCMPI flags */ - /* -- file open flags -- */ - if (param->openFlags & IOR_RDONLY) {fd_mode |= NC_NOWRITE;} - if (param->openFlags & IOR_WRONLY) { - fprintf(stdout, "File write only not implemented in NCMPI\n"); - } - if (param->openFlags & IOR_RDWR) {fd_mode |= NC_WRITE;} - if (param->openFlags & IOR_APPEND) { - fprintf(stdout, "File append not implemented in NCMPI\n"); - } - if (param->openFlags & IOR_CREAT) {fd_mode |= NC_CLOBBER;} - if (param->openFlags & IOR_EXCL) { - fprintf(stdout, "Exclusive access not implemented in NCMPI\n"); - } - if (param->openFlags & IOR_TRUNC) { - fprintf(stdout, "File truncation not implemented in NCMPI\n"); - } - if (param->openFlags & IOR_DIRECT) { - fprintf(stdout, "O_DIRECT not implemented in NCMPI\n"); - } + /* set IOR file flags to NCMPI flags */ + /* -- file open flags -- */ + if (param->openFlags & IOR_RDONLY) { + fd_mode |= NC_NOWRITE; + } + if (param->openFlags & IOR_WRONLY) { + fprintf(stdout, "File write only not implemented in NCMPI\n"); + } + if (param->openFlags & IOR_RDWR) { + fd_mode |= NC_WRITE; + } + if (param->openFlags & IOR_APPEND) { + fprintf(stdout, "File append not implemented in NCMPI\n"); + } + if (param->openFlags & IOR_CREAT) { + fd_mode |= NC_CLOBBER; + } + if (param->openFlags & IOR_EXCL) { + fprintf(stdout, "Exclusive access not implemented in NCMPI\n"); + } + if (param->openFlags & IOR_TRUNC) { + fprintf(stdout, "File truncation not implemented in NCMPI\n"); + } + if (param->openFlags & IOR_DIRECT) { + fprintf(stdout, "O_DIRECT not implemented in NCMPI\n"); + } - /* Wei-keng Liao: to enable > 4GB file size */ - fd_mode |= NC_64BIT_OFFSET; - - return(fd_mode); -} /* GetFileMode() */ + /* Wei-keng Liao: to enable > 4GB file size */ + fd_mode |= NC_64BIT_OFFSET; + return (fd_mode); +} /* GetFileMode() */ /******************************************************************************/ /* @@ -416,9 +405,7 @@ GetFileMode(IOR_param_t * param) */ IOR_offset_t -IOR_GetFileSize_NCMPI(IOR_param_t * test, - MPI_Comm testComm, - char * testFileName) +IOR_GetFileSize_NCMPI(IOR_param_t * test, MPI_Comm testComm, char *testFileName) { - return(IOR_GetFileSize_MPIIO(test, testComm, testFileName)); -} /* IOR_GetFileSize_NCMPI() */ + return (IOR_GetFileSize_MPIIO(test, testComm, testFileName)); +} /* IOR_GetFileSize_NCMPI() */ diff --git a/src/aiori-POSIX.c b/src/aiori-POSIX.c index 78a7a3d..973f273 100644 --- a/src/aiori-POSIX.c +++ b/src/aiori-POSIX.c @@ -9,65 +9,64 @@ * \******************************************************************************/ -#include "aiori.h" /* abstract IOR interface */ +#include "aiori.h" /* abstract IOR interface */ #ifdef __linux__ -# include /* necessary for: */ -# define __USE_GNU /* O_DIRECT and */ -# include /* IO operations */ -# undef __USE_GNU -#endif /* __linux__ */ -#include /* sys_errlist */ -#include /* IO operations */ -#include /* only for fprintf() */ +#include /* necessary for: */ +#define __USE_GNU /* O_DIRECT and */ +#include /* IO operations */ +#undef __USE_GNU +#endif /* __linux__ */ +#include /* sys_errlist */ +#include /* IO operations */ +#include /* only for fprintf() */ #include #include #include #ifdef HAVE_LUSTRE_LUSTRE_USER_H -# include -#endif /* HAVE_LUSTRE_LUSTRE_USER_H */ +#include +#endif /* HAVE_LUSTRE_LUSTRE_USER_H */ -#ifndef open64 /* necessary for TRU64 -- */ -# define open64 open /* unlikely, but may pose */ -#endif /* not open64 */ /* conflicting prototypes */ +#ifndef open64 /* necessary for TRU64 -- */ +#define open64 open /* unlikely, but may pose */ +#endif /* not open64 */ /* conflicting prototypes */ -#ifndef lseek64 /* necessary for TRU64 -- */ -# define lseek64 lseek /* unlikely, but may pose */ -#endif /* not lseek64 */ /* conflicting prototypes */ +#ifndef lseek64 /* necessary for TRU64 -- */ +#define lseek64 lseek /* unlikely, but may pose */ +#endif /* not lseek64 */ /* conflicting prototypes */ -#ifndef O_BINARY /* Required on Windows */ -# define O_BINARY 0 +#ifndef O_BINARY /* Required on Windows */ +#define O_BINARY 0 #endif - /**************************** P R O T O T Y P E S *****************************/ -void * IOR_Create_POSIX (char *, IOR_param_t *); -void * IOR_Open_POSIX (char *, IOR_param_t *); -IOR_offset_t IOR_Xfer_POSIX (int, void *, IOR_size_t *, - IOR_offset_t, IOR_param_t *); -void IOR_Close_POSIX (void *, IOR_param_t *); -void IOR_Delete_POSIX (char *, IOR_param_t *); -void IOR_SetVersion_POSIX (IOR_param_t *); -void IOR_Fsync_POSIX (void *, IOR_param_t *); -IOR_offset_t IOR_GetFileSize_POSIX (IOR_param_t *, MPI_Comm, char *); +void *IOR_Create_POSIX(char *, IOR_param_t *); +void *IOR_Open_POSIX(char *, IOR_param_t *); +IOR_offset_t IOR_Xfer_POSIX(int, void *, IOR_size_t *, + IOR_offset_t, IOR_param_t *); +void IOR_Close_POSIX(void *, IOR_param_t *); +void IOR_Delete_POSIX(char *, IOR_param_t *); +void IOR_SetVersion_POSIX(IOR_param_t *); +void IOR_Fsync_POSIX(void *, IOR_param_t *); +IOR_offset_t IOR_GetFileSize_POSIX(IOR_param_t *, MPI_Comm, char *); /************************** D E C L A R A T I O N S ***************************/ ior_aiori_t posix_aiori = { - "POSIX", - IOR_Create_POSIX, - IOR_Open_POSIX, - IOR_Xfer_POSIX, - IOR_Close_POSIX, - IOR_Delete_POSIX, - IOR_SetVersion_POSIX, - IOR_Fsync_POSIX, - IOR_GetFileSize_POSIX + "POSIX", + IOR_Create_POSIX, + IOR_Open_POSIX, + IOR_Xfer_POSIX, + IOR_Close_POSIX, + IOR_Delete_POSIX, + IOR_SetVersion_POSIX, + IOR_Fsync_POSIX, + IOR_GetFileSize_POSIX }; -extern int errno; -extern int rank; -extern int rankOffset; -extern int verbose; +extern int errno; +extern int rank; +extern int rankOffset; +extern int verbose; extern MPI_Comm testComm; /***************************** F U N C T I O N S ******************************/ @@ -77,15 +76,15 @@ void set_o_direct_flag(int *fd) /* note that TRU64 needs O_DIRECTIO, SunOS uses directio(), and everyone else needs O_DIRECT */ #ifndef O_DIRECT -# ifndef O_DIRECTIO - WARN("cannot use O_DIRECT"); -# define O_DIRECT 000000 -# else /* O_DIRECTIO */ -# define O_DIRECT O_DIRECTIO -# endif /* not O_DIRECTIO */ -#endif /* not O_DIRECT */ +#ifndef O_DIRECTIO + WARN("cannot use O_DIRECT"); +#define O_DIRECT 000000 +#else /* O_DIRECTIO */ +#define O_DIRECT O_DIRECTIO +#endif /* not O_DIRECTIO */ +#endif /* not O_DIRECT */ - *fd |= O_DIRECT; + *fd |= O_DIRECT; } /******************************************************************************/ @@ -93,112 +92,117 @@ void set_o_direct_flag(int *fd) * Creat and open a file through the POSIX interface. */ -void * -IOR_Create_POSIX(char * testFileName, - IOR_param_t * param) +void *IOR_Create_POSIX(char *testFileName, IOR_param_t * param) { - int fd_oflag = O_BINARY; - int *fd; + int fd_oflag = O_BINARY; + int *fd; - fd = (int *)malloc(sizeof(int)); - if (fd == NULL) ERR("Unable to malloc file descriptor"); + fd = (int *)malloc(sizeof(int)); + if (fd == NULL) + ERR("Unable to malloc file descriptor"); - if (param->useO_DIRECT == TRUE) - set_o_direct_flag(&fd_oflag); + if (param->useO_DIRECT == TRUE) + set_o_direct_flag(&fd_oflag); #ifdef HAVE_LUSTRE_LUSTRE_USER_H - if (param->lustre_set_striping) { - /* In the single-shared-file case, task 0 has to creat the - file with the Lustre striping options before any other processes - open the file */ - if (!param->filePerProc && rank != 0) { - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - fd_oflag |= O_RDWR; - *fd = open64(testFileName, fd_oflag, 0664); - if (*fd < 0) ERR("open64() failed"); + if (param->lustre_set_striping) { + /* In the single-shared-file case, task 0 has to creat the + file with the Lustre striping options before any other processes + open the file */ + if (!param->filePerProc && rank != 0) { + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + fd_oflag |= O_RDWR; + *fd = open64(testFileName, fd_oflag, 0664); + if (*fd < 0) + ERR("open64() failed"); + } else { + struct lov_user_md opts = { 0 }; + + /* Setup Lustre IOCTL striping pattern structure */ + opts.lmm_magic = LOV_USER_MAGIC; + opts.lmm_stripe_size = param->lustre_stripe_size; + opts.lmm_stripe_offset = param->lustre_start_ost; + opts.lmm_stripe_count = param->lustre_stripe_count; + + /* File needs to be opened O_EXCL because we cannot set + Lustre striping information on a pre-existing file. */ + fd_oflag |= + O_CREAT | O_EXCL | O_RDWR | O_LOV_DELAY_CREATE; + *fd = open64(testFileName, fd_oflag, 0664); + if (*fd < 0) { + fprintf(stdout, "\nUnable to open '%s': %s\n", + testFileName, strerror(errno)); + MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), + "MPI_Abort() error"); + } else if (ioctl(*fd, LL_IOC_LOV_SETSTRIPE, &opts)) { + char *errmsg = "stripe already set"; + if (errno != EEXIST && errno != EALREADY) + errmsg = strerror(errno); + fprintf(stdout, + "\nError on ioctl for '%s' (%d): %s\n", + testFileName, *fd, errmsg); + MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), + "MPI_Abort() error"); + } + if (!param->filePerProc) + MPI_CHECK(MPI_Barrier(testComm), + "barrier error"); + } } else { - struct lov_user_md opts = { 0 }; - - /* Setup Lustre IOCTL striping pattern structure */ - opts.lmm_magic = LOV_USER_MAGIC; - opts.lmm_stripe_size = param->lustre_stripe_size; - opts.lmm_stripe_offset = param->lustre_start_ost; - opts.lmm_stripe_count = param->lustre_stripe_count; - - /* File needs to be opened O_EXCL because we cannot set - Lustre striping information on a pre-existing file. */ - fd_oflag |= O_CREAT | O_EXCL | O_RDWR | O_LOV_DELAY_CREATE; - *fd = open64(testFileName, fd_oflag, 0664); - if (*fd < 0) { - fprintf(stdout, "\nUnable to open '%s': %s\n", - testFileName, strerror(errno)); - MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); - } else if (ioctl(*fd, LL_IOC_LOV_SETSTRIPE, &opts)) { - char *errmsg = "stripe already set"; - if (errno != EEXIST && errno != EALREADY) - errmsg = strerror(errno); - fprintf(stdout, "\nError on ioctl for '%s' (%d): %s\n", - testFileName, *fd, errmsg); - MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); - } - if (!param->filePerProc) - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - } - } else { -#endif /* HAVE_LUSTRE_LUSTRE_USER_H */ - fd_oflag |= O_CREAT | O_RDWR; - *fd = open64(testFileName, fd_oflag, 0664); - if (*fd < 0) ERR("open64() failed"); +#endif /* HAVE_LUSTRE_LUSTRE_USER_H */ + fd_oflag |= O_CREAT | O_RDWR; + *fd = open64(testFileName, fd_oflag, 0664); + if (*fd < 0) + ERR("open64() failed"); #ifdef HAVE_LUSTRE_LUSTRE_USER_H - } - - if (param->lustre_ignore_locks) { - int lustre_ioctl_flags = LL_FILE_IGNORE_LOCK; - if (ioctl(*fd, LL_IOC_SETFLAGS, &lustre_ioctl_flags) == -1) - ERR("ioctl(LL_IOC_SETFLAGS) failed"); - } -#endif /* HAVE_LUSTRE_LUSTRE_USER_H */ + } - return((void *)fd); -} /* IOR_Create_POSIX() */ + if (param->lustre_ignore_locks) { + int lustre_ioctl_flags = LL_FILE_IGNORE_LOCK; + if (ioctl(*fd, LL_IOC_SETFLAGS, &lustre_ioctl_flags) == -1) + ERR("ioctl(LL_IOC_SETFLAGS) failed"); + } +#endif /* HAVE_LUSTRE_LUSTRE_USER_H */ + return ((void *)fd); +} /* IOR_Create_POSIX() */ /******************************************************************************/ /* * Open a file through the POSIX interface. */ -void * -IOR_Open_POSIX(char * testFileName, - IOR_param_t * param) +void *IOR_Open_POSIX(char *testFileName, IOR_param_t * param) { - int fd_oflag = O_BINARY; - int *fd; + int fd_oflag = O_BINARY; + int *fd; - fd = (int *)malloc(sizeof(int)); - if (fd == NULL) ERR("Unable to malloc file descriptor"); + fd = (int *)malloc(sizeof(int)); + if (fd == NULL) + ERR("Unable to malloc file descriptor"); - if (param->useO_DIRECT == TRUE) - set_o_direct_flag(&fd_oflag); + if (param->useO_DIRECT == TRUE) + set_o_direct_flag(&fd_oflag); - fd_oflag |= O_RDWR; - *fd = open64(testFileName, fd_oflag); - if (*fd < 0) ERR("open64 failed"); + fd_oflag |= O_RDWR; + *fd = open64(testFileName, fd_oflag); + if (*fd < 0) + ERR("open64 failed"); #ifdef HAVE_LUSTRE_LUSTRE_USER_H - if (param->lustre_ignore_locks) { - int lustre_ioctl_flags = LL_FILE_IGNORE_LOCK; - if (verbose >= VERBOSE_1) { - fprintf(stdout, "** Disabling lustre range locking **\n"); + if (param->lustre_ignore_locks) { + int lustre_ioctl_flags = LL_FILE_IGNORE_LOCK; + if (verbose >= VERBOSE_1) { + fprintf(stdout, + "** Disabling lustre range locking **\n"); + } + if (ioctl(*fd, LL_IOC_SETFLAGS, &lustre_ioctl_flags) == -1) + ERR("ioctl(LL_IOC_SETFLAGS) failed"); } - if (ioctl(*fd, LL_IOC_SETFLAGS, &lustre_ioctl_flags) == -1) - ERR("ioctl(LL_IOC_SETFLAGS) failed"); - } -#endif /* HAVE_LUSTRE_LUSTRE_USER_H */ - - return((void *)fd); -} /* IOR_Open_POSIX() */ +#endif /* HAVE_LUSTRE_LUSTRE_USER_H */ + return ((void *)fd); +} /* IOR_Open_POSIX() */ /******************************************************************************/ /* @@ -206,123 +210,117 @@ IOR_Open_POSIX(char * testFileName, */ IOR_offset_t -IOR_Xfer_POSIX(int access, - void * file, - IOR_size_t * buffer, - IOR_offset_t length, - IOR_param_t * param) +IOR_Xfer_POSIX(int access, + void *file, + IOR_size_t * buffer, IOR_offset_t length, IOR_param_t * param) { - int xferRetries = 0; - long long remaining = (long long)length; - char * ptr = (char *)buffer; - long long rc; - int fd; + int xferRetries = 0; + long long remaining = (long long)length; + char *ptr = (char *)buffer; + long long rc; + int fd; - fd = *(int *)file; + fd = *(int *)file; - /* seek to offset */ - if (lseek64(fd, param->offset, SEEK_SET) == -1) - ERR("lseek64() failed"); + /* seek to offset */ + if (lseek64(fd, param->offset, SEEK_SET) == -1) + ERR("lseek64() failed"); - while (remaining > 0) { - /* write/read file */ - if (access == WRITE) { /* WRITE */ - if (verbose >= VERBOSE_4) { - fprintf(stdout, "task %d writing to offset %lld\n", - rank, param->offset + length - remaining); - } - rc = write(fd, ptr, remaining); - if (param->fsyncPerWrite == TRUE) - IOR_Fsync_POSIX(&fd, param); - if (rc == -1) - ERR("write() failed"); - } else { /* READ or CHECK */ - if (verbose >= VERBOSE_4) { - fprintf(stdout, "task %d reading from offset %lld\n", - rank, param->offset + length - remaining); - } - rc = read(fd, ptr, remaining); - if (rc == 0) - ERR("read() returned EOF prematurely"); - if (rc == -1) - ERR("read() failed"); + while (remaining > 0) { + /* write/read file */ + if (access == WRITE) { /* WRITE */ + if (verbose >= VERBOSE_4) { + fprintf(stdout, + "task %d writing to offset %lld\n", + rank, + param->offset + length - remaining); + } + rc = write(fd, ptr, remaining); + if (param->fsyncPerWrite == TRUE) + IOR_Fsync_POSIX(&fd, param); + if (rc == -1) + ERR("write() failed"); + } else { /* READ or CHECK */ + if (verbose >= VERBOSE_4) { + fprintf(stdout, + "task %d reading from offset %lld\n", + rank, + param->offset + length - remaining); + } + rc = read(fd, ptr, remaining); + if (rc == 0) + ERR("read() returned EOF prematurely"); + if (rc == -1) + ERR("read() failed"); + } + if (rc < remaining) { + fprintf(stdout, + "WARNING: Task %d, partial %s, %lld of %lld bytes at offset %lld\n", + rank, + access == WRITE ? "write()" : "read()", + rc, remaining, + param->offset + length - remaining); + if (param->singleXferAttempt == TRUE) + MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), + "barrier error"); + if (xferRetries > MAX_RETRY) + ERR("too many retries -- aborting"); + } + assert(rc >= 0); + assert(rc <= remaining); + remaining -= rc; + ptr += rc; + xferRetries++; } - if (rc < remaining) { - fprintf(stdout, - "WARNING: Task %d, partial %s, %lld of %lld bytes at offset %lld\n", - rank, - access == WRITE ? "write()" : "read()", - rc, remaining, - param->offset+length-remaining); - if (param->singleXferAttempt == TRUE) - MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "barrier error"); - if (xferRetries > MAX_RETRY) - ERR("too many retries -- aborting"); - } - assert(rc >= 0); - assert(rc <= remaining); - remaining -= rc; - ptr += rc; - xferRetries++; - } - return(length); -} /* IOR_Xfer_POSIX() */ - + return (length); +} /* IOR_Xfer_POSIX() */ /******************************************************************************/ /* * Perform fsync(). */ -void -IOR_Fsync_POSIX(void * fd, IOR_param_t * param) +void IOR_Fsync_POSIX(void *fd, IOR_param_t * param) { - if (fsync(*(int *)fd) != 0) - WARN("fsync() failed"); -} /* IOR_Fsync_POSIX() */ - + if (fsync(*(int *)fd) != 0) + WARN("fsync() failed"); +} /* IOR_Fsync_POSIX() */ /******************************************************************************/ /* * Close a file through the POSIX interface. */ -void -IOR_Close_POSIX(void *fd, - IOR_param_t * param) +void IOR_Close_POSIX(void *fd, IOR_param_t * param) { - if (close(*(int *)fd) != 0) - ERR("close() failed"); - free(fd); -} /* IOR_Close_POSIX() */ - + if (close(*(int *)fd) != 0) + ERR("close() failed"); + free(fd); +} /* IOR_Close_POSIX() */ /******************************************************************************/ /* * Delete a file through the POSIX interface. */ -void -IOR_Delete_POSIX(char * testFileName, IOR_param_t * param) +void IOR_Delete_POSIX(char *testFileName, IOR_param_t * param) { - char errmsg[256]; - sprintf(errmsg,"[RANK %03d]: unlink() of file \"%s\" failed\n", - rank, testFileName); - if (unlink(testFileName) != 0) WARN(errmsg); -} /* IOR_Delete_POSIX() */ - + char errmsg[256]; + sprintf(errmsg, "[RANK %03d]: unlink() of file \"%s\" failed\n", + rank, testFileName); + if (unlink(testFileName) != 0) + WARN(errmsg); +} /* IOR_Delete_POSIX() */ /******************************************************************************/ /* * Determine api version. */ -void -IOR_SetVersion_POSIX(IOR_param_t *test) +void IOR_SetVersion_POSIX(IOR_param_t * test) { - strcpy(test->apiVersion, test->api); -} /* IOR_SetVersion_POSIX() */ - + strcpy(test->apiVersion, test->api); +} /* IOR_SetVersion_POSIX() */ /******************************************************************************/ /* @@ -330,39 +328,36 @@ IOR_SetVersion_POSIX(IOR_param_t *test) */ IOR_offset_t -IOR_GetFileSize_POSIX(IOR_param_t * test, - MPI_Comm testComm, - char * testFileName) +IOR_GetFileSize_POSIX(IOR_param_t * test, MPI_Comm testComm, char *testFileName) { - struct stat stat_buf; - IOR_offset_t aggFileSizeFromStat, - tmpMin, tmpMax, tmpSum; + struct stat stat_buf; + IOR_offset_t aggFileSizeFromStat, tmpMin, tmpMax, tmpSum; - if (stat(testFileName, &stat_buf) != 0) { - ERR("stat() failed"); - } - aggFileSizeFromStat = stat_buf.st_size; - - if (test->filePerProc == TRUE) { - MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpSum, 1, - MPI_LONG_LONG_INT, MPI_SUM, testComm), - "cannot total data moved"); - aggFileSizeFromStat = tmpSum; - } else { - MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMin, 1, - MPI_LONG_LONG_INT, MPI_MIN, testComm), - "cannot total data moved"); - MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMax, 1, - MPI_LONG_LONG_INT, MPI_MAX, testComm), - "cannot total data moved"); - if (tmpMin != tmpMax) { - if (rank == 0) { - WARN("inconsistent file size by different tasks"); - } - /* incorrect, but now consistent across tasks */ - aggFileSizeFromStat = tmpMin; + if (stat(testFileName, &stat_buf) != 0) { + ERR("stat() failed"); } - } + aggFileSizeFromStat = stat_buf.st_size; - return(aggFileSizeFromStat); -} /* IOR_GetFileSize_POSIX() */ + if (test->filePerProc == TRUE) { + MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpSum, 1, + MPI_LONG_LONG_INT, MPI_SUM, testComm), + "cannot total data moved"); + aggFileSizeFromStat = tmpSum; + } else { + MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMin, 1, + MPI_LONG_LONG_INT, MPI_MIN, testComm), + "cannot total data moved"); + MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMax, 1, + MPI_LONG_LONG_INT, MPI_MAX, testComm), + "cannot total data moved"); + if (tmpMin != tmpMax) { + if (rank == 0) { + WARN("inconsistent file size by different tasks"); + } + /* incorrect, but now consistent across tasks */ + aggFileSizeFromStat = tmpMin; + } + } + + return (aggFileSizeFromStat); +} /* IOR_GetFileSize_POSIX() */ diff --git a/src/ior.c b/src/ior.c index b56edf9..8e9a84b 100644 --- a/src/ior.c +++ b/src/ior.c @@ -5,38 +5,38 @@ * * \******************************************************************************/ -#include "aiori.h" /* IOR I/O interfaces */ -#include "ior.h" /* IOR definitions - and prototypes */ -#include /* tolower() */ -#include /* sys_errlist */ +#include "aiori.h" /* IOR I/O interfaces */ +#include "ior.h" /* IOR definitions + and prototypes */ +#include /* tolower() */ +#include /* sys_errlist */ #include #include #include #include #include -#include /* struct stat */ +#include /* struct stat */ #include #ifndef _WIN32 -# include /* gettimeofday() */ -# include /* uname() */ +#include /* gettimeofday() */ +#include /* uname() */ #endif #include /************************** D E C L A R A T I O N S ***************************/ extern IOR_param_t initialTestParams; -extern int errno; /* error number */ -extern char ** environ; -int totalErrorCount = 0; -int numTasksWorld = 0; -int rank = 0; -int rankOffset = 0; -int tasksPerNode = 0; /* tasks per node */ -int verbose = VERBOSE_0; /* verbose output */ -double wall_clock_delta = 0; -double wall_clock_deviation; -MPI_Comm testComm; +extern int errno; /* error number */ +extern char **environ; +int totalErrorCount = 0; +int numTasksWorld = 0; +int rank = 0; +int rankOffset = 0; +int tasksPerNode = 0; /* tasks per node */ +int verbose = VERBOSE_0; /* verbose output */ +double wall_clock_delta = 0; +double wall_clock_deviation; +MPI_Comm testComm; ior_aiori_t *backend; @@ -55,101 +55,98 @@ extern ior_aiori_t ncmpi_aiori; ior_aiori_t *available_aiori[] = { #ifdef USE_POSIX_AIORI - &posix_aiori, + &posix_aiori, #endif #ifdef USE_MPIIO_AIORI - &mpiio_aiori, + &mpiio_aiori, #endif #ifdef USE_HDF5_AIORI - &hdf5_aiori, + &hdf5_aiori, #endif #ifdef USE_NCMPI_AIORI - &ncmpi_aiori, + &ncmpi_aiori, #endif - NULL + NULL }; /********************************** M A I N ***********************************/ -int -main(int argc, - char ** argv) +int main(int argc, char **argv) { - int i; - IOR_queue_t * tests; + int i; + IOR_queue_t *tests; - /* - * check -h option from commandline without starting MPI; - * if the help option is requested in a script file (showHelp=TRUE), - * the help output will be displayed in the MPI job - */ - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-h") == 0) { - DisplayUsage(argv); - return(0); + /* + * check -h option from commandline without starting MPI; + * if the help option is requested in a script file (showHelp=TRUE), + * the help output will be displayed in the MPI job + */ + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-h") == 0) { + DisplayUsage(argv); + return (0); + } } - } - /* start the MPI code */ - MPI_CHECK(MPI_Init(&argc, &argv), "cannot initialize MPI"); - MPI_CHECK(MPI_Comm_size(MPI_COMM_WORLD, &numTasksWorld), - "cannot get number of tasks"); - MPI_CHECK(MPI_Comm_rank(MPI_COMM_WORLD, &rank), "cannot get rank"); - /* set error-handling */ - /*MPI_CHECK(MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN), - "cannot set errhandler");*/ - - /* Sanity check, we were compiled with SOME backend, right? */ - if (available_aiori[0] == NULL) { - ERR("No IO backends compiled into ior. That should not have happened."); - } + /* start the MPI code */ + MPI_CHECK(MPI_Init(&argc, &argv), "cannot initialize MPI"); + MPI_CHECK(MPI_Comm_size(MPI_COMM_WORLD, &numTasksWorld), + "cannot get number of tasks"); + MPI_CHECK(MPI_Comm_rank(MPI_COMM_WORLD, &rank), "cannot get rank"); + /* set error-handling */ + /*MPI_CHECK(MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN), + "cannot set errhandler"); */ - /* setup tests before verifying test validity */ - tests = SetupTests(argc, argv); - verbose = tests->testParameters.verbose; - tests->testParameters.testComm = MPI_COMM_WORLD; - - /* check for commandline usage */ - if (rank == 0 && tests->testParameters.showHelp == TRUE) { - DisplayUsage(argv); - } - - /* perform each test */ - while (tests != NULL) { - verbose = tests->testParameters.verbose; - if (rank == 0 && verbose >= VERBOSE_0) { - ShowInfo(argc, argv, &tests->testParameters); - } - if (rank == 0 && verbose >= VERBOSE_3) { - ShowTest(&tests->testParameters); - } - TestIoSys(&tests->testParameters); - tests = tests->nextTest; - } + /* Sanity check, we were compiled with SOME backend, right? */ + if (available_aiori[0] == NULL) { + ERR("No IO backends compiled into ior. That should not have happened."); + } - /* display finish time */ - if (rank == 0 && verbose >= VERBOSE_0) { - fprintf(stdout, "Run finished: %s", CurrentTimeString()); - } + /* setup tests before verifying test validity */ + tests = SetupTests(argc, argv); + verbose = tests->testParameters.verbose; + tests->testParameters.testComm = MPI_COMM_WORLD; - MPI_CHECK(MPI_Finalize(), "cannot finalize MPI"); + /* check for commandline usage */ + if (rank == 0 && tests->testParameters.showHelp == TRUE) { + DisplayUsage(argv); + } - return(totalErrorCount); + /* perform each test */ + while (tests != NULL) { + verbose = tests->testParameters.verbose; + if (rank == 0 && verbose >= VERBOSE_0) { + ShowInfo(argc, argv, &tests->testParameters); + } + if (rank == 0 && verbose >= VERBOSE_3) { + ShowTest(&tests->testParameters); + } + TestIoSys(&tests->testParameters); + tests = tests->nextTest; + } -} /* main() */ + /* display finish time */ + if (rank == 0 && verbose >= VERBOSE_0) { + fprintf(stdout, "Run finished: %s", CurrentTimeString()); + } + MPI_CHECK(MPI_Finalize(), "cannot finalize MPI"); + + return (totalErrorCount); + +} /* main() */ /***************************** F U N C T I O N S ******************************/ /* * Initialize an IOR_param_t structure to the defaults */ -void init_IOR_Param_t(IOR_param_t *p) +void init_IOR_Param_t(IOR_param_t * p) { memset(p, 0, sizeof(IOR_param_t)); - p->mode = IOR_IRUSR|IOR_IWUSR|IOR_IRGRP|IOR_IWGRP; - p->openFlags = IOR_RDWR|IOR_CREAT; + p->mode = IOR_IRUSR | IOR_IWUSR | IOR_IRGRP | IOR_IWGRP; + p->openFlags = IOR_RDWR | IOR_CREAT; p->TestNum = -1; assert(available_aiori[0] != NULL); strncpy(p->api, available_aiori[0]->name, MAX_STR); @@ -176,25 +173,23 @@ void init_IOR_Param_t(IOR_param_t *p) * function table. */ -void -AioriBind(char * api) +void AioriBind(char *api) { - ior_aiori_t **tmp; + ior_aiori_t **tmp; - backend = NULL; - for (tmp = available_aiori; *tmp != NULL; tmp++) { - if (strcmp(api, (*tmp)->name) == 0) { - backend = *tmp; - break; + backend = NULL; + for (tmp = available_aiori; *tmp != NULL; tmp++) { + if (strcmp(api, (*tmp)->name) == 0) { + backend = *tmp; + break; + } } - } - if (backend == NULL) { - ERR("unrecognized IO API"); - } - -} /* AioriBind() */ + if (backend == NULL) { + ERR("unrecognized IO API"); + } +} /* AioriBind() */ /******************************************************************************/ /* @@ -202,73 +197,71 @@ AioriBind(char * api) */ void -DisplayOutliers(int numTasks, +DisplayOutliers(int numTasks, double timerVal, - char * timeString, - int access, - int outlierThreshold) + char *timeString, int access, int outlierThreshold) { - char accessString[MAX_STR]; - double sum, mean, sqrDiff, var, sd; + char accessString[MAX_STR]; + double sum, mean, sqrDiff, var, sd; - /* for local timerVal, don't compensate for wall clock delta */ - timerVal += wall_clock_delta; + /* for local timerVal, don't compensate for wall clock delta */ + timerVal += wall_clock_delta; - MPI_CHECK(MPI_Allreduce(&timerVal, &sum, 1, MPI_DOUBLE, MPI_SUM, testComm), - "MPI_Allreduce()"); - mean = sum / numTasks; - sqrDiff = pow((mean - timerVal), 2); - MPI_CHECK(MPI_Allreduce(&sqrDiff, &var, 1, MPI_DOUBLE, MPI_SUM, testComm), - "MPI_Allreduce()"); - var = var / numTasks; - sd = sqrt(var); - - if (access == WRITE) { - strcpy(accessString, "write"); - } else { /* READ */ - strcpy(accessString, "read"); - } - if (fabs(timerVal - mean) > (double)outlierThreshold){ - fprintf(stdout, "WARNING: for task %d, %s %s is %f\n", - rank, accessString, timeString, timerVal); - fprintf(stdout, " (mean=%f, stddev=%f)\n", mean, sd); - fflush(stdout); - } -} /* DisplayOutliers() */ + MPI_CHECK(MPI_Allreduce + (&timerVal, &sum, 1, MPI_DOUBLE, MPI_SUM, testComm), + "MPI_Allreduce()"); + mean = sum / numTasks; + sqrDiff = pow((mean - timerVal), 2); + MPI_CHECK(MPI_Allreduce + (&sqrDiff, &var, 1, MPI_DOUBLE, MPI_SUM, testComm), + "MPI_Allreduce()"); + var = var / numTasks; + sd = sqrt(var); + if (access == WRITE) { + strcpy(accessString, "write"); + } else { /* READ */ + strcpy(accessString, "read"); + } + if (fabs(timerVal - mean) > (double)outlierThreshold) { + fprintf(stdout, "WARNING: for task %d, %s %s is %f\n", + rank, accessString, timeString, timerVal); + fprintf(stdout, " (mean=%f, stddev=%f)\n", mean, sd); + fflush(stdout); + } +} /* DisplayOutliers() */ /******************************************************************************/ /* * Check for outliers in start/end times and elapsed create/xfer/close times. */ -void -CheckForOutliers(IOR_param_t * test, - double ** timer, - int rep, - int access) +void CheckForOutliers(IOR_param_t * test, double **timer, int rep, int access) { - int shift; + int shift; - if (access == WRITE) { - shift = 0; - } else { /* READ */ - shift = 6; - } + if (access == WRITE) { + shift = 0; + } else { /* READ */ + shift = 6; + } - DisplayOutliers(test->numTasks, timer[shift+0][rep], - "start time", access, test->outlierThreshold); - DisplayOutliers(test->numTasks, timer[shift+1][rep]-timer[shift+0][rep], - "elapsed create time", access, test->outlierThreshold); - DisplayOutliers(test->numTasks, timer[shift+3][rep]-timer[shift+2][rep], - "elapsed transfer time", access, test->outlierThreshold); - DisplayOutliers(test->numTasks, timer[shift+5][rep]-timer[shift+4][rep], - "elapsed close time", access, test->outlierThreshold); - DisplayOutliers(test->numTasks, timer[shift+5][rep], - "end time", access, test->outlierThreshold); - -} /* CheckForOutliers() */ + DisplayOutliers(test->numTasks, timer[shift + 0][rep], + "start time", access, test->outlierThreshold); + DisplayOutliers(test->numTasks, + timer[shift + 1][rep] - timer[shift + 0][rep], + "elapsed create time", access, test->outlierThreshold); + DisplayOutliers(test->numTasks, + timer[shift + 3][rep] - timer[shift + 2][rep], + "elapsed transfer time", access, + test->outlierThreshold); + DisplayOutliers(test->numTasks, + timer[shift + 5][rep] - timer[shift + 4][rep], + "elapsed close time", access, test->outlierThreshold); + DisplayOutliers(test->numTasks, timer[shift + 5][rep], "end time", + access, test->outlierThreshold); +} /* CheckForOutliers() */ /******************************************************************************/ /* @@ -276,56 +269,52 @@ CheckForOutliers(IOR_param_t * test, * calculating performance rate. */ -void -CheckFileSize(IOR_param_t *test, - IOR_offset_t dataMoved, - int rep) +void CheckFileSize(IOR_param_t * test, IOR_offset_t dataMoved, int rep) { - MPI_CHECK(MPI_Allreduce(&dataMoved, &test->aggFileSizeFromXfer[rep], - 1, MPI_LONG_LONG_INT, MPI_SUM, testComm), - "cannot total data moved"); + MPI_CHECK(MPI_Allreduce(&dataMoved, &test->aggFileSizeFromXfer[rep], + 1, MPI_LONG_LONG_INT, MPI_SUM, testComm), + "cannot total data moved"); - if (strcmp(test->api, "HDF5") != 0 && strcmp(test->api, "NCMPI") != 0) { - if (verbose >= VERBOSE_0 && rank == 0) { - if ((test->aggFileSizeFromCalc[rep] - != test->aggFileSizeFromXfer[rep]) - || - (test->aggFileSizeFromStat[rep] - != test->aggFileSizeFromXfer[rep])) { - fprintf(stdout, - "WARNING: Expected aggregate file size = %lld.\n", - (long long)test->aggFileSizeFromCalc[rep]); - fprintf(stdout, - "WARNING: Stat() of aggregate file size = %lld.\n", - (long long)test->aggFileSizeFromStat[rep]); - fprintf(stdout, - "WARNING: Using actual aggregate bytes moved = %lld.\n", - (long long)test->aggFileSizeFromXfer[rep]); - } + if (strcmp(test->api, "HDF5") != 0 && strcmp(test->api, "NCMPI") != 0) { + if (verbose >= VERBOSE_0 && rank == 0) { + if ((test->aggFileSizeFromCalc[rep] + != test->aggFileSizeFromXfer[rep]) + || (test->aggFileSizeFromStat[rep] + != test->aggFileSizeFromXfer[rep])) { + fprintf(stdout, + "WARNING: Expected aggregate file size = %lld.\n", + (long long) + test->aggFileSizeFromCalc[rep]); + fprintf(stdout, + "WARNING: Stat() of aggregate file size = %lld.\n", + (long long) + test->aggFileSizeFromStat[rep]); + fprintf(stdout, + "WARNING: Using actual aggregate bytes moved = %lld.\n", + (long long) + test->aggFileSizeFromXfer[rep]); + } + } } - } - test->aggFileSizeForBW[rep] = test->aggFileSizeFromXfer[rep]; - -} /* CheckFileSize() */ + test->aggFileSizeForBW[rep] = test->aggFileSizeFromXfer[rep]; +} /* CheckFileSize() */ /******************************************************************************/ /* * Check if string is true or false. */ -char * -CheckTorF(char * string) +char *CheckTorF(char *string) { - string = LowerCase(string); - if (strcmp(string, "false") == 0) { - strcpy(string, "0"); - } else if (strcmp(string, "true") == 0) { - strcpy(string, "1"); - } - return(string); -} /* CheckTorF() */ - + string = LowerCase(string); + if (strcmp(string, "false") == 0) { + strcpy(string, "0"); + } else if (strcmp(string, "true") == 0) { + strcpy(string, "1"); + } + return (string); +} /* CheckTorF() */ /******************************************************************************/ /* @@ -334,417 +323,412 @@ CheckTorF(char * string) */ size_t -CompareBuffers(void * expectedBuffer, - void * unknownBuffer, - size_t size, - IOR_offset_t transferCount, - IOR_param_t * test, - int access) +CompareBuffers(void *expectedBuffer, + void *unknownBuffer, + size_t size, + IOR_offset_t transferCount, IOR_param_t * test, int access) { - char testFileName[MAXPATHLEN], - bufferLabel1[MAX_STR], - bufferLabel2[MAX_STR]; - size_t i, j, length, first, last; - size_t errorCount = 0; - int inError = 0; - unsigned long long *goodbuf = (unsigned long long *)expectedBuffer; - unsigned long long *testbuf = (unsigned long long *)unknownBuffer; + char testFileName[MAXPATHLEN], + bufferLabel1[MAX_STR], bufferLabel2[MAX_STR]; + size_t i, j, length, first, last; + size_t errorCount = 0; + int inError = 0; + unsigned long long *goodbuf = (unsigned long long *)expectedBuffer; + unsigned long long *testbuf = (unsigned long long *)unknownBuffer; - if (access == WRITECHECK) { - strcpy(bufferLabel1, "Expected: "); - strcpy(bufferLabel2, "Actual: "); - } else if (access == READCHECK) { - strcpy(bufferLabel1, "1st Read: "); - strcpy(bufferLabel2, "2nd Read: "); - } else { - ERR("incorrect argument for CompareBuffers()"); - } - - length = size / sizeof(IOR_size_t); - first = -1; - if (verbose >= VERBOSE_3) { - fprintf(stdout, - "[%d] At file byte offset %lld, comparing %llu-byte transfer\n", - rank, test->offset, (long long)size); - } - for (i = 0; i < length; i++) { - if (testbuf[i] != goodbuf[i]) { - errorCount++; - if (verbose >= VERBOSE_2) { - fprintf(stdout, - "[%d] At transfer buffer #%lld, index #%lld (file byte offset %lld):\n", - rank, transferCount-1, (long long)i, - test->offset + (IOR_size_t)(i * sizeof(IOR_size_t))); - fprintf(stdout, "[%d] %s0x", rank, bufferLabel1); - fprintf(stdout, "%016llx\n", goodbuf[i]); - fprintf(stdout, "[%d] %s0x", rank, bufferLabel2); - fprintf(stdout, "%016llx\n", testbuf[i]); - } - if (!inError) { - inError = 1; - first = i; - last = i; - } else { - last = i; - } - } else if (verbose >= VERBOSE_5 && i % 4 == 0) { - fprintf(stdout, "[%d] PASSED offset = %lld bytes, transfer %lld\n", - rank, ((i * sizeof(unsigned long long)) + test->offset), - transferCount); - fprintf(stdout, "[%d] GOOD %s0x", rank, bufferLabel1); - for (j = 0; j < 4; j++) - fprintf(stdout, "%016llx ", goodbuf[i + j]); - fprintf(stdout, "\n[%d] GOOD %s0x", rank, bufferLabel2); - for (j = 0; j < 4; j++) - fprintf(stdout, "%016llx ", testbuf[i + j]); - fprintf(stdout, "\n"); + if (access == WRITECHECK) { + strcpy(bufferLabel1, "Expected: "); + strcpy(bufferLabel2, "Actual: "); + } else if (access == READCHECK) { + strcpy(bufferLabel1, "1st Read: "); + strcpy(bufferLabel2, "2nd Read: "); + } else { + ERR("incorrect argument for CompareBuffers()"); } - } - if (inError) { - inError = 0; - GetTestFileName(testFileName, test); - fprintf(stdout, - "[%d] FAILED comparison of buffer containing %d-byte ints:\n", - rank, (int)sizeof(unsigned long long int)); - fprintf(stdout, "[%d] File name = %s\n", rank, testFileName); - fprintf(stdout, "[%d] In transfer %lld, ", - rank, transferCount); - fprintf(stdout, "%lld errors between buffer indices %lld and %lld.\n", - (long long)errorCount, (long long)first, (long long)last); - fprintf(stdout, "[%d] File byte offset = %lld:\n", - rank, ((first * sizeof(unsigned long long)) + test->offset)); - fprintf(stdout, "[%d] %s0x", rank, bufferLabel1); - for (j = first; j < length && j < first + 4; j++) - fprintf(stdout, "%016llx ", goodbuf[j]); - if (j == length) fprintf(stdout, "[end of buffer]"); - fprintf(stdout, "\n[%d] %s0x", rank, bufferLabel2); - for (j = first; j < length && j < first + 4; j++) - fprintf(stdout, "%016llx ", testbuf[j]); - if (j == length) fprintf(stdout, "[end of buffer]"); - fprintf(stdout, "\n"); - if (test->quitOnError == TRUE) - ERR("data check error, aborting execution"); - } - return(errorCount); -} /* CompareBuffers() */ + length = size / sizeof(IOR_size_t); + first = -1; + if (verbose >= VERBOSE_3) { + fprintf(stdout, + "[%d] At file byte offset %lld, comparing %llu-byte transfer\n", + rank, test->offset, (long long)size); + } + for (i = 0; i < length; i++) { + if (testbuf[i] != goodbuf[i]) { + errorCount++; + if (verbose >= VERBOSE_2) { + fprintf(stdout, + "[%d] At transfer buffer #%lld, index #%lld (file byte offset %lld):\n", + rank, transferCount - 1, (long long)i, + test->offset + + (IOR_size_t) (i * sizeof(IOR_size_t))); + fprintf(stdout, "[%d] %s0x", rank, + bufferLabel1); + fprintf(stdout, "%016llx\n", goodbuf[i]); + fprintf(stdout, "[%d] %s0x", rank, + bufferLabel2); + fprintf(stdout, "%016llx\n", testbuf[i]); + } + if (!inError) { + inError = 1; + first = i; + last = i; + } else { + last = i; + } + } else if (verbose >= VERBOSE_5 && i % 4 == 0) { + fprintf(stdout, + "[%d] PASSED offset = %lld bytes, transfer %lld\n", + rank, + ((i * sizeof(unsigned long long)) + + test->offset), transferCount); + fprintf(stdout, "[%d] GOOD %s0x", rank, bufferLabel1); + for (j = 0; j < 4; j++) + fprintf(stdout, "%016llx ", goodbuf[i + j]); + fprintf(stdout, "\n[%d] GOOD %s0x", rank, bufferLabel2); + for (j = 0; j < 4; j++) + fprintf(stdout, "%016llx ", testbuf[i + j]); + fprintf(stdout, "\n"); + } + } + if (inError) { + inError = 0; + GetTestFileName(testFileName, test); + fprintf(stdout, + "[%d] FAILED comparison of buffer containing %d-byte ints:\n", + rank, (int)sizeof(unsigned long long int)); + fprintf(stdout, "[%d] File name = %s\n", rank, testFileName); + fprintf(stdout, "[%d] In transfer %lld, ", rank, + transferCount); + fprintf(stdout, + "%lld errors between buffer indices %lld and %lld.\n", + (long long)errorCount, (long long)first, + (long long)last); + fprintf(stdout, "[%d] File byte offset = %lld:\n", rank, + ((first * sizeof(unsigned long long)) + test->offset)); + fprintf(stdout, "[%d] %s0x", rank, bufferLabel1); + for (j = first; j < length && j < first + 4; j++) + fprintf(stdout, "%016llx ", goodbuf[j]); + if (j == length) + fprintf(stdout, "[end of buffer]"); + fprintf(stdout, "\n[%d] %s0x", rank, bufferLabel2); + for (j = first; j < length && j < first + 4; j++) + fprintf(stdout, "%016llx ", testbuf[j]); + if (j == length) + fprintf(stdout, "[end of buffer]"); + fprintf(stdout, "\n"); + if (test->quitOnError == TRUE) + ERR("data check error, aborting execution"); + } + return (errorCount); +} /* CompareBuffers() */ -/******************************************************************************//* - * Count all errors across all tasks; report errors found. - */ + /******************************************************************************//* + * Count all errors across all tasks; report errors found. + */ -int -CountErrors(IOR_param_t *test, - int access, - int errors) +int CountErrors(IOR_param_t * test, int access, int errors) { - int allErrors = 0; + int allErrors = 0; - if (test->checkWrite || test->checkRead) { - MPI_CHECK(MPI_Reduce(&errors, &allErrors, 1, MPI_INT, MPI_SUM, - 0, testComm), "cannot reduce errors"); - MPI_CHECK(MPI_Bcast(&allErrors, 1, MPI_INT, 0, testComm), - "cannot broadcast allErrors value"); - if (allErrors != 0) { - totalErrorCount += allErrors; - test->errorFound = TRUE; + if (test->checkWrite || test->checkRead) { + MPI_CHECK(MPI_Reduce(&errors, &allErrors, 1, MPI_INT, MPI_SUM, + 0, testComm), "cannot reduce errors"); + MPI_CHECK(MPI_Bcast(&allErrors, 1, MPI_INT, 0, testComm), + "cannot broadcast allErrors value"); + if (allErrors != 0) { + totalErrorCount += allErrors; + test->errorFound = TRUE; + } + if (rank == 0 && allErrors != 0) { + if (allErrors < 0) { + WARN("overflow in errors counted"); + allErrors = -1; + } + if (access == WRITECHECK) { + fprintf(stdout, + "WARNING: incorrect data on write.\n"); + fprintf(stdout, + " %d errors found on write check.\n", + allErrors); + } else { + fprintf(stdout, + "WARNING: incorrect data on read.\n"); + fprintf(stdout, + " %d errors found on read check.\n", + allErrors); + } + fprintf(stdout, + "Used Time Stamp %u (0x%x) for Data Signature\n", + test->timeStampSignatureValue, + test->timeStampSignatureValue); + } } - if (rank == 0 && allErrors != 0) { - if (allErrors < 0) { - WARN("overflow in errors counted"); - allErrors = -1; - } - if (access == WRITECHECK) { - fprintf(stdout, "WARNING: incorrect data on write.\n"); - fprintf(stdout, - " %d errors found on write check.\n", allErrors); - } else { - fprintf(stdout, "WARNING: incorrect data on read.\n"); - fprintf(stdout, - " %d errors found on read check.\n", allErrors); - } - fprintf(stdout, "Used Time Stamp %u (0x%x) for Data Signature\n", - test->timeStampSignatureValue, test->timeStampSignatureValue); - } - } - return(allErrors); -} /* CountErrors() */ - + return (allErrors); +} /* CountErrors() */ /******************************************************************************/ /* * Compares hostnames to determine the number of tasks per node */ -int -CountTasksPerNode(int numTasks, MPI_Comm comm) +int CountTasksPerNode(int numTasks, MPI_Comm comm) { - char localhost[MAX_STR], - hostname[MAX_STR], - taskOnNode[MAX_STR]; - int count = 1, - resultsLen = MAX_STR, - i; - static int firstPass = TRUE; - MPI_Status status; + char localhost[MAX_STR], hostname[MAX_STR], taskOnNode[MAX_STR]; + int count = 1, resultsLen = MAX_STR, i; + static int firstPass = TRUE; + MPI_Status status; - MPI_CHECK(MPI_Get_processor_name(localhost, &resultsLen), - "cannot get processor name"); + MPI_CHECK(MPI_Get_processor_name(localhost, &resultsLen), + "cannot get processor name"); - if (verbose >= VERBOSE_2 && firstPass) { - sprintf(taskOnNode, "task %d on %s", rank, localhost); - OutputToRoot(numTasks, comm, taskOnNode); - firstPass = FALSE; - } - - if (numTasks > 1) { - if (rank == 0) { - /* MPI_receive all hostnames, and compare to local hostname */ - for (i = 0; i < numTasks-1; i++) { - MPI_CHECK(MPI_Recv(hostname, MAX_STR, MPI_CHAR, MPI_ANY_SOURCE, - MPI_ANY_TAG, comm, &status), - "cannot receive hostnames"); - if (strcmp(hostname, localhost) == 0) - count++; - } - } else { - /* MPI_send hostname to root node */ - MPI_CHECK(MPI_Send(localhost, MAX_STR, MPI_CHAR, 0, 0, - comm), "cannot send hostname"); + if (verbose >= VERBOSE_2 && firstPass) { + sprintf(taskOnNode, "task %d on %s", rank, localhost); + OutputToRoot(numTasks, comm, taskOnNode); + firstPass = FALSE; } - MPI_CHECK(MPI_Bcast(&count, 1, MPI_INT, 0, comm), - "cannot broadcast tasks-per-node value"); - } - return(count); -} /* CountTasksPerNode() */ + if (numTasks > 1) { + if (rank == 0) { + /* MPI_receive all hostnames, and compare to local hostname */ + for (i = 0; i < numTasks - 1; i++) { + MPI_CHECK(MPI_Recv + (hostname, MAX_STR, MPI_CHAR, + MPI_ANY_SOURCE, MPI_ANY_TAG, comm, + &status), + "cannot receive hostnames"); + if (strcmp(hostname, localhost) == 0) + count++; + } + } else { + /* MPI_send hostname to root node */ + MPI_CHECK(MPI_Send(localhost, MAX_STR, MPI_CHAR, 0, 0, + comm), "cannot send hostname"); + } + MPI_CHECK(MPI_Bcast(&count, 1, MPI_INT, 0, comm), + "cannot broadcast tasks-per-node value"); + } + return (count); +} /* CountTasksPerNode() */ /******************************************************************************/ /* * Allocate a page-aligned (required by O_DIRECT) buffer. */ -void * -CreateBuffer(size_t size) +void *CreateBuffer(size_t size) { - size_t pageSize; - size_t pageMask; - char *buf, *tmp; - char *aligned; + size_t pageSize; + size_t pageMask; + char *buf, *tmp; + char *aligned; - pageSize = getpagesize(); - pageMask = pageSize-1; - buf = malloc(size + pageSize + sizeof(void *)); - if (buf == NULL) ERR("out of memory"); - /* find the alinged buffer */ - tmp = buf + sizeof(char *); - aligned = tmp + pageSize - ((size_t)tmp & pageMask); - /* write a pointer to the original malloc()ed buffer into the bytes - preceding "aligned", so that the aligned buffer can later be free()ed */ - tmp = aligned - sizeof(void *); - *(void **)tmp = buf; - - return((void *)aligned); -} /* CreateBuffer() */ + pageSize = getpagesize(); + pageMask = pageSize - 1; + buf = malloc(size + pageSize + sizeof(void *)); + if (buf == NULL) + ERR("out of memory"); + /* find the alinged buffer */ + tmp = buf + sizeof(char *); + aligned = tmp + pageSize - ((size_t) tmp & pageMask); + /* write a pointer to the original malloc()ed buffer into the bytes + preceding "aligned", so that the aligned buffer can later be free()ed */ + tmp = aligned - sizeof(void *); + *(void **)tmp = buf; + return ((void *)aligned); +} /* CreateBuffer() */ /******************************************************************************/ /* * Create new test for list of tests. */ -IOR_queue_t * -CreateNewTest(int test_num) +IOR_queue_t *CreateNewTest(int test_num) { - IOR_queue_t * newTest = NULL; - - newTest = (IOR_queue_t *)malloc(sizeof(IOR_queue_t)); - if (newTest == NULL) ERR("out of memory"); - newTest->testParameters = initialTestParams; - GetPlatformName(newTest->testParameters.platform); - newTest->testParameters.nodes = initialTestParams.numTasks / tasksPerNode; - newTest->testParameters.tasksPerNode = tasksPerNode; - newTest->testParameters.id = test_num; - newTest->nextTest = NULL; - return(newTest); -} /* CreateNewTest() */ + IOR_queue_t *newTest = NULL; + newTest = (IOR_queue_t *) malloc(sizeof(IOR_queue_t)); + if (newTest == NULL) + ERR("out of memory"); + newTest->testParameters = initialTestParams; + GetPlatformName(newTest->testParameters.platform); + newTest->testParameters.nodes = + initialTestParams.numTasks / tasksPerNode; + newTest->testParameters.tasksPerNode = tasksPerNode; + newTest->testParameters.id = test_num; + newTest->nextTest = NULL; + return (newTest); +} /* CreateNewTest() */ /******************************************************************************/ /* * Sleep for 'delay' seconds. */ -void -DelaySecs(int delay) +void DelaySecs(int delay) { - if (rank == 0 && delay > 0 ) { - if (verbose >= VERBOSE_1) - fprintf(stdout, "delaying %d seconds . . .\n", delay); - sleep(delay); - } -} /* DelaySecs() */ - + if (rank == 0 && delay > 0) { + if (verbose >= VERBOSE_1) + fprintf(stdout, "delaying %d seconds . . .\n", delay); + sleep(delay); + } +} /* DelaySecs() */ /******************************************************************************/ /* * Display freespace (df). */ -void -DisplayFreespace(IOR_param_t * test) +void DisplayFreespace(IOR_param_t * test) { - char fileName[MAX_STR] = {0}; - int i; - int directoryFound = FALSE; + char fileName[MAX_STR] = { 0 }; + int i; + int directoryFound = FALSE; - /* get outfile name */ - GetTestFileName(fileName, test); + /* get outfile name */ + GetTestFileName(fileName, test); - /* get directory for outfile */ - i = strlen(fileName); - while (i-- > 0) { - if (fileName[i] == '/') { - fileName[i] = '\0'; - directoryFound = TRUE; - break; + /* get directory for outfile */ + i = strlen(fileName); + while (i-- > 0) { + if (fileName[i] == '/') { + fileName[i] = '\0'; + directoryFound = TRUE; + break; + } } - } - /* if no directory/, use '.' */ - if (directoryFound == FALSE) { - strcpy(fileName, "."); - } + /* if no directory/, use '.' */ + if (directoryFound == FALSE) { + strcpy(fileName, "."); + } +#if USE_UNDOC_OPT /* NFS */ + if (test->NFS_serverCount) { + strcpy(fileName, test->NFS_rootPath); + } +#endif /* USE_UNDOC_OPT - NFS */ -#if USE_UNDOC_OPT /* NFS */ - if (test->NFS_serverCount) { - strcpy(fileName, test->NFS_rootPath); - } -#endif /* USE_UNDOC_OPT - NFS */ - - ShowFileSystemSize(fileName); - - return; -} /* DisplayFreespace() */ + ShowFileSystemSize(fileName); + return; +} /* DisplayFreespace() */ /******************************************************************************/ /* * Display usage of script file. */ -void -DisplayUsage(char ** argv) +void DisplayUsage(char **argv) { - char * opts[] = { -"OPTIONS:", -" -A N testNum -- test number for reference in some output", -" -a S api -- API for I/O [POSIX|MPIIO|HDF5|NCMPI]", -" -b N blockSize -- contiguous bytes to write per task (e.g.: 8, 4k, 2m, 1g)", -" -B useO_DIRECT -- uses O_DIRECT for POSIX, bypassing I/O buffers", -" -c collective -- collective I/O", -" -C reorderTasks -- changes task ordering to n+1 ordering for readback", -" -Q N taskPerNodeOffset for read tests use with -C & -Z options (-C constant N, -Z at least N)", -" -Z reorderTasksRandom -- changes task ordering to random ordering for readback", -" -X N reorderTasksRandomSeed -- random seed for -Z option", -" -d N interTestDelay -- delay between reps in seconds", -" -D N deadlineForStonewalling -- seconds before stopping write or read phase", -" -Y fsyncPerWrite -- perform fsync after each POSIX write", -" -e fsync -- perform fsync upon POSIX write close", -" -E useExistingTestFile -- do not remove test file before write access", -" -f S scriptFile -- test script name", -" -F filePerProc -- file-per-process", -" -g intraTestBarriers -- use barriers between open, write/read, and close", -" -G N setTimeStampSignature -- set value for time stamp signature", -" -h showHelp -- displays options and help", -" -H showHints -- show hints", -" -i N repetitions -- number of repetitions of test", -" -I individualDataSets -- datasets not shared by all procs [not working]", -" -j N outlierThreshold -- warn on outlier N seconds from mean", -" -J N setAlignment -- HDF5 alignment in bytes (e.g.: 8, 4k, 2m, 1g)", -" -k keepFile -- don't remove the test file(s) on program exit", -" -K keepFileWithError -- keep error-filled file(s) after data-checking", -" -l storeFileOffset -- use file offset as stored signature", -" -m multiFile -- use number of reps (-i) for multiple file count", -" -n noFill -- no fill in HDF5 file creation", -" -N N numTasks -- number of tasks that should participate in the test", -" -o S testFile -- full name for test", -" -O S string of IOR directives (e.g. -O checkRead=1,lustreStripeCount=32)", -" -p preallocate -- preallocate file size", -" -P useSharedFilePointer -- use shared file pointer [not working]", -" -q quitOnError -- during file error-checking, abort on error", -" -r readFile -- read existing file", -" -R checkRead -- check read after read", -" -s N segmentCount -- number of segments", -" -S useStridedDatatype -- put strided access into datatype [not working]", -" -t N transferSize -- size of transfer in bytes (e.g.: 8, 4k, 2m, 1g)", -" -T N maxTimeDuration -- max time in minutes to run tests", -" -u uniqueDir -- use unique directory name for each file-per-process", -" -U S hintsFileName -- full name for hints file", -" -v verbose -- output information (repeating flag increases level)", -" -V useFileView -- use MPI_File_set_view", -" -w writeFile -- write file", -" -W checkWrite -- check read after write", -" -x singleXferAttempt -- do not retry transfer if incomplete", -" -z randomOffset -- access is to random, not sequential, offsets within a file", -" ", -" NOTE: S is a string, N is an integer number.", -" ", -"" }; - int i = 0; + char *opts[] = { + "OPTIONS:", + " -A N testNum -- test number for reference in some output", + " -a S api -- API for I/O [POSIX|MPIIO|HDF5|NCMPI]", + " -b N blockSize -- contiguous bytes to write per task (e.g.: 8, 4k, 2m, 1g)", + " -B useO_DIRECT -- uses O_DIRECT for POSIX, bypassing I/O buffers", + " -c collective -- collective I/O", + " -C reorderTasks -- changes task ordering to n+1 ordering for readback", + " -Q N taskPerNodeOffset for read tests use with -C & -Z options (-C constant N, -Z at least N)", + " -Z reorderTasksRandom -- changes task ordering to random ordering for readback", + " -X N reorderTasksRandomSeed -- random seed for -Z option", + " -d N interTestDelay -- delay between reps in seconds", + " -D N deadlineForStonewalling -- seconds before stopping write or read phase", + " -Y fsyncPerWrite -- perform fsync after each POSIX write", + " -e fsync -- perform fsync upon POSIX write close", + " -E useExistingTestFile -- do not remove test file before write access", + " -f S scriptFile -- test script name", + " -F filePerProc -- file-per-process", + " -g intraTestBarriers -- use barriers between open, write/read, and close", + " -G N setTimeStampSignature -- set value for time stamp signature", + " -h showHelp -- displays options and help", + " -H showHints -- show hints", + " -i N repetitions -- number of repetitions of test", + " -I individualDataSets -- datasets not shared by all procs [not working]", + " -j N outlierThreshold -- warn on outlier N seconds from mean", + " -J N setAlignment -- HDF5 alignment in bytes (e.g.: 8, 4k, 2m, 1g)", + " -k keepFile -- don't remove the test file(s) on program exit", + " -K keepFileWithError -- keep error-filled file(s) after data-checking", + " -l storeFileOffset -- use file offset as stored signature", + " -m multiFile -- use number of reps (-i) for multiple file count", + " -n noFill -- no fill in HDF5 file creation", + " -N N numTasks -- number of tasks that should participate in the test", + " -o S testFile -- full name for test", + " -O S string of IOR directives (e.g. -O checkRead=1,lustreStripeCount=32)", + " -p preallocate -- preallocate file size", + " -P useSharedFilePointer -- use shared file pointer [not working]", + " -q quitOnError -- during file error-checking, abort on error", + " -r readFile -- read existing file", + " -R checkRead -- check read after read", + " -s N segmentCount -- number of segments", + " -S useStridedDatatype -- put strided access into datatype [not working]", + " -t N transferSize -- size of transfer in bytes (e.g.: 8, 4k, 2m, 1g)", + " -T N maxTimeDuration -- max time in minutes to run tests", + " -u uniqueDir -- use unique directory name for each file-per-process", + " -U S hintsFileName -- full name for hints file", + " -v verbose -- output information (repeating flag increases level)", + " -V useFileView -- use MPI_File_set_view", + " -w writeFile -- write file", + " -W checkWrite -- check read after write", + " -x singleXferAttempt -- do not retry transfer if incomplete", + " -z randomOffset -- access is to random, not sequential, offsets within a file", + " ", + " NOTE: S is a string, N is an integer number.", + " ", + "" + }; + int i = 0; - fprintf(stdout, "Usage: %s [OPTIONS]\n\n", * argv); - for (i=0; strlen(opts[i]) > 0; i++) - fprintf(stdout, "%s\n", opts[i]); - - return; -} /* DisplayUsage() */ + fprintf(stdout, "Usage: %s [OPTIONS]\n\n", *argv); + for (i = 0; strlen(opts[i]) > 0; i++) + fprintf(stdout, "%s\n", opts[i]); + return; +} /* DisplayUsage() */ /******************************************************************************/ /* * Distribute IOR_HINTs to all tasks' environments. */ -void -DistributeHints(void) +void DistributeHints(void) { - char hint[MAX_HINTS][MAX_STR], - fullHint[MAX_STR], - hintVariable[MAX_STR]; - int hintCount = 0, - i; + char hint[MAX_HINTS][MAX_STR], fullHint[MAX_STR], hintVariable[MAX_STR]; + int hintCount = 0, i; - if (rank == 0) { - for (i = 0; environ[i] != NULL; i++) { - if (strncmp(environ[i], "IOR_HINT", strlen("IOR_HINT")) == 0) { - hintCount++; - if (hintCount == MAX_HINTS) { - WARN("exceeded max hints; reset MAX_HINTS and recompile"); - hintCount = MAX_HINTS; - break; + if (rank == 0) { + for (i = 0; environ[i] != NULL; i++) { + if (strncmp(environ[i], "IOR_HINT", strlen("IOR_HINT")) + == 0) { + hintCount++; + if (hintCount == MAX_HINTS) { + WARN("exceeded max hints; reset MAX_HINTS and recompile"); + hintCount = MAX_HINTS; + break; + } + /* assume no IOR_HINT is greater than MAX_STR in length */ + strncpy(hint[hintCount - 1], environ[i], + MAX_STR - 1); + } } - /* assume no IOR_HINT is greater than MAX_STR in length */ - strncpy(hint[hintCount-1], environ[i], MAX_STR-1); - } } - } - MPI_CHECK(MPI_Bcast(&hintCount, sizeof(hintCount), MPI_BYTE, - 0, MPI_COMM_WORLD), "cannot broadcast hints"); - for (i = 0; i < hintCount; i++) { - MPI_CHECK(MPI_Bcast(&hint[i], MAX_STR, MPI_BYTE, + MPI_CHECK(MPI_Bcast(&hintCount, sizeof(hintCount), MPI_BYTE, 0, MPI_COMM_WORLD), "cannot broadcast hints"); - strcpy(fullHint, hint[i]); - strcpy(hintVariable, strtok(fullHint, "=")); - if (getenv(hintVariable) == NULL) { - /* doesn't exist in this task's environment; better set it */ - if (putenv(hint[i]) != 0) WARN("cannot set environment variable"); + for (i = 0; i < hintCount; i++) { + MPI_CHECK(MPI_Bcast(&hint[i], MAX_STR, MPI_BYTE, + 0, MPI_COMM_WORLD), + "cannot broadcast hints"); + strcpy(fullHint, hint[i]); + strcpy(hintVariable, strtok(fullHint, "=")); + if (getenv(hintVariable) == NULL) { + /* doesn't exist in this task's environment; better set it */ + if (putenv(hint[i]) != 0) + WARN("cannot set environment variable"); + } } - } -} /* DistributeHints() */ - +} /* DistributeHints() */ /******************************************************************************/ /* @@ -756,101 +740,90 @@ DistributeHints(void) */ void -FillBuffer(void * buffer, - IOR_param_t * test, - unsigned long long offset, - int fillrank) +FillBuffer(void *buffer, + IOR_param_t * test, unsigned long long offset, int fillrank) { - size_t i; - unsigned long long hi, lo; - unsigned long long *buf = (unsigned long long *)buffer; + size_t i; + unsigned long long hi, lo; + unsigned long long *buf = (unsigned long long *)buffer; - hi = ((unsigned long long)fillrank) << 32; - lo = (unsigned long long)test->timeStampSignatureValue; - for (i = 0; i < test->transferSize / sizeof(unsigned long long); i++) { - if ((i%2) == 0) { - /* evens contain MPI rank and time in seconds */ - buf[i] = hi | lo; - } else { - /* odds contain offset */ - buf[i] = offset + (i * sizeof(unsigned long long)); + hi = ((unsigned long long)fillrank) << 32; + lo = (unsigned long long)test->timeStampSignatureValue; + for (i = 0; i < test->transferSize / sizeof(unsigned long long); i++) { + if ((i % 2) == 0) { + /* evens contain MPI rank and time in seconds */ + buf[i] = hi | lo; + } else { + /* odds contain offset */ + buf[i] = offset + (i * sizeof(unsigned long long)); + } } - } -} /* FillBuffer() */ +} /* FillBuffer() */ - -/******************************************************************************//* - * Free transfer buffers. - */ + /******************************************************************************//* + * Free transfer buffers. + */ void -FreeBuffers(int access, - void *checkBuffer, - void *readCheckBuffer, - void *buffer, - IOR_offset_t *offsetArray) +FreeBuffers(int access, + void *checkBuffer, + void *readCheckBuffer, void *buffer, IOR_offset_t * offsetArray) { - /* free() aligned buffers */ - if (access == WRITECHECK || access == READCHECK) { - free( *(void **)((char *)checkBuffer - sizeof(char *)) ); - } - if (access == READCHECK) { - free( *(void **)((char *)readCheckBuffer - sizeof(char *)) ); - } - free( *(void **)((char *)buffer - sizeof(char *)) ); - - /* nothing special needed to free() this unaligned buffer */ - free(offsetArray); - return; -} /* FreeBuffers() */ + /* free() aligned buffers */ + if (access == WRITECHECK || access == READCHECK) { + free(*(void **)((char *)checkBuffer - sizeof(char *))); + } + if (access == READCHECK) { + free(*(void **)((char *)readCheckBuffer - sizeof(char *))); + } + free(*(void **)((char *)buffer - sizeof(char *))); + /* nothing special needed to free() this unaligned buffer */ + free(offsetArray); + return; +} /* FreeBuffers() */ /******************************************************************************/ /* * Return string describing machine name and type. */ - -void -GetPlatformName(char * platformName) + +void GetPlatformName(char *platformName) { - char nodeName[MAX_STR], - * p, - * start, - sysName[MAX_STR]; - struct utsname name; + char nodeName[MAX_STR], *p, *start, sysName[MAX_STR]; + struct utsname name; - if (uname(&name) != 0) { - WARN("cannot get platform name"); - sprintf(sysName, "%s", "Unknown"); - sprintf(nodeName, "%s", "Unknown"); - } else { - sprintf(sysName, "%s", name.sysname); - sprintf(nodeName, "%s", name.nodename); - } - - start = nodeName; - if (strlen(nodeName) == 0) { - p = start; - } else { - /* point to one character back from '\0' */ - p = start + strlen(nodeName) - 1; - } - /* - * to cut off trailing node number, search backwards - * for the first non-numeric character - */ - while (p != start) { - if (* p < '0' || * p > '9') { - * (p+1) = '\0'; - break; + if (uname(&name) != 0) { + WARN("cannot get platform name"); + sprintf(sysName, "%s", "Unknown"); + sprintf(nodeName, "%s", "Unknown"); } else { - p--; + sprintf(sysName, "%s", name.sysname); + sprintf(nodeName, "%s", name.nodename); } - } - sprintf(platformName, "%s(%s)", nodeName, sysName); -} /* GetPlatformName() */ + start = nodeName; + if (strlen(nodeName) == 0) { + p = start; + } else { + /* point to one character back from '\0' */ + p = start + strlen(nodeName) - 1; + } + /* + * to cut off trailing node number, search backwards + * for the first non-numeric character + */ + while (p != start) { + if (*p < '0' || *p > '9') { + *(p + 1) = '\0'; + break; + } else { + p--; + } + } + sprintf(platformName, "%s(%s)", nodeName, sysName); +} /* GetPlatformName() */ /******************************************************************************/ /* @@ -858,57 +831,57 @@ GetPlatformName(char * platformName) * for single shared file, fileNames[0] is returned in testFileName */ -void -GetTestFileName(char * testFileName, IOR_param_t * test) +void GetTestFileName(char *testFileName, IOR_param_t * test) { - char ** fileNames, + char **fileNames, initialTestFileName[MAXPATHLEN], - testFileNameRoot[MAX_STR], - tmpString[MAX_STR]; - int count; + testFileNameRoot[MAX_STR], tmpString[MAX_STR]; + int count; - /* parse filename for multiple file systems */ - strcpy(initialTestFileName, test->testFileName); - fileNames = ParseFileName(initialTestFileName, &count); - if (count > 1 && test->uniqueDir == TRUE) - ERR("cannot use multiple file names with unique directories"); - if (test->filePerProc) { - strcpy(testFileNameRoot, - fileNames[((rank+rankOffset)%test->numTasks) % count]); - } else { - strcpy(testFileNameRoot, fileNames[0]); - } - - /* give unique name if using multiple files */ - if (test->filePerProc) { - /* - * prepend rank subdirectory before filename - * e.g., /dir/file => /dir//file - */ - if (test->uniqueDir == TRUE) { - strcpy(testFileNameRoot, PrependDir(test, testFileNameRoot)); + /* parse filename for multiple file systems */ + strcpy(initialTestFileName, test->testFileName); + fileNames = ParseFileName(initialTestFileName, &count); + if (count > 1 && test->uniqueDir == TRUE) + ERR("cannot use multiple file names with unique directories"); + if (test->filePerProc) { + strcpy(testFileNameRoot, + fileNames[((rank + + rankOffset) % test->numTasks) % count]); + } else { + strcpy(testFileNameRoot, fileNames[0]); } -#if USE_UNDOC_OPT /* NFS */ - if (test->NFS_serverCount) { - sprintf(tmpString, "%s/%s%d/%s", test->NFS_rootPath, - test->NFS_serverName, rank%(test->NFS_serverCount), - testFileNameRoot); - strcpy(testFileNameRoot, tmpString); + + /* give unique name if using multiple files */ + if (test->filePerProc) { + /* + * prepend rank subdirectory before filename + * e.g., /dir/file => /dir//file + */ + if (test->uniqueDir == TRUE) { + strcpy(testFileNameRoot, + PrependDir(test, testFileNameRoot)); + } +#if USE_UNDOC_OPT /* NFS */ + if (test->NFS_serverCount) { + sprintf(tmpString, "%s/%s%d/%s", test->NFS_rootPath, + test->NFS_serverName, + rank % (test->NFS_serverCount), + testFileNameRoot); + strcpy(testFileNameRoot, tmpString); + } +#endif /* USE_UNDOC_OPT - NFS */ + sprintf(testFileName, "%s.%08d", testFileNameRoot, + (rank + rankOffset) % test->numTasks); + } else { + strcpy(testFileName, testFileNameRoot); } -#endif /* USE_UNDOC_OPT - NFS */ - sprintf(testFileName, "%s.%08d", testFileNameRoot, - (rank+rankOffset)%test->numTasks); - } else { - strcpy(testFileName, testFileNameRoot); - } - - /* add suffix for multiple files */ - if (test->repCounter > -1) { - sprintf(tmpString, ".%d", test->repCounter); - strcat(testFileName, tmpString); - } -} /* GetTestFileName() */ + /* add suffix for multiple files */ + if (test->repCounter > -1) { + sprintf(tmpString, ".%d", test->repCounter); + strcat(testFileName, tmpString); + } +} /* GetTestFileName() */ /******************************************************************************/ /* @@ -916,137 +889,132 @@ GetTestFileName(char * testFileName, IOR_param_t * test) * in which case use gettimeofday(). */ -double -GetTimeStamp(void) +double GetTimeStamp(void) { - double timeVal; + double timeVal; #ifdef _NO_MPI_TIMER - struct timeval timer; + struct timeval timer; - if (gettimeofday(&timer, (struct timezone *)NULL) != 0) - ERR("cannot use gettimeofday()"); - timeVal = (double)timer.tv_sec + ((double)timer.tv_usec/1000000); -#else /* not _NO_MPI_TIMER */ - timeVal = MPI_Wtime(); /* no MPI_CHECK(), just check return value */ - if (timeVal < 0) ERR("cannot use MPI_Wtime()"); -#endif /* _NO_MPI_TIMER */ + if (gettimeofday(&timer, (struct timezone *)NULL) != 0) + ERR("cannot use gettimeofday()"); + timeVal = (double)timer.tv_sec + ((double)timer.tv_usec / 1000000); +#else /* not _NO_MPI_TIMER */ + timeVal = MPI_Wtime(); /* no MPI_CHECK(), just check return value */ + if (timeVal < 0) + ERR("cannot use MPI_Wtime()"); +#endif /* _NO_MPI_TIMER */ - /* wall_clock_delta is difference from root node's time */ - timeVal -= wall_clock_delta; - - return(timeVal); -} /* GetTimeStamp() */ + /* wall_clock_delta is difference from root node's time */ + timeVal -= wall_clock_delta; + return (timeVal); +} /* GetTimeStamp() */ /******************************************************************************/ /* * Convert IOR_offset_t value to human readable string. */ -char * -HumanReadable(IOR_offset_t value, int base) +char *HumanReadable(IOR_offset_t value, int base) { - char * valueStr; - int m = 0, g = 0; - char m_str[8], g_str[8]; + char *valueStr; + int m = 0, g = 0; + char m_str[8], g_str[8]; - valueStr = (char *)malloc(MAX_STR); - if (valueStr == NULL) ERR("out of memory"); + valueStr = (char *)malloc(MAX_STR); + if (valueStr == NULL) + ERR("out of memory"); - if (base == BASE_TWO) { - m = MEBIBYTE; - g = GIBIBYTE; - strcpy(m_str, "MiB"); - strcpy(g_str, "GiB"); - } else if (base == BASE_TEN) { - m = MEGABYTE; - g = GIGABYTE; - strcpy(m_str, "MB"); - strcpy(g_str, "GB"); - } - - if (value >= g) { - if (value % (IOR_offset_t)g) { - sprintf(valueStr, "%.2f %s", (double)((double)value/g), g_str); - } else { - sprintf(valueStr, "%d %s", (int)(value/g), g_str); + if (base == BASE_TWO) { + m = MEBIBYTE; + g = GIBIBYTE; + strcpy(m_str, "MiB"); + strcpy(g_str, "GiB"); + } else if (base == BASE_TEN) { + m = MEGABYTE; + g = GIGABYTE; + strcpy(m_str, "MB"); + strcpy(g_str, "GB"); } - } else if (value >= m) { - if (value % (IOR_offset_t)m) { - sprintf(valueStr, "%.2f %s", (double)((double)value/m), m_str); - } else { - sprintf(valueStr, "%d %s", (int)(value/m), m_str); - } - } else if (value >= 0) { - sprintf(valueStr, "%d bytes", (int)value); - } else { - sprintf(valueStr, "-"); - } - return valueStr; -} /* HumanReadable() */ + if (value >= g) { + if (value % (IOR_offset_t) g) { + sprintf(valueStr, "%.2f %s", + (double)((double)value / g), g_str); + } else { + sprintf(valueStr, "%d %s", (int)(value / g), g_str); + } + } else if (value >= m) { + if (value % (IOR_offset_t) m) { + sprintf(valueStr, "%.2f %s", + (double)((double)value / m), m_str); + } else { + sprintf(valueStr, "%d %s", (int)(value / m), m_str); + } + } else if (value >= 0) { + sprintf(valueStr, "%d bytes", (int)value); + } else { + sprintf(valueStr, "-"); + } + return valueStr; +} /* HumanReadable() */ /******************************************************************************/ /* * Change string to lower case. */ -char * -LowerCase(char * string) +char *LowerCase(char *string) { - char * nextChar = string; - - while (* nextChar != '\0') { - * nextChar = (char)tolower((int)* nextChar); - nextChar++; - } - return(string); -} /* LowerCase() */ + char *nextChar = string; + while (*nextChar != '\0') { + *nextChar = (char)tolower((int)*nextChar); + nextChar++; + } + return (string); +} /* LowerCase() */ /******************************************************************************/ /* * Parse file name. */ -char ** -ParseFileName(char * name, int * count) +char **ParseFileName(char *name, int *count) { - char ** fileNames, - * tmp, - * token; - char delimiterString[3] = { FILENAME_DELIMITER, '\n', '\0' }; - int i = 0; + char **fileNames, *tmp, *token; + char delimiterString[3] = { FILENAME_DELIMITER, '\n', '\0' }; + int i = 0; - * count = 0; - tmp = name; + *count = 0; + tmp = name; - /* pass one */ - /* if something there, count the first item */ - if (* tmp != '\0') { - (* count)++; - } - /* count the rest of the filenames */ - while (* tmp != '\0') { - if (* tmp == FILENAME_DELIMITER) { - (* count)++; + /* pass one */ + /* if something there, count the first item */ + if (*tmp != '\0') { + (*count)++; + } + /* count the rest of the filenames */ + while (*tmp != '\0') { + if (*tmp == FILENAME_DELIMITER) { + (*count)++; + } + tmp++; } - tmp++; - } - fileNames = (char **)malloc((* count) * sizeof(char **)); - if (fileNames == NULL) ERR("out of memory"); - - /* pass two */ - token = strtok(name, delimiterString); - while (token != NULL) { - fileNames[i] = token; - token = strtok(NULL, delimiterString); - i++; - } - return(fileNames); -} /* ParseFileName() */ + fileNames = (char **)malloc((*count) * sizeof(char **)); + if (fileNames == NULL) + ERR("out of memory"); + /* pass two */ + token = strtok(name, delimiterString); + while (token != NULL) { + fileNames[i] = token; + token = strtok(NULL, delimiterString); + i++; + } + return (fileNames); +} /* ParseFileName() */ /******************************************************************************/ /* @@ -1055,32 +1023,28 @@ ParseFileName(char * name, int * count) * that should be appended to the number field. */ -void -PPDouble(int leftjustify, - double number, - char * append) +void PPDouble(int leftjustify, double number, char *append) { - if (number < 0) { - fprintf(stdout, " - %s", append); - } else { - if (leftjustify) { - if (number < 1) - fprintf(stdout, "%-10.6f%s", number, append); - else if (number < 3600) - fprintf(stdout, "%-10.2f%s", number, append); - else - fprintf(stdout, "%-10.0f%s", number, append); + if (number < 0) { + fprintf(stdout, " - %s", append); } else { - if (number < 1) - fprintf(stdout, "%10.6f%s", number, append); - else if (number < 3600) - fprintf(stdout, "%10.2f%s", number, append); - else - fprintf(stdout, "%10.0f%s", number, append); + if (leftjustify) { + if (number < 1) + fprintf(stdout, "%-10.6f%s", number, append); + else if (number < 3600) + fprintf(stdout, "%-10.2f%s", number, append); + else + fprintf(stdout, "%-10.0f%s", number, append); + } else { + if (number < 1) + fprintf(stdout, "%10.6f%s", number, append); + else if (number < 3600) + fprintf(stdout, "%10.2f%s", number, append); + else + fprintf(stdout, "%10.0f%s", number, append); + } } - } -} /* PPDouble() */ - +} /* PPDouble() */ /******************************************************************************/ /* @@ -1089,1454 +1053,1554 @@ PPDouble(int leftjustify, * */ -char * -PrependDir(IOR_param_t * test, char * rootDir) +char *PrependDir(IOR_param_t * test, char *rootDir) { - char * dir; - char fname[MAX_STR+1]; - char * p; - int i; + char *dir; + char fname[MAX_STR + 1]; + char *p; + int i; - dir = (char *)malloc(MAX_STR+1); - if (dir == NULL) ERR("out of memory"); + dir = (char *)malloc(MAX_STR + 1); + if (dir == NULL) + ERR("out of memory"); - /* get dir name */ - strcpy(dir, rootDir); - i = strlen(dir)-1; - while (i > 0) { - if (dir[i] == '\0' || dir[i] == '/') { - dir[i] = '/'; - dir[i+1] = '\0'; - break; - } - i--; - } - - /* get file name */ - strcpy(fname, rootDir); - p = fname; - while (i > 0) { - if (fname[i] == '\0' || fname[i] == '/') { - p = fname + (i+1); - break; - } - i--; - } - - /* create directory with rank as subdirectory */ - sprintf(dir, "%s%d", dir, (rank+rankOffset)%test->numTasks); - - /* dir doesn't exist, so create */ - if (access(dir, F_OK) != 0) { - if (mkdir(dir, S_IRWXU) < 0 ) { - ERR("cannot create directory"); + /* get dir name */ + strcpy(dir, rootDir); + i = strlen(dir) - 1; + while (i > 0) { + if (dir[i] == '\0' || dir[i] == '/') { + dir[i] = '/'; + dir[i + 1] = '\0'; + break; + } + i--; } - /* check if correct permissions */ - } else if (access(dir, R_OK) != 0 || access(dir, W_OK) != 0 || - access(dir, X_OK) != 0) { - ERR("invalid directory permissions"); - } + /* get file name */ + strcpy(fname, rootDir); + p = fname; + while (i > 0) { + if (fname[i] == '\0' || fname[i] == '/') { + p = fname + (i + 1); + break; + } + i--; + } - /* concatenate dir and file names */ - strcat(dir, "/"); - strcat(dir, p); + /* create directory with rank as subdirectory */ + sprintf(dir, "%s%d", dir, (rank + rankOffset) % test->numTasks); - return dir; -} /* PrependDir() */ + /* dir doesn't exist, so create */ + if (access(dir, F_OK) != 0) { + if (mkdir(dir, S_IRWXU) < 0) { + ERR("cannot create directory"); + } + /* check if correct permissions */ + } else if (access(dir, R_OK) != 0 || access(dir, W_OK) != 0 || + access(dir, X_OK) != 0) { + ERR("invalid directory permissions"); + } -/******************************************************************************//* - * Read and then reread buffer to confirm data read twice matches. - */ + /* concatenate dir and file names */ + strcat(dir, "/"); + strcat(dir, p); + + return dir; +} /* PrependDir() */ + + /******************************************************************************//* + * Read and then reread buffer to confirm data read twice matches. + */ void -ReadCheck(void *fd, - void *buffer, - void *checkBuffer, - void *readCheckBuffer, - IOR_param_t *test, - IOR_offset_t transfer, - IOR_offset_t blockSize, - IOR_offset_t *amtXferred, - IOR_offset_t *transferCount, - int access, - int *errors) +ReadCheck(void *fd, + void *buffer, + void *checkBuffer, + void *readCheckBuffer, + IOR_param_t * test, + IOR_offset_t transfer, + IOR_offset_t blockSize, + IOR_offset_t * amtXferred, + IOR_offset_t * transferCount, int access, int *errors) { - int readCheckToRank, readCheckFromRank; - MPI_Status status; - IOR_offset_t tmpOffset; - IOR_offset_t segmentSize, segmentNum; + int readCheckToRank, readCheckFromRank; + MPI_Status status; + IOR_offset_t tmpOffset; + IOR_offset_t segmentSize, segmentNum; - memset(buffer, 'a', transfer); - *amtXferred = backend->xfer(access, fd, buffer, transfer, test); - tmpOffset = test->offset; - if (test->filePerProc == FALSE) { - /* offset changes for shared file, not for file-per-proc */ - segmentSize = test->numTasks * blockSize; - segmentNum = test->offset / segmentSize; - - /* work in current segment */ - test->offset = (((test->offset % segmentSize) - /* offset to neighbor's data */ - + ((test->reorderTasks ? - test->tasksPerNode : 0) * blockSize)) - /* stay within current segment */ - % segmentSize) - /* return segment to actual file offset */ - + (segmentNum * segmentSize); - } - if (*amtXferred != transfer) - ERR("cannot read from file on read check"); - memset(checkBuffer, 'a', transfer); /* empty buffer */ -#if USE_UNDOC_OPT /* corruptFile */ - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - /* intentionally corrupt file to determine if check works */ - if (test->corruptFile) { - CorruptFile(test->testFileName, test, 0, READCHECK); - } -#endif /* USE_UNDOC_OPT - corruptFile */ - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - if (test->filePerProc) { - *amtXferred = backend->xfer(access, test->fd_fppReadCheck, - checkBuffer, transfer, test); - } else { - *amtXferred = backend->xfer(access, fd, checkBuffer, transfer, test); - } - test->offset = tmpOffset; - if (*amtXferred != transfer) - ERR("cannot reread from file read check"); - (*transferCount)++; - /* exchange buffers */ - memset(readCheckBuffer, 'a', transfer); - readCheckToRank = (rank + (test->reorderTasks ? test->tasksPerNode : 0)) - % test->numTasks; - readCheckFromRank = (rank + (test->numTasks - - (test->reorderTasks ? test->tasksPerNode : 0))) - % test->numTasks; - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - MPI_Sendrecv(checkBuffer, transfer, MPI_CHAR, readCheckToRank, 1, - readCheckBuffer, transfer, MPI_CHAR, readCheckFromRank, 1, - testComm, &status); - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - *errors += CompareBuffers(buffer, readCheckBuffer, transfer, - *transferCount, test, READCHECK); - return; -} /* ReadCheck() */ + memset(buffer, 'a', transfer); + *amtXferred = backend->xfer(access, fd, buffer, transfer, test); + tmpOffset = test->offset; + if (test->filePerProc == FALSE) { + /* offset changes for shared file, not for file-per-proc */ + segmentSize = test->numTasks * blockSize; + segmentNum = test->offset / segmentSize; + /* work in current segment */ + test->offset = (((test->offset % segmentSize) + /* offset to neighbor's data */ + + ((test->reorderTasks ? + test->tasksPerNode : 0) * blockSize)) + /* stay within current segment */ + % segmentSize) + /* return segment to actual file offset */ + + (segmentNum * segmentSize); + } + if (*amtXferred != transfer) + ERR("cannot read from file on read check"); + memset(checkBuffer, 'a', transfer); /* empty buffer */ +#if USE_UNDOC_OPT /* corruptFile */ + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + /* intentionally corrupt file to determine if check works */ + if (test->corruptFile) { + CorruptFile(test->testFileName, test, 0, READCHECK); + } +#endif /* USE_UNDOC_OPT - corruptFile */ + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + if (test->filePerProc) { + *amtXferred = backend->xfer(access, test->fd_fppReadCheck, + checkBuffer, transfer, test); + } else { + *amtXferred = + backend->xfer(access, fd, checkBuffer, transfer, test); + } + test->offset = tmpOffset; + if (*amtXferred != transfer) + ERR("cannot reread from file read check"); + (*transferCount)++; + /* exchange buffers */ + memset(readCheckBuffer, 'a', transfer); + readCheckToRank = (rank + (test->reorderTasks ? test->tasksPerNode : 0)) + % test->numTasks; + readCheckFromRank = (rank + (test->numTasks + - + (test->reorderTasks ? test-> + tasksPerNode : 0))) + % test->numTasks; + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + MPI_Sendrecv(checkBuffer, transfer, MPI_CHAR, readCheckToRank, 1, + readCheckBuffer, transfer, MPI_CHAR, readCheckFromRank, 1, + testComm, &status); + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + *errors += CompareBuffers(buffer, readCheckBuffer, transfer, + *transferCount, test, READCHECK); + return; +} /* ReadCheck() */ /******************************************************************************/ /* * Reduce test results, and show if verbose set. */ -void -ReduceIterResults(IOR_param_t * test, - double ** timer, - int rep, - int access) +void ReduceIterResults(IOR_param_t * test, double **timer, int rep, int access) { - double reduced[12] = { 0 }, - diff[6], - currentWrite, - currentRead, - totalWriteTime, - totalReadTime; - enum {RIGHT, LEFT}; - int i; - static int firstIteration = TRUE; - IOR_offset_t aggFileSizeForBW; - MPI_Op op; + double reduced[12] = { 0 }, + diff[6], currentWrite, currentRead, totalWriteTime, totalReadTime; + enum { RIGHT, LEFT }; + int i; + static int firstIteration = TRUE; + IOR_offset_t aggFileSizeForBW; + MPI_Op op; - /* Find the minimum start time of the even numbered timers, and the - maximum finish time for the odd numbered timers */ - for (i = 0; i < 12; i++) { - op = i % 2 ? MPI_MAX : MPI_MIN; - MPI_CHECK(MPI_Reduce(&timer[i][rep], &reduced[i], 1, MPI_DOUBLE, - op, 0, testComm), - "MPI_Reduce()"); - } - - if (rank == 0) { - /* Calculate elapsed times and throughput numbers */ - for (i = 0; i < 6; i++) - diff[i] = reduced[2*i+1] - reduced[2*i]; - totalReadTime = reduced[11] - reduced[6]; - totalWriteTime = reduced[5] - reduced[0]; - aggFileSizeForBW = test->aggFileSizeForBW[rep]; - if (access == WRITE) { - currentWrite = (double)((double)aggFileSizeForBW / totalWriteTime); - test->writeVal[0][rep] = currentWrite; - test->writeVal[1][rep] = totalWriteTime; + /* Find the minimum start time of the even numbered timers, and the + maximum finish time for the odd numbered timers */ + for (i = 0; i < 12; i++) { + op = i % 2 ? MPI_MAX : MPI_MIN; + MPI_CHECK(MPI_Reduce(&timer[i][rep], &reduced[i], 1, MPI_DOUBLE, + op, 0, testComm), "MPI_Reduce()"); } - if (access == READ) { - currentRead = (double)((double)aggFileSizeForBW / totalReadTime); - test->readVal[0][rep] = currentRead; - test->readVal[1][rep] = totalReadTime; - } - } - -#if USE_UNDOC_OPT /* fillTheFileSystem */ - if (test->fillTheFileSystem && rank == 0 && firstIteration - && rep == 0 && verbose >= VERBOSE_1) { - fprintf(stdout, " . . . skipping iteration results output . . .\n"); - fflush(stdout); - } -#endif /* USE_UNDOC_OPT - fillTheFileSystem */ - - if (rank == 0 && verbose >= VERBOSE_2 -#if USE_UNDOC_OPT /* fillTheFileSystem */ - && test->fillTheFileSystem == FALSE -#endif /* USE_UNDOC_OPT - fillTheFileSystem */ - ) { - /* print out the results */ - if (firstIteration && rep == 0) { - fprintf(stdout, "access bw(MiB/s) block(KiB) xfer(KiB)"); - fprintf(stdout, " open(s) wr/rd(s) close(s) total(s) iter\n"); - fprintf(stdout, "------ --------- ---------- ---------"); - fprintf(stdout, " -------- -------- -------- -------- ----\n"); + if (rank == 0) { + /* Calculate elapsed times and throughput numbers */ + for (i = 0; i < 6; i++) + diff[i] = reduced[2 * i + 1] - reduced[2 * i]; + totalReadTime = reduced[11] - reduced[6]; + totalWriteTime = reduced[5] - reduced[0]; + aggFileSizeForBW = test->aggFileSizeForBW[rep]; + if (access == WRITE) { + currentWrite = + (double)((double)aggFileSizeForBW / totalWriteTime); + test->writeVal[0][rep] = currentWrite; + test->writeVal[1][rep] = totalWriteTime; + } + if (access == READ) { + currentRead = + (double)((double)aggFileSizeForBW / totalReadTime); + test->readVal[0][rep] = currentRead; + test->readVal[1][rep] = totalReadTime; + } } - if (access == WRITE) { - fprintf(stdout, "write "); - PPDouble(LEFT, (currentWrite/MEBIBYTE), " \0"); - PPDouble(LEFT, (double)test->blockSize/KIBIBYTE, " \0"); - PPDouble(LEFT, (double)test->transferSize/KIBIBYTE, " \0"); - if (test->writeFile) { - PPDouble(LEFT, diff[0], " \0"); - PPDouble(LEFT, diff[1], " \0"); - PPDouble(LEFT, diff[2], " \0"); - PPDouble(LEFT, totalWriteTime, " \0"); - } - fprintf(stdout, "%-4d XXCEL\n", rep); +#if USE_UNDOC_OPT /* fillTheFileSystem */ + if (test->fillTheFileSystem && rank == 0 && firstIteration + && rep == 0 && verbose >= VERBOSE_1) { + fprintf(stdout, + " . . . skipping iteration results output . . .\n"); + fflush(stdout); } - if (access == READ) { - fprintf(stdout, "read "); - PPDouble(LEFT, (currentRead/MEBIBYTE), " \0"); - PPDouble(LEFT, (double)test->blockSize/KIBIBYTE, " \0"); - PPDouble(LEFT, (double)test->transferSize/KIBIBYTE, " \0"); - if (test->readFile) { - PPDouble(LEFT, diff[3], " \0"); - PPDouble(LEFT, diff[4], " \0"); - PPDouble(LEFT, diff[5], " \0"); - PPDouble(LEFT, totalReadTime, " \0"); - } - fprintf(stdout, "%-4d XXCEL\n", rep); - } - fflush(stdout); - } - firstIteration = FALSE; /* set to TRUE to repeat this header */ -} /* ReduceIterResults() */ +#endif /* USE_UNDOC_OPT - fillTheFileSystem */ + if (rank == 0 && verbose >= VERBOSE_2 +#if USE_UNDOC_OPT /* fillTheFileSystem */ + && test->fillTheFileSystem == FALSE +#endif /* USE_UNDOC_OPT - fillTheFileSystem */ + ) { + /* print out the results */ + if (firstIteration && rep == 0) { + fprintf(stdout, + "access bw(MiB/s) block(KiB) xfer(KiB)"); + fprintf(stdout, + " open(s) wr/rd(s) close(s) total(s) iter\n"); + fprintf(stdout, + "------ --------- ---------- ---------"); + fprintf(stdout, + " -------- -------- -------- -------- ----\n"); + } + if (access == WRITE) { + fprintf(stdout, "write "); + PPDouble(LEFT, (currentWrite / MEBIBYTE), " \0"); + PPDouble(LEFT, (double)test->blockSize / KIBIBYTE, + " \0"); + PPDouble(LEFT, (double)test->transferSize / KIBIBYTE, + " \0"); + if (test->writeFile) { + PPDouble(LEFT, diff[0], " \0"); + PPDouble(LEFT, diff[1], " \0"); + PPDouble(LEFT, diff[2], " \0"); + PPDouble(LEFT, totalWriteTime, " \0"); + } + fprintf(stdout, "%-4d XXCEL\n", rep); + } + if (access == READ) { + fprintf(stdout, "read "); + PPDouble(LEFT, (currentRead / MEBIBYTE), " \0"); + PPDouble(LEFT, (double)test->blockSize / KIBIBYTE, + " \0"); + PPDouble(LEFT, (double)test->transferSize / KIBIBYTE, + " \0"); + if (test->readFile) { + PPDouble(LEFT, diff[3], " \0"); + PPDouble(LEFT, diff[4], " \0"); + PPDouble(LEFT, diff[5], " \0"); + PPDouble(LEFT, totalReadTime, " \0"); + } + fprintf(stdout, "%-4d XXCEL\n", rep); + } + fflush(stdout); + } + firstIteration = FALSE; /* set to TRUE to repeat this header */ +} /* ReduceIterResults() */ /******************************************************************************/ /* * Check for file(s), then remove all files if file-per-proc, else single file. */ - -void -RemoveFile(char * testFileName, - int filePerProc, - IOR_param_t * test) -{ - int tmpRankOffset; - if (filePerProc) - { - /* in random tasks, delete own file */ - if (test->reorderTasksRandom == TRUE) - { - tmpRankOffset = rankOffset; - rankOffset = 0; - GetTestFileName(testFileName, test); - } - if (access(testFileName, F_OK) == 0) - { - backend->delete(testFileName, test); - } - if (test->reorderTasksRandom == TRUE) - { - rankOffset = tmpRankOffset; - GetTestFileName(testFileName, test); - } - } else { - if ((rank == 0) && (access(testFileName, F_OK) == 0)) { - backend->delete(testFileName, test); - } - } -} /* RemoveFile() */ +void RemoveFile(char *testFileName, int filePerProc, IOR_param_t * test) +{ + int tmpRankOffset; + if (filePerProc) { + /* in random tasks, delete own file */ + if (test->reorderTasksRandom == TRUE) { + tmpRankOffset = rankOffset; + rankOffset = 0; + GetTestFileName(testFileName, test); + } + if (access(testFileName, F_OK) == 0) { + backend->delete(testFileName, test); + } + if (test->reorderTasksRandom == TRUE) { + rankOffset = tmpRankOffset; + GetTestFileName(testFileName, test); + } + } else { + if ((rank == 0) && (access(testFileName, F_OK) == 0)) { + backend->delete(testFileName, test); + } + } +} /* RemoveFile() */ /******************************************************************************/ /* * Setup tests by parsing commandline and creating test script. */ -IOR_queue_t * -SetupTests(int argc, char ** argv) +IOR_queue_t *SetupTests(int argc, char **argv) { - IOR_queue_t * tests, - * testsHead; + IOR_queue_t *tests, *testsHead; - /* count the tasks per node */ - tasksPerNode = CountTasksPerNode(numTasksWorld, MPI_COMM_WORLD); + /* count the tasks per node */ + tasksPerNode = CountTasksPerNode(numTasksWorld, MPI_COMM_WORLD); - testsHead = tests = ParseCommandLine(argc, argv); - /* - * Since there is no guarantee that anyone other than - * task 0 has the environment settings for the hints, pass - * the hint=value pair to everyone else in MPI_COMM_WORLD - */ - DistributeHints(); + testsHead = tests = ParseCommandLine(argc, argv); + /* + * Since there is no guarantee that anyone other than + * task 0 has the environment settings for the hints, pass + * the hint=value pair to everyone else in MPI_COMM_WORLD + */ + DistributeHints(); - /* check validity of tests and create test queue */ - while (tests != NULL) { - ValidTests(&tests->testParameters); - tests = tests->nextTest; - } + /* check validity of tests and create test queue */ + while (tests != NULL) { + ValidTests(&tests->testParameters); + tests = tests->nextTest; + } - /* check for skew between tasks' start times */ - wall_clock_deviation = TimeDeviation(); + /* check for skew between tasks' start times */ + wall_clock_deviation = TimeDeviation(); - /* seed random number generator */ - SeedRandGen(MPI_COMM_WORLD); + /* seed random number generator */ + SeedRandGen(MPI_COMM_WORLD); - return(testsHead); -} /* SetupTests() */ + return (testsHead); +} /* SetupTests() */ - -/******************************************************************************//* - * Setup transfer buffers, creating and filling as needed. - */ + /******************************************************************************//* + * Setup transfer buffers, creating and filling as needed. + */ void -SetupXferBuffers(void **buffer, - void **checkBuffer, - void **readCheckBuffer, - IOR_param_t *test, - int pretendRank, - int access) +SetupXferBuffers(void **buffer, + void **checkBuffer, + void **readCheckBuffer, + IOR_param_t * test, int pretendRank, int access) { - /* create buffer of filled data */ - *buffer = CreateBuffer(test->transferSize); - FillBuffer(*buffer, test, 0, pretendRank); - if (access == WRITECHECK || access == READCHECK) { - /* this allocates buffer only */ - *checkBuffer = CreateBuffer(test->transferSize); - if (access == READCHECK) { - *readCheckBuffer = CreateBuffer(test->transferSize); + /* create buffer of filled data */ + *buffer = CreateBuffer(test->transferSize); + FillBuffer(*buffer, test, 0, pretendRank); + if (access == WRITECHECK || access == READCHECK) { + /* this allocates buffer only */ + *checkBuffer = CreateBuffer(test->transferSize); + if (access == READCHECK) { + *readCheckBuffer = CreateBuffer(test->transferSize); + } } - } - return; -} /* SetupXferBuffers() */ - + return; +} /* SetupXferBuffers() */ /******************************************************************************/ /* * Print header information for test output. */ -void -ShowInfo(int argc, char **argv, IOR_param_t *test) +void ShowInfo(int argc, char **argv, IOR_param_t * test) { - int i; - struct utsname unamebuf; + int i; + struct utsname unamebuf; - fprintf(stdout, "IOR-"META_VERSION": MPI Coordinated Test of Parallel I/O\n\n"); + fprintf(stdout, + "IOR-" META_VERSION + ": MPI Coordinated Test of Parallel I/O\n\n"); - fprintf(stdout, "Run began: %s", CurrentTimeString()); -#if USE_UNDOC_OPT /* NFS */ - if (test->NFS_serverCount) { - fprintf(stdout, "NFS path: %s%s[0..%d]\n", test->NFS_rootPath, - test->NFS_serverName, test->NFS_serverCount-1); - } -#endif /* USE_UNDOC_OPT - NFS */ - fprintf(stdout, "Command line used:"); - for (i = 0; i < argc; i++) { - fprintf(stdout, " %s", argv[i]); - } - fprintf(stdout, "\n"); - if (uname(&unamebuf) != 0) { - WARN("uname failed"); - fprintf(stdout, "Machine: Unknown"); - } else { - fprintf(stdout, "Machine: %s %s", unamebuf.sysname, unamebuf.nodename); - if (verbose >= VERBOSE_2) { - fprintf(stdout, " %s %s %s", unamebuf.release, unamebuf.version, - unamebuf.machine); + fprintf(stdout, "Run began: %s", CurrentTimeString()); +#if USE_UNDOC_OPT /* NFS */ + if (test->NFS_serverCount) { + fprintf(stdout, "NFS path: %s%s[0..%d]\n", test->NFS_rootPath, + test->NFS_serverName, test->NFS_serverCount - 1); } - } - fprintf(stdout, "\n"); +#endif /* USE_UNDOC_OPT - NFS */ + fprintf(stdout, "Command line used:"); + for (i = 0; i < argc; i++) { + fprintf(stdout, " %s", argv[i]); + } + fprintf(stdout, "\n"); + if (uname(&unamebuf) != 0) { + WARN("uname failed"); + fprintf(stdout, "Machine: Unknown"); + } else { + fprintf(stdout, "Machine: %s %s", unamebuf.sysname, + unamebuf.nodename); + if (verbose >= VERBOSE_2) { + fprintf(stdout, " %s %s %s", unamebuf.release, + unamebuf.version, unamebuf.machine); + } + } + fprintf(stdout, "\n"); #ifdef _NO_MPI_TIMER - if (verbose >= VERBOSE_2) - fprintf(stdout, "Using unsynchronized POSIX timer\n"); -#else /* not _NO_MPI_TIMER */ - if (MPI_WTIME_IS_GLOBAL) { if (verbose >= VERBOSE_2) - fprintf(stdout, "Using synchronized MPI timer\n"); - } else { - if (verbose >= VERBOSE_2) - fprintf(stdout, "Using unsynchronized MPI timer\n"); - } -#endif /* _NO_MPI_TIMER */ - if (verbose >= VERBOSE_1) { - fprintf(stdout, "Start time skew across all tasks: %.02f sec\n", - wall_clock_deviation); - /* if pvfs2:, then skip */ - if (Regex(test->testFileName, "^[a-z][a-z].*:") == 0) { - DisplayFreespace(test); + fprintf(stdout, "Using unsynchronized POSIX timer\n"); +#else /* not _NO_MPI_TIMER */ + if (MPI_WTIME_IS_GLOBAL) { + if (verbose >= VERBOSE_2) + fprintf(stdout, "Using synchronized MPI timer\n"); + } else { + if (verbose >= VERBOSE_2) + fprintf(stdout, "Using unsynchronized MPI timer\n"); } - } - if (verbose >= VERBOSE_3) { /* show env */ - fprintf(stdout, "STARTING ENVIRON LOOP\n"); - for (i = 0; environ[i] != NULL; i++) { - fprintf(stdout, "%s\n", environ[i]); +#endif /* _NO_MPI_TIMER */ + if (verbose >= VERBOSE_1) { + fprintf(stdout, "Start time skew across all tasks: %.02f sec\n", + wall_clock_deviation); + /* if pvfs2:, then skip */ + if (Regex(test->testFileName, "^[a-z][a-z].*:") == 0) { + DisplayFreespace(test); + } } - fprintf(stdout, "ENDING ENVIRON LOOP\n"); - } - fflush(stdout); -} /* ShowInfo() */ - + if (verbose >= VERBOSE_3) { /* show env */ + fprintf(stdout, "STARTING ENVIRON LOOP\n"); + for (i = 0; environ[i] != NULL; i++) { + fprintf(stdout, "%s\n", environ[i]); + } + fprintf(stdout, "ENDING ENVIRON LOOP\n"); + } + fflush(stdout); +} /* ShowInfo() */ /******************************************************************************/ /* * Show simple test output with max results for iterations. */ -void -ShowSetup(IOR_param_t * test) +void ShowSetup(IOR_param_t * test) { - IOR_offset_t aggFileSizeForBW; + IOR_offset_t aggFileSizeForBW; - /* use expected file size of iteration #0 for display */ - aggFileSizeForBW = test->aggFileSizeFromCalc[0]; + /* use expected file size of iteration #0 for display */ + aggFileSizeForBW = test->aggFileSizeFromCalc[0]; - if (strcmp(test->debug, "") != 0) { - fprintf(stdout, "\n*** DEBUG MODE ***\n"); - fprintf(stdout, "*** %s ***\n\n", test->debug); - } - fprintf(stdout, "\nSummary:\n"); - fprintf(stdout, "\tapi = %s\n", - test->apiVersion); - fprintf(stdout, "\ttest filename = %s\n", test->testFileName); - fprintf(stdout, "\taccess = "); - if (test->filePerProc) { - fprintf(stdout, "file-per-process"); - } else { - fprintf(stdout, "single-shared-file"); - } - if (verbose >= VERBOSE_1 && strcmp(test->api, "POSIX") != 0) { - if (test->collective == FALSE) { - fprintf(stdout, ", independent"); - } else { - fprintf(stdout, ", collective"); + if (strcmp(test->debug, "") != 0) { + fprintf(stdout, "\n*** DEBUG MODE ***\n"); + fprintf(stdout, "*** %s ***\n\n", test->debug); } - } - fprintf(stdout, "\n"); - if (verbose >= VERBOSE_1) { - if (test->segmentCount > 1) { - fprintf(stdout, "\tpattern = strided (%d segments)\n", - (int)test->segmentCount); + fprintf(stdout, "\nSummary:\n"); + fprintf(stdout, "\tapi = %s\n", test->apiVersion); + fprintf(stdout, "\ttest filename = %s\n", test->testFileName); + fprintf(stdout, "\taccess = "); + if (test->filePerProc) { + fprintf(stdout, "file-per-process"); } else { - fprintf(stdout, "\tpattern = segmented (1 segment)\n"); + fprintf(stdout, "single-shared-file"); } - } - fprintf(stdout, "\tordering in a file ="); - if (test->randomOffset == FALSE) { - fprintf(stdout, " sequential offsets\n"); - } else { - fprintf(stdout, " random offsets\n"); - } - fprintf(stdout, "\tordering inter file="); - if (test->reorderTasks == FALSE && test->reorderTasksRandom == FALSE){ - fprintf(stdout, " no tasks offsets\n"); - } - if (test->reorderTasks == TRUE) - { - fprintf(stdout, "constant task offsets = %d\n",test->taskPerNodeOffset); - } - if (test->reorderTasksRandom == TRUE) - { - fprintf(stdout, "random task offsets >= %d, seed=%d\n",test->taskPerNodeOffset,test->reorderTasksRandomSeed); - } - fprintf(stdout, "\tclients = %d (%d per node)\n", - test->numTasks, test->tasksPerNode); - fprintf(stdout, "\trepetitions = %d\n", - test->repetitions); - fprintf(stdout, "\txfersize = %s\n", - HumanReadable(test->transferSize, BASE_TWO)); - fprintf(stdout, "\tblocksize = %s\n", - HumanReadable(test->blockSize, BASE_TWO)); - fprintf(stdout, "\taggregate filesize = %s\n", - HumanReadable(aggFileSizeForBW, BASE_TWO)); + if (verbose >= VERBOSE_1 && strcmp(test->api, "POSIX") != 0) { + if (test->collective == FALSE) { + fprintf(stdout, ", independent"); + } else { + fprintf(stdout, ", collective"); + } + } + fprintf(stdout, "\n"); + if (verbose >= VERBOSE_1) { + if (test->segmentCount > 1) { + fprintf(stdout, + "\tpattern = strided (%d segments)\n", + (int)test->segmentCount); + } else { + fprintf(stdout, + "\tpattern = segmented (1 segment)\n"); + } + } + fprintf(stdout, "\tordering in a file ="); + if (test->randomOffset == FALSE) { + fprintf(stdout, " sequential offsets\n"); + } else { + fprintf(stdout, " random offsets\n"); + } + fprintf(stdout, "\tordering inter file="); + if (test->reorderTasks == FALSE && test->reorderTasksRandom == FALSE) { + fprintf(stdout, " no tasks offsets\n"); + } + if (test->reorderTasks == TRUE) { + fprintf(stdout, "constant task offsets = %d\n", + test->taskPerNodeOffset); + } + if (test->reorderTasksRandom == TRUE) { + fprintf(stdout, "random task offsets >= %d, seed=%d\n", + test->taskPerNodeOffset, test->reorderTasksRandomSeed); + } + fprintf(stdout, "\tclients = %d (%d per node)\n", + test->numTasks, test->tasksPerNode); + fprintf(stdout, "\trepetitions = %d\n", test->repetitions); + fprintf(stdout, "\txfersize = %s\n", + HumanReadable(test->transferSize, BASE_TWO)); + fprintf(stdout, "\tblocksize = %s\n", + HumanReadable(test->blockSize, BASE_TWO)); + fprintf(stdout, "\taggregate filesize = %s\n", + HumanReadable(aggFileSizeForBW, BASE_TWO)); #ifdef HAVE_LUSTRE_LUSTRE_USER_H - fprintf(stdout, "\tLustre stripe size = %s\n", - ((test->lustre_stripe_size == 0) ? "Use default" : - HumanReadable(test->lustre_stripe_size, BASE_TWO))); - if (test->lustre_stripe_count == 0) { - fprintf(stdout, "\t stripe count = %s\n", "Use default"); - } else { - fprintf(stdout, "\t stripe count = %d\n", - test->lustre_stripe_count); - } -#endif /* HAVE_LUSTRE_LUSTRE_USER_H */ - if (test->deadlineForStonewalling > 0) { - fprintf(stdout, "\tUsing stonewalling = %d second(s)\n", - test->deadlineForStonewalling); - } - fprintf(stdout, "\n"); - /*fprintf(stdout, "\n ================================\n\n");*/ - fflush(stdout); -} /* ShowSetup() */ - + fprintf(stdout, "\tLustre stripe size = %s\n", + ((test->lustre_stripe_size == 0) ? "Use default" : + HumanReadable(test->lustre_stripe_size, BASE_TWO))); + if (test->lustre_stripe_count == 0) { + fprintf(stdout, "\t stripe count = %s\n", "Use default"); + } else { + fprintf(stdout, "\t stripe count = %d\n", + test->lustre_stripe_count); + } +#endif /* HAVE_LUSTRE_LUSTRE_USER_H */ + if (test->deadlineForStonewalling > 0) { + fprintf(stdout, "\tUsing stonewalling = %d second(s)\n", + test->deadlineForStonewalling); + } + fprintf(stdout, "\n"); + /*fprintf(stdout, "\n ================================\n\n"); */ + fflush(stdout); +} /* ShowSetup() */ /******************************************************************************/ /* * Show test description. */ -void -ShowTest(IOR_param_t * test) +void ShowTest(IOR_param_t * test) { - fprintf(stdout, "\n\n ================================\n\n"); - fprintf(stdout, "TEST:\t%s=%d\n", "id", test->id); - fprintf(stdout, "\t%s=%d\n", "testnum", test->TestNum); - fprintf(stdout, "\t%s=%s\n", "api", test->api); - fprintf(stdout, "\t%s=%s\n", "platform", test->platform); - fprintf(stdout, "\t%s=%s\n", "testFileName", test->testFileName); - fprintf(stdout, "\t%s=%s\n", "hintsFileName", test->hintsFileName); - fprintf(stdout, "\t%s=%d\n", "deadlineForStonewall", - test->deadlineForStonewalling); - fprintf(stdout, "\t%s=%d\n", "maxTimeDuration", test->maxTimeDuration); - fprintf(stdout, "\t%s=%d\n", "outlierThreshold", test->outlierThreshold); - fprintf(stdout, "\t%s=%s\n", "options", test->options); - fprintf(stdout, "\t%s=%d\n", "nodes", test->nodes); - fprintf(stdout, "\t%s=%d\n", "tasksPerNode", tasksPerNode); - fprintf(stdout, "\t%s=%d\n", "repetitions", test->repetitions); - fprintf(stdout, "\t%s=%d\n", "multiFile", test->multiFile); - fprintf(stdout, "\t%s=%d\n", "interTestDelay", test->interTestDelay); - fprintf(stdout, "\t%s=%d\n", "fsync", test->fsync); - fprintf(stdout, "\t%s=%d\n", "fsYncperwrite", test->fsyncPerWrite); - fprintf(stdout, "\t%s=%d\n", "useExistingTestFile", - test->useExistingTestFile); - fprintf(stdout, "\t%s=%d\n", "showHints", test->showHints); - fprintf(stdout, "\t%s=%d\n", "uniqueDir", test->uniqueDir); - fprintf(stdout, "\t%s=%d\n", "showHelp", test->showHelp); - fprintf(stdout, "\t%s=%d\n", "individualDataSets",test->individualDataSets); - fprintf(stdout, "\t%s=%d\n", "singleXferAttempt", test->singleXferAttempt); - fprintf(stdout, "\t%s=%d\n", "readFile", test->readFile); - fprintf(stdout, "\t%s=%d\n", "writeFile", test->writeFile); - fprintf(stdout, "\t%s=%d\n", "filePerProc", test->filePerProc); - fprintf(stdout, "\t%s=%d\n", "reorderTasks", test->reorderTasks); - fprintf(stdout, "\t%s=%d\n", "reorderTasksRandom", test->reorderTasksRandom); - fprintf(stdout, "\t%s=%d\n", "reorderTasksRandomSeed", test->reorderTasksRandomSeed); - fprintf(stdout, "\t%s=%d\n", "randomOffset", test->randomOffset); - fprintf(stdout, "\t%s=%d\n", "checkWrite", test->checkWrite); - fprintf(stdout, "\t%s=%d\n", "checkRead", test->checkRead); - fprintf(stdout, "\t%s=%d\n", "preallocate", test->preallocate); - fprintf(stdout, "\t%s=%d\n", "useFileView", test->useFileView); - fprintf(stdout, "\t%s=%lld\n", "setAlignment", test->setAlignment); - fprintf(stdout, "\t%s=%d\n", "storeFileOffset", test->storeFileOffset); - fprintf(stdout, "\t%s=%d\n", "useSharedFilePointer", - test->useSharedFilePointer); - fprintf(stdout, "\t%s=%d\n", "useO_DIRECT", test->useO_DIRECT); - fprintf(stdout, "\t%s=%d\n", "useStridedDatatype", - test->useStridedDatatype); - fprintf(stdout, "\t%s=%d\n", "keepFile", test->keepFile); - fprintf(stdout, "\t%s=%d\n", "keepFileWithError", test->keepFileWithError); - fprintf(stdout, "\t%s=%d\n", "quitOnError", test->quitOnError); - fprintf(stdout, "\t%s=%d\n", "verbose", verbose); - fprintf(stdout, "\t%s=%d\n", "setTimeStampSignature", - test->setTimeStampSignature); - fprintf(stdout, "\t%s=%d\n", "collective", test->collective); - fprintf(stdout, "\t%s=%lld", "segmentCount", test->segmentCount); - if (strcmp(test->api, "HDF5") == 0) { - fprintf(stdout, " (datasets)"); - } - fprintf(stdout, "\n"); - fprintf(stdout, "\t%s=%lld\n", "transferSize", test->transferSize); - fprintf(stdout, "\t%s=%lld\n", "blockSize", test->blockSize); -} /* ShowTest() */ - + fprintf(stdout, "\n\n ================================\n\n"); + fprintf(stdout, "TEST:\t%s=%d\n", "id", test->id); + fprintf(stdout, "\t%s=%d\n", "testnum", test->TestNum); + fprintf(stdout, "\t%s=%s\n", "api", test->api); + fprintf(stdout, "\t%s=%s\n", "platform", test->platform); + fprintf(stdout, "\t%s=%s\n", "testFileName", test->testFileName); + fprintf(stdout, "\t%s=%s\n", "hintsFileName", test->hintsFileName); + fprintf(stdout, "\t%s=%d\n", "deadlineForStonewall", + test->deadlineForStonewalling); + fprintf(stdout, "\t%s=%d\n", "maxTimeDuration", test->maxTimeDuration); + fprintf(stdout, "\t%s=%d\n", "outlierThreshold", + test->outlierThreshold); + fprintf(stdout, "\t%s=%s\n", "options", test->options); + fprintf(stdout, "\t%s=%d\n", "nodes", test->nodes); + fprintf(stdout, "\t%s=%d\n", "tasksPerNode", tasksPerNode); + fprintf(stdout, "\t%s=%d\n", "repetitions", test->repetitions); + fprintf(stdout, "\t%s=%d\n", "multiFile", test->multiFile); + fprintf(stdout, "\t%s=%d\n", "interTestDelay", test->interTestDelay); + fprintf(stdout, "\t%s=%d\n", "fsync", test->fsync); + fprintf(stdout, "\t%s=%d\n", "fsYncperwrite", test->fsyncPerWrite); + fprintf(stdout, "\t%s=%d\n", "useExistingTestFile", + test->useExistingTestFile); + fprintf(stdout, "\t%s=%d\n", "showHints", test->showHints); + fprintf(stdout, "\t%s=%d\n", "uniqueDir", test->uniqueDir); + fprintf(stdout, "\t%s=%d\n", "showHelp", test->showHelp); + fprintf(stdout, "\t%s=%d\n", "individualDataSets", + test->individualDataSets); + fprintf(stdout, "\t%s=%d\n", "singleXferAttempt", + test->singleXferAttempt); + fprintf(stdout, "\t%s=%d\n", "readFile", test->readFile); + fprintf(stdout, "\t%s=%d\n", "writeFile", test->writeFile); + fprintf(stdout, "\t%s=%d\n", "filePerProc", test->filePerProc); + fprintf(stdout, "\t%s=%d\n", "reorderTasks", test->reorderTasks); + fprintf(stdout, "\t%s=%d\n", "reorderTasksRandom", + test->reorderTasksRandom); + fprintf(stdout, "\t%s=%d\n", "reorderTasksRandomSeed", + test->reorderTasksRandomSeed); + fprintf(stdout, "\t%s=%d\n", "randomOffset", test->randomOffset); + fprintf(stdout, "\t%s=%d\n", "checkWrite", test->checkWrite); + fprintf(stdout, "\t%s=%d\n", "checkRead", test->checkRead); + fprintf(stdout, "\t%s=%d\n", "preallocate", test->preallocate); + fprintf(stdout, "\t%s=%d\n", "useFileView", test->useFileView); + fprintf(stdout, "\t%s=%lld\n", "setAlignment", test->setAlignment); + fprintf(stdout, "\t%s=%d\n", "storeFileOffset", test->storeFileOffset); + fprintf(stdout, "\t%s=%d\n", "useSharedFilePointer", + test->useSharedFilePointer); + fprintf(stdout, "\t%s=%d\n", "useO_DIRECT", test->useO_DIRECT); + fprintf(stdout, "\t%s=%d\n", "useStridedDatatype", + test->useStridedDatatype); + fprintf(stdout, "\t%s=%d\n", "keepFile", test->keepFile); + fprintf(stdout, "\t%s=%d\n", "keepFileWithError", + test->keepFileWithError); + fprintf(stdout, "\t%s=%d\n", "quitOnError", test->quitOnError); + fprintf(stdout, "\t%s=%d\n", "verbose", verbose); + fprintf(stdout, "\t%s=%d\n", "setTimeStampSignature", + test->setTimeStampSignature); + fprintf(stdout, "\t%s=%d\n", "collective", test->collective); + fprintf(stdout, "\t%s=%lld", "segmentCount", test->segmentCount); + if (strcmp(test->api, "HDF5") == 0) { + fprintf(stdout, " (datasets)"); + } + fprintf(stdout, "\n"); + fprintf(stdout, "\t%s=%lld\n", "transferSize", test->transferSize); + fprintf(stdout, "\t%s=%lld\n", "blockSize", test->blockSize); +} /* ShowTest() */ /******************************************************************************/ /* * Summarize results, showing max rates (and min, mean, stddev if verbose) */ -void -SummarizeResults(IOR_param_t * test) +void SummarizeResults(IOR_param_t * test) { - int rep, ival; - double maxWrite[2], minWrite[2], maxRead[2], minRead[2], - meanWrite[2], meanRead[2], - varWrite[2], varRead[2], - sdWrite[2], sdRead[2], - sumWrite[2], sumRead[2], - writeTimeSum, readTimeSum; + int rep, ival; + double maxWrite[2], minWrite[2], maxRead[2], minRead[2], + meanWrite[2], meanRead[2], + varWrite[2], varRead[2], + sdWrite[2], sdRead[2], + sumWrite[2], sumRead[2], writeTimeSum, readTimeSum; - for (ival=0; ival<2; ival++) - { - varWrite[ival] = 0; - varRead[ival] = 0; - sdWrite[ival] = 0; - sdRead[ival] = 0; - sumWrite[ival] = 0; - sumRead[ival] = 0; - writeTimeSum = 0; - readTimeSum = 0; + for (ival = 0; ival < 2; ival++) { + varWrite[ival] = 0; + varRead[ival] = 0; + sdWrite[ival] = 0; + sdRead[ival] = 0; + sumWrite[ival] = 0; + sumRead[ival] = 0; + writeTimeSum = 0; + readTimeSum = 0; - if (ival == 1) - { - for (rep = 0; rep < test->repetitions; rep++) - { - writeTimeSum += test->writeVal[ival][rep]; - readTimeSum += test->readVal [ival][rep]; - test->writeVal[ival][rep] = (double)test->numTasks*((double)test->blockSize/(double)test->transferSize)/test->writeVal[ival][rep]; - test->readVal [ival][rep] = (double)test->numTasks*((double)test->blockSize/(double)test->transferSize)/test->readVal [ival][rep]; - } - } + if (ival == 1) { + for (rep = 0; rep < test->repetitions; rep++) { + writeTimeSum += test->writeVal[ival][rep]; + readTimeSum += test->readVal[ival][rep]; + test->writeVal[ival][rep] = + (double)test->numTasks * + ((double)test->blockSize / + (double)test->transferSize) / + test->writeVal[ival][rep]; + test->readVal[ival][rep] = + (double)test->numTasks * + ((double)test->blockSize / + (double)test->transferSize) / + test->readVal[ival][rep]; + } + } - maxWrite[ival] = minWrite[ival] = test->writeVal[ival][0]; - maxRead[ival] = minRead[ival] = test->readVal[ival][0]; + maxWrite[ival] = minWrite[ival] = test->writeVal[ival][0]; + maxRead[ival] = minRead[ival] = test->readVal[ival][0]; - for (rep = 0; rep < test->repetitions; rep++) { - if (maxWrite[ival] < test->writeVal[ival][rep]) { - maxWrite[ival] = test->writeVal[ival][rep]; - } - if (maxRead[ival] < test->readVal[ival][rep]) { - maxRead[ival] = test->readVal[ival][rep]; - } - if (minWrite[ival] > test->writeVal[ival][rep]) { - minWrite[ival] = test->writeVal[ival][rep]; - } - if (minRead[ival] > test->readVal[ival][rep]) { - minRead[ival] = test->readVal[ival][rep]; - } - sumWrite[ival] += test->writeVal[ival][rep]; - sumRead[ival] += test->readVal[ival][rep]; - } + for (rep = 0; rep < test->repetitions; rep++) { + if (maxWrite[ival] < test->writeVal[ival][rep]) { + maxWrite[ival] = test->writeVal[ival][rep]; + } + if (maxRead[ival] < test->readVal[ival][rep]) { + maxRead[ival] = test->readVal[ival][rep]; + } + if (minWrite[ival] > test->writeVal[ival][rep]) { + minWrite[ival] = test->writeVal[ival][rep]; + } + if (minRead[ival] > test->readVal[ival][rep]) { + minRead[ival] = test->readVal[ival][rep]; + } + sumWrite[ival] += test->writeVal[ival][rep]; + sumRead[ival] += test->readVal[ival][rep]; + } - meanWrite[ival] = sumWrite[ival] / test->repetitions; - meanRead[ival] = sumRead[ival] / test->repetitions; + meanWrite[ival] = sumWrite[ival] / test->repetitions; + meanRead[ival] = sumRead[ival] / test->repetitions; - for (rep = 0; rep < test->repetitions; rep++) { - varWrite[ival] += pow((meanWrite[ival] - test->writeVal[ival][rep]), 2); - varRead[ival] += pow((meanRead[ival] - test->readVal[ival][rep]), 2); - } - varWrite[ival] = varWrite[ival] / test->repetitions; - varRead[ival] = varRead[ival] / test->repetitions; - sdWrite[ival] = sqrt(varWrite[ival]); - sdRead[ival] = sqrt(varRead[ival]); - } + for (rep = 0; rep < test->repetitions; rep++) { + varWrite[ival] += + pow((meanWrite[ival] - test->writeVal[ival][rep]), + 2); + varRead[ival] += + pow((meanRead[ival] - test->readVal[ival][rep]), 2); + } + varWrite[ival] = varWrite[ival] / test->repetitions; + varRead[ival] = varRead[ival] / test->repetitions; + sdWrite[ival] = sqrt(varWrite[ival]); + sdRead[ival] = sqrt(varRead[ival]); + } - if (rank == 0 && verbose >= VERBOSE_0) - { - fprintf(stdout, "Operation Max (MiB) Min (MiB) Mean (MiB) Std Dev Max (OPs) Min (OPs) Mean (OPs) Std Dev Mean (s) "); - if (verbose >= VERBOSE_1) - fprintf(stdout, "Op grep #Tasks tPN reps fPP reord reordoff reordrand seed segcnt blksiz xsize aggsize\n"); - fprintf(stdout, "\n"); - fprintf(stdout, "--------- --------- --------- ---------- ------- --------- --------- ---------- ------- --------\n"); - if (maxWrite[0] > 0.) - { - fprintf(stdout,"%s ", "write"); - fprintf(stdout,"%10.2f ", maxWrite[0]/MEBIBYTE); - fprintf(stdout,"%10.2f ", minWrite[0]/MEBIBYTE); - fprintf(stdout,"%10.2f", meanWrite[0]/MEBIBYTE); - fprintf(stdout,"%10.2f ", sdWrite[0]/MEBIBYTE); - fprintf(stdout,"%10.2f ", maxWrite[1]); - fprintf(stdout,"%10.2f ", minWrite[1]); - fprintf(stdout,"%10.2f", meanWrite[1]); - fprintf(stdout,"%10.2f", sdWrite[1]); - fprintf(stdout,"%10.5f ", writeTimeSum/(double)(test->repetitions)); - if (verbose >= VERBOSE_1) - { - fprintf(stdout,"%d ", test->numTasks); - fprintf(stdout,"%d ", test->tasksPerNode); - fprintf(stdout,"%d ", test->repetitions); - fprintf(stdout,"%d ", test->filePerProc); - fprintf(stdout,"%d ", test->reorderTasks); - fprintf(stdout,"%d ", test->taskPerNodeOffset); - fprintf(stdout,"%d ", test->reorderTasksRandom); - fprintf(stdout,"%d ", test->reorderTasksRandomSeed); - fprintf(stdout,"%lld ", test->segmentCount); - fprintf(stdout,"%lld ", test->blockSize); - fprintf(stdout,"%lld ", test->transferSize); - fprintf(stdout,"%lld ", test->aggFileSizeForBW[0]); - fprintf(stdout,"%d ", test->TestNum); - fprintf(stdout,"%s ", test->api); - } - fprintf(stdout,"EXCEL\n"); + if (rank == 0 && verbose >= VERBOSE_0) { + fprintf(stdout, + "Operation Max (MiB) Min (MiB) Mean (MiB) Std Dev Max (OPs) Min (OPs) Mean (OPs) Std Dev Mean (s) "); + if (verbose >= VERBOSE_1) + fprintf(stdout, + "Op grep #Tasks tPN reps fPP reord reordoff reordrand seed segcnt blksiz xsize aggsize\n"); + fprintf(stdout, "\n"); + fprintf(stdout, + "--------- --------- --------- ---------- ------- --------- --------- ---------- ------- --------\n"); + if (maxWrite[0] > 0.) { + fprintf(stdout, "%s ", "write"); + fprintf(stdout, "%10.2f ", maxWrite[0] / MEBIBYTE); + fprintf(stdout, "%10.2f ", minWrite[0] / MEBIBYTE); + fprintf(stdout, "%10.2f", meanWrite[0] / MEBIBYTE); + fprintf(stdout, "%10.2f ", sdWrite[0] / MEBIBYTE); + fprintf(stdout, "%10.2f ", maxWrite[1]); + fprintf(stdout, "%10.2f ", minWrite[1]); + fprintf(stdout, "%10.2f", meanWrite[1]); + fprintf(stdout, "%10.2f", sdWrite[1]); + fprintf(stdout, "%10.5f ", + writeTimeSum / (double)(test->repetitions)); + if (verbose >= VERBOSE_1) { + fprintf(stdout, "%d ", test->numTasks); + fprintf(stdout, "%d ", test->tasksPerNode); + fprintf(stdout, "%d ", test->repetitions); + fprintf(stdout, "%d ", test->filePerProc); + fprintf(stdout, "%d ", test->reorderTasks); + fprintf(stdout, "%d ", test->taskPerNodeOffset); + fprintf(stdout, "%d ", + test->reorderTasksRandom); + fprintf(stdout, "%d ", + test->reorderTasksRandomSeed); + fprintf(stdout, "%lld ", test->segmentCount); + fprintf(stdout, "%lld ", test->blockSize); + fprintf(stdout, "%lld ", test->transferSize); + fprintf(stdout, "%lld ", + test->aggFileSizeForBW[0]); + fprintf(stdout, "%d ", test->TestNum); + fprintf(stdout, "%s ", test->api); + } + fprintf(stdout, "EXCEL\n"); + } + if (maxRead[0] > 0.) { + fprintf(stdout, "%s ", "read"); + fprintf(stdout, "%10.2f ", maxRead[0] / MEBIBYTE); + fprintf(stdout, "%10.2f ", minRead[0] / MEBIBYTE); + fprintf(stdout, "%10.2f", meanRead[0] / MEBIBYTE); + fprintf(stdout, "%10.2f ", sdRead[0] / MEBIBYTE); + fprintf(stdout, "%10.2f ", maxRead[1]); + fprintf(stdout, "%10.2f ", minRead[1]); + fprintf(stdout, "%10.2f", meanRead[1]); + fprintf(stdout, "%10.2f", sdRead[1]); + fprintf(stdout, "%10.5f ", + readTimeSum / (double)(test->repetitions)); + if (verbose >= VERBOSE_1) { + fprintf(stdout, "%d ", test->numTasks); + fprintf(stdout, "%d ", test->tasksPerNode); + fprintf(stdout, "%d ", test->repetitions); + fprintf(stdout, "%d ", test->filePerProc); + fprintf(stdout, "%d ", test->reorderTasks); + fprintf(stdout, "%d ", test->taskPerNodeOffset); + fprintf(stdout, "%d ", + test->reorderTasksRandom); + fprintf(stdout, "%d ", + test->reorderTasksRandomSeed); + fprintf(stdout, "%lld ", test->segmentCount); + fprintf(stdout, "%lld ", test->blockSize); + fprintf(stdout, "%lld ", test->transferSize); + fprintf(stdout, "%lld ", + test->aggFileSizeForBW[0]); + fprintf(stdout, "%d ", test->TestNum); + fprintf(stdout, "%s ", test->api); + } + fprintf(stdout, "EXCEL\n"); + } + fflush(stdout); } - if (maxRead[0] > 0.) - { - fprintf(stdout,"%s ", "read"); - fprintf(stdout,"%10.2f ", maxRead[0]/MEBIBYTE); - fprintf(stdout,"%10.2f ", minRead[0]/MEBIBYTE); - fprintf(stdout,"%10.2f", meanRead[0]/MEBIBYTE); - fprintf(stdout,"%10.2f ", sdRead[0]/MEBIBYTE); - fprintf(stdout,"%10.2f ", maxRead[1]); - fprintf(stdout,"%10.2f ", minRead[1]); - fprintf(stdout,"%10.2f", meanRead[1]); - fprintf(stdout,"%10.2f", sdRead[1]); - fprintf(stdout,"%10.5f ", readTimeSum/(double)(test->repetitions)); - if (verbose >= VERBOSE_1) - { - fprintf(stdout,"%d ", test->numTasks); - fprintf(stdout,"%d ", test->tasksPerNode); - fprintf(stdout,"%d ", test->repetitions); - fprintf(stdout,"%d ", test->filePerProc); - fprintf(stdout,"%d ", test->reorderTasks); - fprintf(stdout,"%d ", test->taskPerNodeOffset); - fprintf(stdout,"%d ", test->reorderTasksRandom); - fprintf(stdout,"%d ", test->reorderTasksRandomSeed); - fprintf(stdout,"%lld ", test->segmentCount); - fprintf(stdout,"%lld ", test->blockSize); - fprintf(stdout,"%lld ", test->transferSize); - fprintf(stdout,"%lld ", test->aggFileSizeForBW[0]); - fprintf(stdout,"%d ", test->TestNum); - fprintf(stdout,"%s ", test->api); - } - fprintf(stdout,"EXCEL\n"); - } - fflush(stdout); - } - if (rank == 0 && verbose >= VERBOSE_0) { - fprintf(stdout, "\n"); - if (test->writeFile) { - fprintf(stdout, "Max Write: %.2f MiB/sec (%.2f MB/sec)\n", - maxWrite[0]/MEBIBYTE, maxWrite[0]/MEGABYTE); + if (rank == 0 && verbose >= VERBOSE_0) { + fprintf(stdout, "\n"); + if (test->writeFile) { + fprintf(stdout, + "Max Write: %.2f MiB/sec (%.2f MB/sec)\n", + maxWrite[0] / MEBIBYTE, maxWrite[0] / MEGABYTE); + } + if (test->readFile) { + fprintf(stdout, + "Max Read: %.2f MiB/sec (%.2f MB/sec)\n", + maxRead[0] / MEBIBYTE, maxRead[0] / MEGABYTE); + } + fprintf(stdout, "\n"); } - if (test->readFile) { - fprintf(stdout, "Max Read: %.2f MiB/sec (%.2f MB/sec)\n", - maxRead[0]/MEBIBYTE, maxRead[0]/MEGABYTE); - } - fprintf(stdout, "\n"); - } -} /* SummarizeResults() */ - +} /* SummarizeResults() */ /******************************************************************************/ /* * Using the test parameters, run iteration(s) of single test. */ -void -TestIoSys(IOR_param_t *test) +void TestIoSys(IOR_param_t * test) { - char testFileName[MAX_STR]; - double * timer[12]; - double startTime; - int i, - rep, - maxTimeDuration; - void * fd; - MPI_Group orig_group, new_group; - int range[3]; - IOR_offset_t dataMoved; /* for data rate calculation */ + char testFileName[MAX_STR]; + double *timer[12]; + double startTime; + int i, rep, maxTimeDuration; + void *fd; + MPI_Group orig_group, new_group; + int range[3]; + IOR_offset_t dataMoved; /* for data rate calculation */ - /* set up communicator for test */ - if (test->numTasks > numTasksWorld) { - if (rank == 0) { - fprintf(stdout, - "WARNING: More tasks requested (%d) than available (%d),", - test->numTasks, numTasksWorld); - fprintf(stdout," running on %d tasks.\n", numTasksWorld); - } - test->numTasks = numTasksWorld; - } - MPI_CHECK(MPI_Comm_group(MPI_COMM_WORLD, &orig_group), - "MPI_Comm_group() error"); - range[0] = 0; /* first rank */ - range[1] = test->numTasks - 1; /* last rank */ - range[2] = 1; /* stride */ - MPI_CHECK(MPI_Group_range_incl(orig_group, 1, &range, &new_group), - "MPI_Group_range_incl() error"); - MPI_CHECK(MPI_Comm_create(MPI_COMM_WORLD, new_group, &testComm), - "MPI_Comm_create() error"); - test->testComm = testComm; - if (testComm == MPI_COMM_NULL) { - /* tasks not in the group do not participate in this test */ - MPI_CHECK(MPI_Barrier(MPI_COMM_WORLD), "barrier error"); - return; - } - if (rank == 0 && verbose >= VERBOSE_1) { - fprintf(stdout, "Participating tasks: %d\n", test->numTasks); - fflush(stdout); - } - if (rank == 0 && test->reorderTasks == TRUE && verbose >= VERBOSE_1) { - fprintf(stdout, - "Using reorderTasks '-C' (expecting block, not cyclic, task assignment)\n"); - fflush(stdout); - } - test->tasksPerNode = CountTasksPerNode(test->numTasks, testComm); - - /* setup timers */ - for (i = 0; i < 12; i++) { - timer[i] = (double *)malloc(test->repetitions * sizeof(double)); - if (timer[i] == NULL) ERR("out of memory"); - } - for (i = 0; i < 2; i++) - { - test->writeVal[i] = (double *)malloc(test->repetitions * sizeof(double)); - if (test->writeVal[i] == NULL) ERR("out of memory"); - test->readVal[i] = (double *)malloc(test->repetitions * sizeof(double)); - if (test->readVal[i] == NULL) ERR("out of memory"); - for (rep = 0; rep < test->repetitions; rep++) { - test->writeVal[i][rep] = test->readVal[i][rep] = 0.0; - } - } - test->aggFileSizeFromCalc = - (IOR_offset_t *)malloc(test->repetitions * sizeof(IOR_offset_t)); - if (test->aggFileSizeFromCalc == NULL) ERR("out of memory"); - test->aggFileSizeFromStat = - (IOR_offset_t *)malloc(test->repetitions * sizeof(IOR_offset_t)); - if (test->aggFileSizeFromStat == NULL) ERR("out of memory"); - test->aggFileSizeFromXfer = - (IOR_offset_t *)malloc(test->repetitions * sizeof(IOR_offset_t)); - if (test->aggFileSizeFromXfer == NULL) ERR("out of memory"); - test->aggFileSizeForBW = - (IOR_offset_t *)malloc(test->repetitions * sizeof(IOR_offset_t)); - if (test->aggFileSizeForBW == NULL) ERR("out of memory"); - - /* bind I/O calls to specific API */ - AioriBind(test->api); - - /* file size is first calculated on for comparison */ - for (rep = 0; rep < test->repetitions; rep++) { - test->aggFileSizeFromCalc[rep] = test->blockSize * test->segmentCount * - test->numTasks; - } - - /* show test setup */ - if (rank == 0 && verbose >= VERBOSE_0) ShowSetup(test); - - startTime = GetTimeStamp(); - maxTimeDuration = test->maxTimeDuration * 60; /* convert to seconds */ - -#if USE_UNDOC_OPT /* fillTheFileSystem */ - if (rank == 0 && test->fillTheFileSystem && verbose >= VERBOSE_0) { - fprintf(stdout, "Run started: %s", CurrentTimeString()); - } -#endif /* USE_UNDOC_OPT - fillTheFileSystem */ - - /* loop over test iterations */ - for (rep = 0; rep < test->repetitions; rep++) { - - /* Get iteration start time in seconds in task 0 and broadcast to - all tasks */ - if (rank == 0) { - if (test->setTimeStampSignature) { - test->timeStampSignatureValue = - (unsigned int)test->setTimeStampSignature; - } else { - time_t currentTime; - if ((currentTime = time(NULL)) == -1) { - ERR("cannot get current time"); + /* set up communicator for test */ + if (test->numTasks > numTasksWorld) { + if (rank == 0) { + fprintf(stdout, + "WARNING: More tasks requested (%d) than available (%d),", + test->numTasks, numTasksWorld); + fprintf(stdout, " running on %d tasks.\n", + numTasksWorld); } - test->timeStampSignatureValue = (unsigned int)currentTime; - } - if (verbose >= VERBOSE_2) { - fprintf(stdout, - "Using Time Stamp %u (0x%x) for Data Signature\n", - test->timeStampSignatureValue, - test->timeStampSignatureValue); - } + test->numTasks = numTasksWorld; } - MPI_CHECK(MPI_Bcast(&test->timeStampSignatureValue, 1, MPI_UNSIGNED, 0, - testComm), "cannot broadcast start time value"); -#if USE_UNDOC_OPT /* fillTheFileSystem */ - if (test->fillTheFileSystem && - rep > 0 && rep % (test->fillTheFileSystem / test->numTasks) == 0) { - if (rank == 0 && verbose >= VERBOSE_0) { - fprintf(stdout, "at file #%d, time: %s", rep*test->numTasks, - CurrentTimeString()); + MPI_CHECK(MPI_Comm_group(MPI_COMM_WORLD, &orig_group), + "MPI_Comm_group() error"); + range[0] = 0; /* first rank */ + range[1] = test->numTasks - 1; /* last rank */ + range[2] = 1; /* stride */ + MPI_CHECK(MPI_Group_range_incl(orig_group, 1, &range, &new_group), + "MPI_Group_range_incl() error"); + MPI_CHECK(MPI_Comm_create(MPI_COMM_WORLD, new_group, &testComm), + "MPI_Comm_create() error"); + test->testComm = testComm; + if (testComm == MPI_COMM_NULL) { + /* tasks not in the group do not participate in this test */ + MPI_CHECK(MPI_Barrier(MPI_COMM_WORLD), "barrier error"); + return; + } + if (rank == 0 && verbose >= VERBOSE_1) { + fprintf(stdout, "Participating tasks: %d\n", test->numTasks); fflush(stdout); - } } -#endif /* USE_UNDOC_OPT - fillTheFileSystem */ - /* use repetition count for number of multiple files */ - if (test->multiFile) test->repCounter = rep; - - /* - * write the file(s), getting timing between I/O calls - */ - - if (test->writeFile -#if USE_UNDOC_OPT /* multiReRead */ - && (!test->multiReRead || !rep) -#endif /* USE_UNDOC_OPT - multiReRead */ - && (maxTimeDuration - ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { - GetTestFileName(testFileName, test); - if (verbose >= VERBOSE_3) { - fprintf(stdout, "task %d writing %s\n", rank, testFileName); - } - DelaySecs(test->interTestDelay); - if (test->useExistingTestFile == FALSE) { - RemoveFile(testFileName, test->filePerProc, test); - } - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - test->open = WRITE; - timer[0][rep] = GetTimeStamp(); - fd = backend->create(testFileName, test); - timer[1][rep] = GetTimeStamp(); - if (test->intraTestBarriers) - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - if (rank == 0 && verbose >= VERBOSE_1) { - fprintf(stdout, "Commencing write performance test.\n"); - fprintf(stdout, "%s\n", CurrentTimeString()); - } - timer[2][rep] = GetTimeStamp(); - dataMoved = WriteOrRead(test, fd, WRITE); - timer[3][rep] = GetTimeStamp(); - if (test->intraTestBarriers) - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - timer[4][rep] = GetTimeStamp(); - backend->close(fd, test); - -#if USE_UNDOC_OPT /* includeDeleteTime */ - if (test->includeDeleteTime) { - if (rank == 0 && verbose >= VERBOSE_1) { - fprintf(stdout, "** including delete time **\n"); - } - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - RemoveFile(testFileName, test->filePerProc, test); - } -#endif /* USE_UNDOC_OPT - includeDeleteTime */ - - timer[5][rep] = GetTimeStamp(); - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - -#if USE_UNDOC_OPT /* includeDeleteTime */ - if (test->includeDeleteTime) { - /* not accurate, but no longer a test file to examine */ - test->aggFileSizeFromStat[rep] = test->aggFileSizeFromCalc[rep]; - test->aggFileSizeFromXfer[rep] = test->aggFileSizeFromCalc[rep]; - test->aggFileSizeForBW[rep] = test->aggFileSizeFromCalc[rep]; - } else { -#endif /* USE_UNDOC_OPT - includeDeleteTime */ - - /* get the size of the file just written */ - test->aggFileSizeFromStat[rep] - = backend->get_file_size(test, testComm, testFileName); - - /* check if stat() of file doesn't equal expected file size, - use actual amount of byte moved */ - CheckFileSize(test, dataMoved, rep); - -#if USE_UNDOC_OPT /* includeDeleteTime */ - } -#endif /* USE_UNDOC_OPT - includeDeleteTime */ - - if (verbose >= VERBOSE_3) WriteTimes(test, timer, rep, WRITE); - ReduceIterResults(test, timer, rep, WRITE); - if (test->outlierThreshold) { - CheckForOutliers(test, timer, rep, WRITE); - } - } - - /* - * perform a check of data, reading back data and comparing - * against what was expected to be written - */ - if (test->checkWrite -#if USE_UNDOC_OPT /* multiReRead */ - && (!test->multiReRead || rep) -#endif /* USE_UNDOC_OPT - multiReRead */ - && (maxTimeDuration - ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { -#if USE_UNDOC_OPT /* corruptFile */ - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - /* intentionally corrupt file to determine if check works */ - if (test->corruptFile) { - CorruptFile(testFileName, test, rep, WRITECHECK); - } -#endif /* USE_UNDOC_OPT - corruptFile */ - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - if (rank == 0 && verbose >= VERBOSE_1) { + if (rank == 0 && test->reorderTasks == TRUE && verbose >= VERBOSE_1) { fprintf(stdout, - "Verifying contents of the file(s) just written.\n"); - fprintf(stdout, "%s\n", CurrentTimeString()); - } - if (test->reorderTasks) { - /* move two nodes away from writing node */ - rankOffset = (2*test->tasksPerNode) % test->numTasks; - } - GetTestFileName(testFileName, test); - test->open = WRITECHECK; - fd = backend->open(testFileName, test); - dataMoved = WriteOrRead(test, fd, WRITECHECK); - backend->close(fd, test); - rankOffset = 0; + "Using reorderTasks '-C' (expecting block, not cyclic, task assignment)\n"); + fflush(stdout); } - /* - * read the file(s), getting timing between I/O calls - */ - if (test->readFile - && (maxTimeDuration ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { - /* Get rankOffset [file offset] for this process to read, based on -C,-Z,-Q,-X options */ - /* Constant process offset reading */ - if (test->reorderTasks) { - /* move taskPerNodeOffset nodes[1==default] away from writing node */ - rankOffset = (test->taskPerNodeOffset*test->tasksPerNode) % test->numTasks; - } - /* random process offset reading */ - if (test->reorderTasksRandom) - { - /* this should not intefere with randomOffset within a file because GetOffsetArrayRandom */ - /* seeds every random() call */ - int *rankoffs, *filecont, *filehits, ifile, jfile, nodeoffset; - unsigned int iseed0; - nodeoffset = test->taskPerNodeOffset; - nodeoffset = (nodeoffset < test->nodes) ? nodeoffset : test->nodes-1; - iseed0 = (test->reorderTasksRandomSeed < 0) ? (-1*test->reorderTasksRandomSeed+rep):test->reorderTasksRandomSeed; - srand(rank+iseed0); - { rankOffset = rand() % test->numTasks; } - while (rankOffset < (nodeoffset*test->tasksPerNode)) { rankOffset = rand() % test->numTasks; } - /* Get more detailed stats if requested by verbose level */ - if (verbose >= VERBOSE_2) - { - if (rank == 0) - { - rankoffs = (int *)malloc(test->numTasks*sizeof(int)); - filecont = (int *)malloc(test->numTasks*sizeof(int)); - filehits = (int *)malloc(test->numTasks*sizeof(int)); - } - MPI_CHECK(MPI_Gather(&rankOffset,1,MPI_INT,rankoffs,1,MPI_INT,0,MPI_COMM_WORLD), "MPI_Gather error"); - /*file hits histogram*/ - if (rank == 0) - { - memset((void*)filecont,0,test->numTasks*sizeof(int)); - for (ifile=0; ifilenumTasks; ifile++) { filecont[(ifile+rankoffs[ifile])%test->numTasks]++; } - memset((void*)filehits,0,test->numTasks*sizeof(int)); - for (ifile=0; ifilenumTasks; ifile++) - for (jfile=0; jfilenumTasks; jfile++) { if (ifile == filecont[jfile]) filehits[ifile]++; } - /* fprintf(stdout, "File Contention Dist:"); - for (ifile=0; ifilenumTasks; ifile++) { fprintf(stdout," %d",filecont[ifile]); } - fprintf(stdout,"\n"); */ - fprintf(stdout, "#File Hits Dist:"); - jfile = 0; ifile = 0; - while (jfilenumTasks && - ifilenumTasks) { fprintf(stdout," %d",filehits[ifile]);jfile+=filehits[ifile],ifile++;} - fprintf(stdout," XXCEL\n"); - free(rankoffs); - free(filecont); - free(filehits); - } - } - } - /* Using globally passed rankOffset, following function generates testFileName to read */ - GetTestFileName(testFileName, test); + test->tasksPerNode = CountTasksPerNode(test->numTasks, testComm); - if (verbose >= VERBOSE_3) { - fprintf(stdout, "task %d reading %s\n", rank, testFileName); - } - DelaySecs(test->interTestDelay); - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - test->open = READ; - timer[6][rep] = GetTimeStamp(); - fd = backend->open(testFileName, test); - if (rank == 0 && verbose >= VERBOSE_2) { - fprintf(stdout, "[RANK %03d] open for reading file %s XXCEL\n", rank,testFileName); - } - timer[7][rep] = GetTimeStamp(); - if (test->intraTestBarriers) - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - if (rank == 0 && verbose >= VERBOSE_1) { - fprintf(stdout, "Commencing read performance test.\n"); - fprintf(stdout, "%s\n", CurrentTimeString()); - } - timer[8][rep] = GetTimeStamp(); - dataMoved = WriteOrRead(test, fd, READ); - timer[9][rep] = GetTimeStamp(); - if (test->intraTestBarriers) - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - timer[10][rep] = GetTimeStamp(); - backend->close(fd, test); - timer[11][rep] = GetTimeStamp(); - - /* get the size of the file just read */ - test->aggFileSizeFromStat[rep] = backend->get_file_size( - test, testComm, testFileName); - - /* check if stat() of file doesn't equal expected file size, - use actual amount of byte moved */ - CheckFileSize(test, dataMoved, rep); - - if (verbose >= VERBOSE_3) WriteTimes(test, timer, rep, READ); - ReduceIterResults(test, timer, rep, READ); - if (test->outlierThreshold) { - CheckForOutliers(test, timer, rep, READ); - } - } /* end readFile test */ - - /* - * perform a check of data, reading back data twice and - * comparing against what was expected to be read - */ - if (test->checkRead - && (maxTimeDuration - ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - if (rank == 0 && verbose >= VERBOSE_1) { - fprintf(stdout, "Re-reading the file(s) twice to "); - fprintf(stdout, "verify that reads are consistent.\n"); - fprintf(stdout, "%s\n", CurrentTimeString()); - } - if (test->reorderTasks) { - /* move three nodes away from reading node */ - rankOffset = (3*test->tasksPerNode) % test->numTasks; - } - GetTestFileName(testFileName, test); - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - test->open = READCHECK; - fd = backend->open(testFileName, test); - if (test->filePerProc) { - int tmpRankOffset; - tmpRankOffset = rankOffset; - /* increment rankOffset to open comparison file on other node */ - if (test->reorderTasks) { - /* move four nodes away from reading node */ - rankOffset = (4*test->tasksPerNode) % test->numTasks; + /* setup timers */ + for (i = 0; i < 12; i++) { + timer[i] = (double *)malloc(test->repetitions * sizeof(double)); + if (timer[i] == NULL) + ERR("out of memory"); + } + for (i = 0; i < 2; i++) { + test->writeVal[i] = + (double *)malloc(test->repetitions * sizeof(double)); + if (test->writeVal[i] == NULL) + ERR("out of memory"); + test->readVal[i] = + (double *)malloc(test->repetitions * sizeof(double)); + if (test->readVal[i] == NULL) + ERR("out of memory"); + for (rep = 0; rep < test->repetitions; rep++) { + test->writeVal[i][rep] = test->readVal[i][rep] = 0.0; } - GetTestFileName(test->testFileName_fppReadCheck, test); - rankOffset = tmpRankOffset; - test->fd_fppReadCheck = - backend->open(test->testFileName_fppReadCheck, test); - } - dataMoved = WriteOrRead(test, fd, READCHECK); - if (test->filePerProc) { - backend->close(test->fd_fppReadCheck, test); - test->fd_fppReadCheck = NULL; - } - backend->close(fd, test); } - /* - * this final barrier may not be necessary as backend->close should - * be a collective call -- but to make sure that the file has - * has not be removed by a task before another finishes writing, - * the MPI_Barrier() call has been included. - */ - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - if (!test->keepFile && !(test->keepFileWithError && test->errorFound)) { - RemoveFile(testFileName, test->filePerProc, test); + test->aggFileSizeFromCalc = + (IOR_offset_t *) malloc(test->repetitions * sizeof(IOR_offset_t)); + if (test->aggFileSizeFromCalc == NULL) + ERR("out of memory"); + test->aggFileSizeFromStat = + (IOR_offset_t *) malloc(test->repetitions * sizeof(IOR_offset_t)); + if (test->aggFileSizeFromStat == NULL) + ERR("out of memory"); + test->aggFileSizeFromXfer = + (IOR_offset_t *) malloc(test->repetitions * sizeof(IOR_offset_t)); + if (test->aggFileSizeFromXfer == NULL) + ERR("out of memory"); + test->aggFileSizeForBW = + (IOR_offset_t *) malloc(test->repetitions * sizeof(IOR_offset_t)); + if (test->aggFileSizeForBW == NULL) + ERR("out of memory"); + + /* bind I/O calls to specific API */ + AioriBind(test->api); + + /* file size is first calculated on for comparison */ + for (rep = 0; rep < test->repetitions; rep++) { + test->aggFileSizeFromCalc[rep] = + test->blockSize * test->segmentCount * test->numTasks; } - test->errorFound = FALSE; - MPI_CHECK(MPI_Barrier(testComm), "barrier error"); - rankOffset = 0; - } -#if USE_UNDOC_OPT /* fillTheFileSystem */ - if (rank == 0 && test->fillTheFileSystem && verbose >= VERBOSE_0) { - fprintf(stdout, "Run ended: %s", CurrentTimeString()); - } -#endif /* USE_UNDOC_OPT - fillTheFileSystem */ + /* show test setup */ + if (rank == 0 && verbose >= VERBOSE_0) + ShowSetup(test); - SummarizeResults(test); + startTime = GetTimeStamp(); + maxTimeDuration = test->maxTimeDuration * 60; /* convert to seconds */ - MPI_CHECK(MPI_Comm_free(&testComm), "MPI_Comm_free() error"); - for (i = 0; i < 2; i++) - { - free(test->writeVal[i]); - free(test->readVal[i]); - } - free(test->aggFileSizeFromCalc); - free(test->aggFileSizeFromStat); - free(test->aggFileSizeFromXfer); - free(test->aggFileSizeForBW); - for (i = 0; i < 12; i++) { - free(timer[i]); - } - /* Sync with the tasks that did not participate in this test */ - MPI_CHECK(MPI_Barrier(MPI_COMM_WORLD), "barrier error"); +#if USE_UNDOC_OPT /* fillTheFileSystem */ + if (rank == 0 && test->fillTheFileSystem && verbose >= VERBOSE_0) { + fprintf(stdout, "Run started: %s", CurrentTimeString()); + } +#endif /* USE_UNDOC_OPT - fillTheFileSystem */ -} /* TestIoSys() */ + /* loop over test iterations */ + for (rep = 0; rep < test->repetitions; rep++) { + /* Get iteration start time in seconds in task 0 and broadcast to + all tasks */ + if (rank == 0) { + if (test->setTimeStampSignature) { + test->timeStampSignatureValue = + (unsigned int)test->setTimeStampSignature; + } else { + time_t currentTime; + if ((currentTime = time(NULL)) == -1) { + ERR("cannot get current time"); + } + test->timeStampSignatureValue = + (unsigned int)currentTime; + } + if (verbose >= VERBOSE_2) { + fprintf(stdout, + "Using Time Stamp %u (0x%x) for Data Signature\n", + test->timeStampSignatureValue, + test->timeStampSignatureValue); + } + } + MPI_CHECK(MPI_Bcast + (&test->timeStampSignatureValue, 1, MPI_UNSIGNED, 0, + testComm), "cannot broadcast start time value"); +#if USE_UNDOC_OPT /* fillTheFileSystem */ + if (test->fillTheFileSystem && + rep > 0 + && rep % (test->fillTheFileSystem / test->numTasks) == 0) { + if (rank == 0 && verbose >= VERBOSE_0) { + fprintf(stdout, "at file #%d, time: %s", + rep * test->numTasks, + CurrentTimeString()); + fflush(stdout); + } + } +#endif /* USE_UNDOC_OPT - fillTheFileSystem */ + /* use repetition count for number of multiple files */ + if (test->multiFile) + test->repCounter = rep; + + /* + * write the file(s), getting timing between I/O calls + */ + + if (test->writeFile +#if USE_UNDOC_OPT /* multiReRead */ + && (!test->multiReRead || !rep) +#endif /* USE_UNDOC_OPT - multiReRead */ + && (maxTimeDuration + ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { + GetTestFileName(testFileName, test); + if (verbose >= VERBOSE_3) { + fprintf(stdout, "task %d writing %s\n", rank, + testFileName); + } + DelaySecs(test->interTestDelay); + if (test->useExistingTestFile == FALSE) { + RemoveFile(testFileName, test->filePerProc, + test); + } + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + test->open = WRITE; + timer[0][rep] = GetTimeStamp(); + fd = backend->create(testFileName, test); + timer[1][rep] = GetTimeStamp(); + if (test->intraTestBarriers) + MPI_CHECK(MPI_Barrier(testComm), + "barrier error"); + if (rank == 0 && verbose >= VERBOSE_1) { + fprintf(stdout, + "Commencing write performance test.\n"); + fprintf(stdout, "%s\n", CurrentTimeString()); + } + timer[2][rep] = GetTimeStamp(); + dataMoved = WriteOrRead(test, fd, WRITE); + timer[3][rep] = GetTimeStamp(); + if (test->intraTestBarriers) + MPI_CHECK(MPI_Barrier(testComm), + "barrier error"); + timer[4][rep] = GetTimeStamp(); + backend->close(fd, test); + +#if USE_UNDOC_OPT /* includeDeleteTime */ + if (test->includeDeleteTime) { + if (rank == 0 && verbose >= VERBOSE_1) { + fprintf(stdout, + "** including delete time **\n"); + } + MPI_CHECK(MPI_Barrier(testComm), + "barrier error"); + RemoveFile(testFileName, test->filePerProc, + test); + } +#endif /* USE_UNDOC_OPT - includeDeleteTime */ + + timer[5][rep] = GetTimeStamp(); + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + +#if USE_UNDOC_OPT /* includeDeleteTime */ + if (test->includeDeleteTime) { + /* not accurate, but no longer a test file to examine */ + test->aggFileSizeFromStat[rep] = + test->aggFileSizeFromCalc[rep]; + test->aggFileSizeFromXfer[rep] = + test->aggFileSizeFromCalc[rep]; + test->aggFileSizeForBW[rep] = + test->aggFileSizeFromCalc[rep]; + } else { +#endif /* USE_UNDOC_OPT - includeDeleteTime */ + + /* get the size of the file just written */ + test->aggFileSizeFromStat[rep] + = backend->get_file_size(test, testComm, + testFileName); + + /* check if stat() of file doesn't equal expected file size, + use actual amount of byte moved */ + CheckFileSize(test, dataMoved, rep); + +#if USE_UNDOC_OPT /* includeDeleteTime */ + } +#endif /* USE_UNDOC_OPT - includeDeleteTime */ + + if (verbose >= VERBOSE_3) + WriteTimes(test, timer, rep, WRITE); + ReduceIterResults(test, timer, rep, WRITE); + if (test->outlierThreshold) { + CheckForOutliers(test, timer, rep, WRITE); + } + } + + /* + * perform a check of data, reading back data and comparing + * against what was expected to be written + */ + if (test->checkWrite +#if USE_UNDOC_OPT /* multiReRead */ + && (!test->multiReRead || rep) +#endif /* USE_UNDOC_OPT - multiReRead */ + && (maxTimeDuration + ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { +#if USE_UNDOC_OPT /* corruptFile */ + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + /* intentionally corrupt file to determine if check works */ + if (test->corruptFile) { + CorruptFile(testFileName, test, rep, + WRITECHECK); + } +#endif /* USE_UNDOC_OPT - corruptFile */ + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + if (rank == 0 && verbose >= VERBOSE_1) { + fprintf(stdout, + "Verifying contents of the file(s) just written.\n"); + fprintf(stdout, "%s\n", CurrentTimeString()); + } + if (test->reorderTasks) { + /* move two nodes away from writing node */ + rankOffset = + (2 * test->tasksPerNode) % test->numTasks; + } + GetTestFileName(testFileName, test); + test->open = WRITECHECK; + fd = backend->open(testFileName, test); + dataMoved = WriteOrRead(test, fd, WRITECHECK); + backend->close(fd, test); + rankOffset = 0; + } + /* + * read the file(s), getting timing between I/O calls + */ + if (test->readFile + && (maxTimeDuration + ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { + /* Get rankOffset [file offset] for this process to read, based on -C,-Z,-Q,-X options */ + /* Constant process offset reading */ + if (test->reorderTasks) { + /* move taskPerNodeOffset nodes[1==default] away from writing node */ + rankOffset = + (test->taskPerNodeOffset * + test->tasksPerNode) % test->numTasks; + } + /* random process offset reading */ + if (test->reorderTasksRandom) { + /* this should not intefere with randomOffset within a file because GetOffsetArrayRandom */ + /* seeds every random() call */ + int *rankoffs, *filecont, *filehits, ifile, + jfile, nodeoffset; + unsigned int iseed0; + nodeoffset = test->taskPerNodeOffset; + nodeoffset = + (nodeoffset < + test->nodes) ? nodeoffset : test->nodes - + 1; + iseed0 = + (test->reorderTasksRandomSeed < + 0) ? (-1 * test->reorderTasksRandomSeed + + rep) : test->reorderTasksRandomSeed; + srand(rank + iseed0); + { + rankOffset = rand() % test->numTasks; + } + while (rankOffset < + (nodeoffset * test->tasksPerNode)) { + rankOffset = rand() % test->numTasks; + } + /* Get more detailed stats if requested by verbose level */ + if (verbose >= VERBOSE_2) { + if (rank == 0) { + rankoffs = + (int *)malloc(test->numTasks + * + sizeof(int)); + filecont = + (int *)malloc(test->numTasks + * + sizeof(int)); + filehits = + (int *)malloc(test->numTasks + * + sizeof(int)); + } + MPI_CHECK(MPI_Gather + (&rankOffset, 1, MPI_INT, + rankoffs, 1, MPI_INT, 0, + MPI_COMM_WORLD), + "MPI_Gather error"); + /*file hits histogram */ + if (rank == 0) { + memset((void *)filecont, 0, + test->numTasks * + sizeof(int)); + for (ifile = 0; + ifile < test->numTasks; + ifile++) { + filecont[(ifile + + rankoffs + [ifile]) % + test->numTasks]++; + } + memset((void *)filehits, 0, + test->numTasks * + sizeof(int)); + for (ifile = 0; + ifile < test->numTasks; + ifile++) + for (jfile = 0; + jfile < + test->numTasks; + jfile++) { + if (ifile == + filecont + [jfile]) + filehits + [ifile]++; + } + /* fprintf(stdout, "File Contention Dist:"); + for (ifile=0; ifilenumTasks; ifile++) { fprintf(stdout," %d",filecont[ifile]); } + fprintf(stdout,"\n"); */ + fprintf(stdout, + "#File Hits Dist:"); + jfile = 0; + ifile = 0; + while (jfile < test->numTasks && + ifile < test->numTasks) { + fprintf(stdout, " %d", + filehits + [ifile]); + jfile += + filehits[ifile], + ifile++; + } + fprintf(stdout, " XXCEL\n"); + free(rankoffs); + free(filecont); + free(filehits); + } + } + } + /* Using globally passed rankOffset, following function generates testFileName to read */ + GetTestFileName(testFileName, test); + + if (verbose >= VERBOSE_3) { + fprintf(stdout, "task %d reading %s\n", rank, + testFileName); + } + DelaySecs(test->interTestDelay); + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + test->open = READ; + timer[6][rep] = GetTimeStamp(); + fd = backend->open(testFileName, test); + if (rank == 0 && verbose >= VERBOSE_2) { + fprintf(stdout, + "[RANK %03d] open for reading file %s XXCEL\n", + rank, testFileName); + } + timer[7][rep] = GetTimeStamp(); + if (test->intraTestBarriers) + MPI_CHECK(MPI_Barrier(testComm), + "barrier error"); + if (rank == 0 && verbose >= VERBOSE_1) { + fprintf(stdout, + "Commencing read performance test.\n"); + fprintf(stdout, "%s\n", CurrentTimeString()); + } + timer[8][rep] = GetTimeStamp(); + dataMoved = WriteOrRead(test, fd, READ); + timer[9][rep] = GetTimeStamp(); + if (test->intraTestBarriers) + MPI_CHECK(MPI_Barrier(testComm), + "barrier error"); + timer[10][rep] = GetTimeStamp(); + backend->close(fd, test); + timer[11][rep] = GetTimeStamp(); + + /* get the size of the file just read */ + test->aggFileSizeFromStat[rep] = + backend->get_file_size(test, testComm, + testFileName); + + /* check if stat() of file doesn't equal expected file size, + use actual amount of byte moved */ + CheckFileSize(test, dataMoved, rep); + + if (verbose >= VERBOSE_3) + WriteTimes(test, timer, rep, READ); + ReduceIterResults(test, timer, rep, READ); + if (test->outlierThreshold) { + CheckForOutliers(test, timer, rep, READ); + } + } + + /* end readFile test */ + /* + * perform a check of data, reading back data twice and + * comparing against what was expected to be read + */ + if (test->checkRead + && (maxTimeDuration + ? (GetTimeStamp() - startTime < maxTimeDuration) : 1)) { + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + if (rank == 0 && verbose >= VERBOSE_1) { + fprintf(stdout, + "Re-reading the file(s) twice to "); + fprintf(stdout, + "verify that reads are consistent.\n"); + fprintf(stdout, "%s\n", CurrentTimeString()); + } + if (test->reorderTasks) { + /* move three nodes away from reading node */ + rankOffset = + (3 * test->tasksPerNode) % test->numTasks; + } + GetTestFileName(testFileName, test); + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + test->open = READCHECK; + fd = backend->open(testFileName, test); + if (test->filePerProc) { + int tmpRankOffset; + tmpRankOffset = rankOffset; + /* increment rankOffset to open comparison file on other node */ + if (test->reorderTasks) { + /* move four nodes away from reading node */ + rankOffset = + (4 * test->tasksPerNode) % + test->numTasks; + } + GetTestFileName(test->testFileName_fppReadCheck, + test); + rankOffset = tmpRankOffset; + test->fd_fppReadCheck = + backend-> + open(test->testFileName_fppReadCheck, test); + } + dataMoved = WriteOrRead(test, fd, READCHECK); + if (test->filePerProc) { + backend->close(test->fd_fppReadCheck, test); + test->fd_fppReadCheck = NULL; + } + backend->close(fd, test); + } + /* + * this final barrier may not be necessary as backend->close should + * be a collective call -- but to make sure that the file has + * has not be removed by a task before another finishes writing, + * the MPI_Barrier() call has been included. + */ + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + if (!test->keepFile + && !(test->keepFileWithError && test->errorFound)) { + RemoveFile(testFileName, test->filePerProc, test); + } + test->errorFound = FALSE; + MPI_CHECK(MPI_Barrier(testComm), "barrier error"); + rankOffset = 0; + } + +#if USE_UNDOC_OPT /* fillTheFileSystem */ + if (rank == 0 && test->fillTheFileSystem && verbose >= VERBOSE_0) { + fprintf(stdout, "Run ended: %s", CurrentTimeString()); + } +#endif /* USE_UNDOC_OPT - fillTheFileSystem */ + + SummarizeResults(test); + + MPI_CHECK(MPI_Comm_free(&testComm), "MPI_Comm_free() error"); + for (i = 0; i < 2; i++) { + free(test->writeVal[i]); + free(test->readVal[i]); + } + free(test->aggFileSizeFromCalc); + free(test->aggFileSizeFromStat); + free(test->aggFileSizeFromXfer); + free(test->aggFileSizeForBW); + for (i = 0; i < 12; i++) { + free(timer[i]); + } + /* Sync with the tasks that did not participate in this test */ + MPI_CHECK(MPI_Barrier(MPI_COMM_WORLD), "barrier error"); + +} /* TestIoSys() */ /******************************************************************************/ /* * Determine any spread (range) between node times. */ -double -TimeDeviation(void) +double TimeDeviation(void) { - double timestamp, min = 0, max = 0, roottimestamp; + double timestamp, min = 0, max = 0, roottimestamp; - MPI_CHECK(MPI_Barrier(MPI_COMM_WORLD), "barrier error"); - timestamp = GetTimeStamp(); - MPI_CHECK(MPI_Reduce(×tamp, &min, 1, MPI_DOUBLE, - MPI_MIN, 0, MPI_COMM_WORLD), - "cannot reduce tasks' times"); - MPI_CHECK(MPI_Reduce(×tamp, &max, 1, MPI_DOUBLE, - MPI_MAX, 0, MPI_COMM_WORLD), - "cannot reduce tasks' times"); + MPI_CHECK(MPI_Barrier(MPI_COMM_WORLD), "barrier error"); + timestamp = GetTimeStamp(); + MPI_CHECK(MPI_Reduce(×tamp, &min, 1, MPI_DOUBLE, + MPI_MIN, 0, MPI_COMM_WORLD), + "cannot reduce tasks' times"); + MPI_CHECK(MPI_Reduce(×tamp, &max, 1, MPI_DOUBLE, + MPI_MAX, 0, MPI_COMM_WORLD), + "cannot reduce tasks' times"); - /* delta between individual nodes' time and root node's time */ - roottimestamp = timestamp; - MPI_CHECK(MPI_Bcast(&roottimestamp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD), - "cannot broadcast root's time"); - wall_clock_delta = timestamp - roottimestamp; - - return max-min; -} /* TimeDeviation() */ + /* delta between individual nodes' time and root node's time */ + roottimestamp = timestamp; + MPI_CHECK(MPI_Bcast(&roottimestamp, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD), + "cannot broadcast root's time"); + wall_clock_delta = timestamp - roottimestamp; + return max - min; +} /* TimeDeviation() */ /******************************************************************************/ /* * Determine if valid tests from parameters. */ -void -ValidTests(IOR_param_t * test) +void ValidTests(IOR_param_t * test) { - IOR_param_t defaults; + IOR_param_t defaults; - init_IOR_Param_t(&defaults); - /* get the version of the tests */ - AioriBind(test->api); - backend->set_version(test); + init_IOR_Param_t(&defaults); + /* get the version of the tests */ + AioriBind(test->api); + backend->set_version(test); - if (test->repetitions <= 0) - WARN_RESET("too few test repetitions", - test, &defaults, repetitions); - if (test->numTasks <= 0) - ERR("too few tasks for testing"); - if (test->interTestDelay < 0) - WARN_RESET("inter-test delay must be nonnegative value", - test, &defaults, interTestDelay); - if (test->readFile != TRUE && test->writeFile != TRUE - && test->checkRead != TRUE && test->checkWrite != TRUE) - ERR("test must write, read, or check file"); - if ((test->deadlineForStonewalling > 0) - && (test->checkWrite == TRUE || test->checkRead == TRUE)) - ERR("can not perform write or read check with stonewalling"); - if (test->segmentCount < 0) - ERR("segment count must be positive value"); - if ((test->blockSize % sizeof(IOR_size_t)) != 0) - ERR("block size must be a multiple of access size"); - if (test->blockSize < 0) - ERR("block size must be non-negative integer"); - if ((test->transferSize % sizeof(IOR_size_t)) != 0) - ERR("transfer size must be a multiple of access size"); - if (test->setAlignment < 0) - ERR("alignment must be non-negative integer"); - if (test->transferSize < 0) - ERR("transfer size must be non-negative integer"); - if (test->transferSize == 0) { - ERR("test will not complete with zero transfer size"); - } else { - if ((test->blockSize % test->transferSize) != 0) - ERR("block size must be a multiple of transfer size"); - } - if (test->blockSize < test->transferSize) - ERR("block size must not be smaller than transfer size"); - if ((strcmp(test->api, "MPIIO") == 0) - && (test->blockSize < sizeof(IOR_size_t) - || test->transferSize < sizeof(IOR_size_t))) - ERR("block/transfer size may not be smaller than IOR_size_t for MPIIO"); - if ((strcmp(test->api, "HDF5") == 0) - && (test->blockSize < sizeof(IOR_size_t) - || test->transferSize < sizeof(IOR_size_t))) - ERR("block/transfer size may not be smaller than IOR_size_t for HDF5"); - if ((strcmp(test->api, "NCMPI") == 0) - && (test->blockSize < sizeof(IOR_size_t) - || test->transferSize < sizeof(IOR_size_t))) - ERR("block/transfer size may not be smaller than IOR_size_t for NCMPI"); - if ((strcmp(test->api, "NCMPI") == 0) - && ((test->numTasks * test->blockSize * test->segmentCount) - > (2*(IOR_offset_t)GIBIBYTE))) - ERR("file size must be < 2GiB"); - if((test->useFileView == TRUE) - && (sizeof(MPI_Aint) < 8) /* used for 64-bit datatypes */ - && ((test->numTasks * test->blockSize) > (2*(IOR_offset_t)GIBIBYTE))) - ERR("segment size must be < 2GiB"); - if ((strcmp(test->api, "POSIX") != 0) && test->singleXferAttempt) - WARN_RESET("retry only available in POSIX", - test, &defaults, singleXferAttempt); - if ((strcmp(test->api, "POSIX") != 0) && test->fsync) - WARN_RESET("fsync() only available in POSIX", - test, &defaults, fsync); - if ((strcmp(test->api, "MPIIO") != 0) && test->preallocate) - WARN_RESET("preallocation only available in MPIIO", - test, &defaults, preallocate); - if ((strcmp(test->api, "MPIIO") != 0) && test->useFileView) - WARN_RESET("file view only available in MPIIO", - test, &defaults, useFileView); - if ((strcmp(test->api, "MPIIO") != 0) && test->useSharedFilePointer) - WARN_RESET("shared file pointer only available in MPIIO", - test, &defaults, useSharedFilePointer); - if ((strcmp(test->api, "MPIIO") == 0) && test->useSharedFilePointer) - WARN_RESET("shared file pointer not implemented", - test, &defaults, useSharedFilePointer); - if ((strcmp(test->api, "MPIIO") != 0) && test->useStridedDatatype) - WARN_RESET("strided datatype only available in MPIIO", - test, &defaults, useStridedDatatype); - if ((strcmp(test->api, "MPIIO") == 0) && test->useStridedDatatype) - WARN_RESET("strided datatype not implemented", - test, &defaults, useStridedDatatype); - if ((strcmp(test->api, "MPIIO") == 0) - && test->useStridedDatatype - && (test->blockSize < sizeof(IOR_size_t) - || test->transferSize < sizeof(IOR_size_t))) - ERR("need larger file size for strided datatype in MPIIO"); - if ((strcmp(test->api, "POSIX") == 0) && test->showHints) - WARN_RESET("hints not available in POSIX", - test, &defaults, showHints); - if ((strcmp(test->api, "POSIX") == 0) && test->collective) - WARN_RESET("collective not available in POSIX", - test, &defaults, collective); - if (test->reorderTasks == TRUE && test->reorderTasksRandom == TRUE) - ERR("Both Constant and Random task re-ordering specified. Choose one and resubmit"); - if (test->randomOffset && test->reorderTasksRandom && test->filePerProc == FALSE) - ERR("random offset and random reorder tasks specified with single-shared-file. Choose one and resubmit"); - if (test->randomOffset && test->reorderTasks && test->filePerProc == FALSE) - ERR("random offset and constant reorder tasks specified with single-shared-file. Choose one and resubmit"); - if (test->randomOffset && test->checkRead) - ERR("random offset not available with read check option (use write check)"); - if (test->randomOffset && test->storeFileOffset) - ERR("random offset not available with store file offset option)"); - if ((strcmp(test->api, "MPIIO") == 0) && test->randomOffset && test->collective) - ERR("random offset not available with collective MPIIO"); - if ((strcmp(test->api, "MPIIO") == 0) && test->randomOffset && test->useFileView) - ERR("random offset not available with MPIIO fileviews"); - if ((strcmp(test->api, "HDF5") == 0) && test->randomOffset) - ERR("random offset not available with HDF5"); - if ((strcmp(test->api, "NCMPI") == 0) && test->randomOffset) - ERR("random offset not available with NCMPI"); - if ((strcmp(test->api, "HDF5") != 0) && test->individualDataSets) - WARN_RESET("individual datasets only available in HDF5", - test, &defaults, individualDataSets); - if ((strcmp(test->api, "HDF5") == 0) && test->individualDataSets) - WARN_RESET("individual data sets not implemented", - test, &defaults, individualDataSets); - if ((strcmp(test->api, "NCMPI") == 0) && test->filePerProc) - ERR("file-per-proc not available in current NCMPI"); - if (test->noFill) { - if (strcmp(test->api, "HDF5") != 0) { - ERR("'no fill' option only available in HDF5"); + if (test->repetitions <= 0) + WARN_RESET("too few test repetitions", + test, &defaults, repetitions); + if (test->numTasks <= 0) + ERR("too few tasks for testing"); + if (test->interTestDelay < 0) + WARN_RESET("inter-test delay must be nonnegative value", + test, &defaults, interTestDelay); + if (test->readFile != TRUE && test->writeFile != TRUE + && test->checkRead != TRUE && test->checkWrite != TRUE) + ERR("test must write, read, or check file"); + if ((test->deadlineForStonewalling > 0) + && (test->checkWrite == TRUE || test->checkRead == TRUE)) + ERR("can not perform write or read check with stonewalling"); + if (test->segmentCount < 0) + ERR("segment count must be positive value"); + if ((test->blockSize % sizeof(IOR_size_t)) != 0) + ERR("block size must be a multiple of access size"); + if (test->blockSize < 0) + ERR("block size must be non-negative integer"); + if ((test->transferSize % sizeof(IOR_size_t)) != 0) + ERR("transfer size must be a multiple of access size"); + if (test->setAlignment < 0) + ERR("alignment must be non-negative integer"); + if (test->transferSize < 0) + ERR("transfer size must be non-negative integer"); + if (test->transferSize == 0) { + ERR("test will not complete with zero transfer size"); } else { - /* check if hdf5 available */ - #if defined (H5_VERS_MAJOR) && defined (H5_VERS_MINOR) - /* no-fill option not available until hdf5-1.6.x */ - #if (H5_VERS_MAJOR > 0 && H5_VERS_MINOR > 5) - ; - #else - char errorString[MAX_STR]; - sprintf(errorString, "'no fill' option not available in %s", - test->apiVersion); - ERR(errorString); - #endif - #else - WARN("unable to determine HDF5 version for 'no fill' usage"); - #endif + if ((test->blockSize % test->transferSize) != 0) + ERR("block size must be a multiple of transfer size"); } - } - if (test->useExistingTestFile && test->lustre_set_striping) - ERR("Lustre stripe options are incompatible with useExistingTestFile"); -} /* ValidTests() */ - -IOR_offset_t * -GetOffsetArraySequential(IOR_param_t *test, int pretendRank) -{ - IOR_offset_t i, j, k = 0; - IOR_offset_t offsets; - IOR_offset_t *offsetArray; - - /* count needed offsets */ - offsets = (test->blockSize / test->transferSize) * test->segmentCount; - - /* setup empty array */ - offsetArray = (IOR_offset_t *)malloc((offsets+1) * sizeof(IOR_offset_t)); - if (offsetArray == NULL) - ERR("malloc() failed"); - offsetArray[offsets] = -1; /* set last offset with -1 */ - - /* fill with offsets */ - for (i = 0; i < test->segmentCount; i++) { - for (j = 0; j < (test->blockSize / test->transferSize); j++) { - offsetArray[k] = j * test->transferSize; - if (test->filePerProc) { - offsetArray[k] += i * test->blockSize; - } else { - offsetArray[k] += (i * test->numTasks * test->blockSize) - + (pretendRank * test->blockSize); - } - k++; + if (test->blockSize < test->transferSize) + ERR("block size must not be smaller than transfer size"); + if ((strcmp(test->api, "MPIIO") == 0) + && (test->blockSize < sizeof(IOR_size_t) + || test->transferSize < sizeof(IOR_size_t))) + ERR("block/transfer size may not be smaller than IOR_size_t for MPIIO"); + if ((strcmp(test->api, "HDF5") == 0) + && (test->blockSize < sizeof(IOR_size_t) + || test->transferSize < sizeof(IOR_size_t))) + ERR("block/transfer size may not be smaller than IOR_size_t for HDF5"); + if ((strcmp(test->api, "NCMPI") == 0) + && (test->blockSize < sizeof(IOR_size_t) + || test->transferSize < sizeof(IOR_size_t))) + ERR("block/transfer size may not be smaller than IOR_size_t for NCMPI"); + if ((strcmp(test->api, "NCMPI") == 0) + && ((test->numTasks * test->blockSize * test->segmentCount) + > (2 * (IOR_offset_t) GIBIBYTE))) + ERR("file size must be < 2GiB"); + if ((test->useFileView == TRUE) + && (sizeof(MPI_Aint) < 8) /* used for 64-bit datatypes */ + &&((test->numTasks * test->blockSize) > + (2 * (IOR_offset_t) GIBIBYTE))) + ERR("segment size must be < 2GiB"); + if ((strcmp(test->api, "POSIX") != 0) && test->singleXferAttempt) + WARN_RESET("retry only available in POSIX", + test, &defaults, singleXferAttempt); + if ((strcmp(test->api, "POSIX") != 0) && test->fsync) + WARN_RESET("fsync() only available in POSIX", + test, &defaults, fsync); + if ((strcmp(test->api, "MPIIO") != 0) && test->preallocate) + WARN_RESET("preallocation only available in MPIIO", + test, &defaults, preallocate); + if ((strcmp(test->api, "MPIIO") != 0) && test->useFileView) + WARN_RESET("file view only available in MPIIO", + test, &defaults, useFileView); + if ((strcmp(test->api, "MPIIO") != 0) && test->useSharedFilePointer) + WARN_RESET("shared file pointer only available in MPIIO", + test, &defaults, useSharedFilePointer); + if ((strcmp(test->api, "MPIIO") == 0) && test->useSharedFilePointer) + WARN_RESET("shared file pointer not implemented", + test, &defaults, useSharedFilePointer); + if ((strcmp(test->api, "MPIIO") != 0) && test->useStridedDatatype) + WARN_RESET("strided datatype only available in MPIIO", + test, &defaults, useStridedDatatype); + if ((strcmp(test->api, "MPIIO") == 0) && test->useStridedDatatype) + WARN_RESET("strided datatype not implemented", + test, &defaults, useStridedDatatype); + if ((strcmp(test->api, "MPIIO") == 0) + && test->useStridedDatatype && (test->blockSize < sizeof(IOR_size_t) + || test->transferSize < + sizeof(IOR_size_t))) + ERR("need larger file size for strided datatype in MPIIO"); + if ((strcmp(test->api, "POSIX") == 0) && test->showHints) + WARN_RESET("hints not available in POSIX", + test, &defaults, showHints); + if ((strcmp(test->api, "POSIX") == 0) && test->collective) + WARN_RESET("collective not available in POSIX", + test, &defaults, collective); + if (test->reorderTasks == TRUE && test->reorderTasksRandom == TRUE) + ERR("Both Constant and Random task re-ordering specified. Choose one and resubmit"); + if (test->randomOffset && test->reorderTasksRandom + && test->filePerProc == FALSE) + ERR("random offset and random reorder tasks specified with single-shared-file. Choose one and resubmit"); + if (test->randomOffset && test->reorderTasks + && test->filePerProc == FALSE) + ERR("random offset and constant reorder tasks specified with single-shared-file. Choose one and resubmit"); + if (test->randomOffset && test->checkRead) + ERR("random offset not available with read check option (use write check)"); + if (test->randomOffset && test->storeFileOffset) + ERR("random offset not available with store file offset option)"); + if ((strcmp(test->api, "MPIIO") == 0) && test->randomOffset + && test->collective) + ERR("random offset not available with collective MPIIO"); + if ((strcmp(test->api, "MPIIO") == 0) && test->randomOffset + && test->useFileView) + ERR("random offset not available with MPIIO fileviews"); + if ((strcmp(test->api, "HDF5") == 0) && test->randomOffset) + ERR("random offset not available with HDF5"); + if ((strcmp(test->api, "NCMPI") == 0) && test->randomOffset) + ERR("random offset not available with NCMPI"); + if ((strcmp(test->api, "HDF5") != 0) && test->individualDataSets) + WARN_RESET("individual datasets only available in HDF5", + test, &defaults, individualDataSets); + if ((strcmp(test->api, "HDF5") == 0) && test->individualDataSets) + WARN_RESET("individual data sets not implemented", + test, &defaults, individualDataSets); + if ((strcmp(test->api, "NCMPI") == 0) && test->filePerProc) + ERR("file-per-proc not available in current NCMPI"); + if (test->noFill) { + if (strcmp(test->api, "HDF5") != 0) { + ERR("'no fill' option only available in HDF5"); + } else { + /* check if hdf5 available */ +#if defined (H5_VERS_MAJOR) && defined (H5_VERS_MINOR) + /* no-fill option not available until hdf5-1.6.x */ +#if (H5_VERS_MAJOR > 0 && H5_VERS_MINOR > 5) + ; +#else + char errorString[MAX_STR]; + sprintf(errorString, + "'no fill' option not available in %s", + test->apiVersion); + ERR(errorString); +#endif +#else + WARN("unable to determine HDF5 version for 'no fill' usage"); +#endif + } } - } + if (test->useExistingTestFile && test->lustre_set_striping) + ERR("Lustre stripe options are incompatible with useExistingTestFile"); +} /* ValidTests() */ - return(offsetArray); -} /* GetOffsetArraySequential() */ - - -IOR_offset_t * -GetOffsetArrayRandom(IOR_param_t *test, int pretendRank, int access) +IOR_offset_t *GetOffsetArraySequential(IOR_param_t * test, int pretendRank) { - int seed; - IOR_offset_t i, value, tmp; - IOR_offset_t offsets = 0, offsetCnt = 0; - IOR_offset_t fileSize; - IOR_offset_t *offsetArray; + IOR_offset_t i, j, k = 0; + IOR_offset_t offsets; + IOR_offset_t *offsetArray; - /* set up seed for random() */ - if (access == WRITE || access == READ) { - test->randomSeed = seed = random(); - } else { - seed = test->randomSeed; - } - srandom(seed); + /* count needed offsets */ + offsets = (test->blockSize / test->transferSize) * test->segmentCount; - fileSize = test->blockSize * test->segmentCount; - if (test->filePerProc == FALSE) { - fileSize *= test->numTasks; - } + /* setup empty array */ + offsetArray = + (IOR_offset_t *) malloc((offsets + 1) * sizeof(IOR_offset_t)); + if (offsetArray == NULL) + ERR("malloc() failed"); + offsetArray[offsets] = -1; /* set last offset with -1 */ - /* count needed offsets (pass 1) */ - for (i = 0; i < fileSize; i += test->transferSize) { + /* fill with offsets */ + for (i = 0; i < test->segmentCount; i++) { + for (j = 0; j < (test->blockSize / test->transferSize); j++) { + offsetArray[k] = j * test->transferSize; + if (test->filePerProc) { + offsetArray[k] += i * test->blockSize; + } else { + offsetArray[k] += + (i * test->numTasks * test->blockSize) + + (pretendRank * test->blockSize); + } + k++; + } + } + + return (offsetArray); +} /* GetOffsetArraySequential() */ + +IOR_offset_t *GetOffsetArrayRandom(IOR_param_t * test, int pretendRank, + int access) +{ + int seed; + IOR_offset_t i, value, tmp; + IOR_offset_t offsets = 0, offsetCnt = 0; + IOR_offset_t fileSize; + IOR_offset_t *offsetArray; + + /* set up seed for random() */ + if (access == WRITE || access == READ) { + test->randomSeed = seed = random(); + } else { + seed = test->randomSeed; + } + srandom(seed); + + fileSize = test->blockSize * test->segmentCount; if (test->filePerProc == FALSE) { - if ((random() % test->numTasks) == pretendRank) { - offsets++; - } - } else { - offsets++; + fileSize *= test->numTasks; } - } - /* setup empty array */ - offsetArray = (IOR_offset_t *)malloc((offsets+1) * sizeof(IOR_offset_t)); - if (offsetArray == NULL) - ERR("malloc() failed"); - offsetArray[offsets] = -1; /* set last offset with -1 */ - - if (test->filePerProc) { - /* fill array */ - for (i = 0; i < offsets; i++) { - offsetArray[i] = i * test->transferSize; - } - } else { - /* fill with offsets (pass 2) */ - srandom(seed); /* need same seed */ + /* count needed offsets (pass 1) */ for (i = 0; i < fileSize; i += test->transferSize) { - if ((random() % test->numTasks) == pretendRank) { - offsetArray[offsetCnt] = i; - offsetCnt++; - } + if (test->filePerProc == FALSE) { + if ((random() % test->numTasks) == pretendRank) { + offsets++; + } + } else { + offsets++; + } } - } - /* reorder array */ - for (i = 0; i < offsets; i++) { - value = random() % offsets; - tmp = offsetArray[value]; - offsetArray[value] = offsetArray[i]; - offsetArray[i] = tmp; - } - SeedRandGen(test->testComm); /* synchronize seeds across tasks */ - return(offsetArray); -} /* GetOffsetArrayRandom() */ + /* setup empty array */ + offsetArray = + (IOR_offset_t *) malloc((offsets + 1) * sizeof(IOR_offset_t)); + if (offsetArray == NULL) + ERR("malloc() failed"); + offsetArray[offsets] = -1; /* set last offset with -1 */ + if (test->filePerProc) { + /* fill array */ + for (i = 0; i < offsets; i++) { + offsetArray[i] = i * test->transferSize; + } + } else { + /* fill with offsets (pass 2) */ + srandom(seed); /* need same seed */ + for (i = 0; i < fileSize; i += test->transferSize) { + if ((random() % test->numTasks) == pretendRank) { + offsetArray[offsetCnt] = i; + offsetCnt++; + } + } + } + /* reorder array */ + for (i = 0; i < offsets; i++) { + value = random() % offsets; + tmp = offsetArray[value]; + offsetArray[value] = offsetArray[i]; + offsetArray[i] = tmp; + } + SeedRandGen(test->testComm); /* synchronize seeds across tasks */ + + return (offsetArray); +} /* GetOffsetArrayRandom() */ /******************************************************************************/ /* @@ -2544,142 +2608,159 @@ GetOffsetArrayRandom(IOR_param_t *test, int pretendRank, int access) * out the data to each block in transfer sizes, until the remainder left is 0. */ -IOR_offset_t -WriteOrRead(IOR_param_t * test, - void * fd, - int access) +IOR_offset_t WriteOrRead(IOR_param_t * test, void *fd, int access) { - int errors = 0; - IOR_offset_t amtXferred, - transfer, - transferCount = 0, - pairCnt = 0, - * offsetArray; - int pretendRank; - void * buffer = NULL; - void * checkBuffer = NULL; - void * readCheckBuffer = NULL; - IOR_offset_t dataMoved = 0; /* for data rate calculation */ - double startForStonewall; - int hitStonewall; + int errors = 0; + IOR_offset_t amtXferred, + transfer, transferCount = 0, pairCnt = 0, *offsetArray; + int pretendRank; + void *buffer = NULL; + void *checkBuffer = NULL; + void *readCheckBuffer = NULL; + IOR_offset_t dataMoved = 0; /* for data rate calculation */ + double startForStonewall; + int hitStonewall; + /* initialize values */ + pretendRank = (rank + rankOffset) % test->numTasks; - /* initialize values */ - pretendRank = (rank + rankOffset) % test->numTasks; - - if (test->randomOffset) { - offsetArray = GetOffsetArrayRandom(test, pretendRank, access); - } else { - offsetArray = GetOffsetArraySequential(test, pretendRank); - } - - SetupXferBuffers(&buffer, &checkBuffer, &readCheckBuffer, - test, pretendRank, access); - - /* check for stonewall */ - startForStonewall = GetTimeStamp(); - hitStonewall = ((test->deadlineForStonewalling != 0) - && ((GetTimeStamp() - startForStonewall) - > test->deadlineForStonewalling)); - - /* loop over offsets to access */ - while ((offsetArray[pairCnt] != -1) && !hitStonewall) { - test->offset = offsetArray[pairCnt]; - /* - * fills each transfer with a unique pattern - * containing the offset into the file - */ - if (test->storeFileOffset == TRUE) { - FillBuffer(buffer, test, test->offset, pretendRank); + if (test->randomOffset) { + offsetArray = GetOffsetArrayRandom(test, pretendRank, access); + } else { + offsetArray = GetOffsetArraySequential(test, pretendRank); } - transfer = test->transferSize; - if (access == WRITE) { - amtXferred = backend->xfer(access, fd, buffer, transfer, test); - if (amtXferred != transfer) - ERR("cannot write to file"); - } else if (access == READ) { - amtXferred = backend->xfer(access, fd, buffer, transfer, test); - if (amtXferred != transfer) - ERR("cannot read from file"); - } else if (access == WRITECHECK) { - memset(checkBuffer, 'a', transfer); - amtXferred = backend->xfer(access, fd, checkBuffer, transfer, test); - if (amtXferred != transfer) - ERR("cannot read from file write check"); - transferCount++; - errors += CompareBuffers(buffer, checkBuffer, transfer, - transferCount, test, WRITECHECK); - } else if (access == READCHECK){ - ReadCheck(fd, buffer, checkBuffer, readCheckBuffer, test, - transfer, test->blockSize, &amtXferred, - &transferCount, access, &errors); - } - dataMoved += amtXferred; - pairCnt++; + SetupXferBuffers(&buffer, &checkBuffer, &readCheckBuffer, + test, pretendRank, access); + + /* check for stonewall */ + startForStonewall = GetTimeStamp(); hitStonewall = ((test->deadlineForStonewalling != 0) && ((GetTimeStamp() - startForStonewall) > test->deadlineForStonewalling)); - } - totalErrorCount += CountErrors(test, access, errors); + /* loop over offsets to access */ + while ((offsetArray[pairCnt] != -1) && !hitStonewall) { + test->offset = offsetArray[pairCnt]; + /* + * fills each transfer with a unique pattern + * containing the offset into the file + */ + if (test->storeFileOffset == TRUE) { + FillBuffer(buffer, test, test->offset, pretendRank); + } + transfer = test->transferSize; + if (access == WRITE) { + amtXferred = + backend->xfer(access, fd, buffer, transfer, test); + if (amtXferred != transfer) + ERR("cannot write to file"); + } else if (access == READ) { + amtXferred = + backend->xfer(access, fd, buffer, transfer, test); + if (amtXferred != transfer) + ERR("cannot read from file"); + } else if (access == WRITECHECK) { + memset(checkBuffer, 'a', transfer); + amtXferred = + backend->xfer(access, fd, checkBuffer, transfer, + test); + if (amtXferred != transfer) + ERR("cannot read from file write check"); + transferCount++; + errors += CompareBuffers(buffer, checkBuffer, transfer, + transferCount, test, + WRITECHECK); + } else if (access == READCHECK) { + ReadCheck(fd, buffer, checkBuffer, readCheckBuffer, + test, transfer, test->blockSize, &amtXferred, + &transferCount, access, &errors); + } + dataMoved += amtXferred; + pairCnt++; - FreeBuffers(access, checkBuffer, readCheckBuffer, buffer, offsetArray); + hitStonewall = ((test->deadlineForStonewalling != 0) + && ((GetTimeStamp() - startForStonewall) + > test->deadlineForStonewalling)); + } - if (access == WRITE && test->fsync == TRUE) { - backend->fsync(fd, test); /*fsync after all accesses*/ - } - return(dataMoved); -} /* WriteOrRead() */ + totalErrorCount += CountErrors(test, access, errors); + FreeBuffers(access, checkBuffer, readCheckBuffer, buffer, offsetArray); + + if (access == WRITE && test->fsync == TRUE) { + backend->fsync(fd, test); /*fsync after all accesses */ + } + return (dataMoved); +} /* WriteOrRead() */ /******************************************************************************/ /* * Write times taken during each iteration of the test. */ - + void -WriteTimes(IOR_param_t * test, - double ** timer, - int iteration, - int writeOrRead) +WriteTimes(IOR_param_t * test, double **timer, int iteration, int writeOrRead) { - char accessType[MAX_STR], - timerName[MAX_STR]; - int i, - start, - stop; + char accessType[MAX_STR], timerName[MAX_STR]; + int i, start, stop; - if (writeOrRead == WRITE) { - start = 0; - stop = 6; - strcpy(accessType, "WRITE"); - } else if (writeOrRead == READ) { - start = 6; - stop = 12; - strcpy(accessType, "READ"); - } else { - ERR("incorrect WRITE/READ option"); - } - - for (i = start; i < stop; i++) { - switch(i) { - case 0: strcpy(timerName, "write open start"); break; - case 1: strcpy(timerName, "write open stop"); break; - case 2: strcpy(timerName, "write start"); break; - case 3: strcpy(timerName, "write stop"); break; - case 4: strcpy(timerName, "write close start"); break; - case 5: strcpy(timerName, "write close stop"); break; - case 6: strcpy(timerName, "read open start"); break; - case 7: strcpy(timerName, "read open stop"); break; - case 8: strcpy(timerName, "read start"); break; - case 9: strcpy(timerName, "read stop"); break; - case 10: strcpy(timerName, "read close start"); break; - case 11: strcpy(timerName, "read close stop"); break; - default: strcpy(timerName, "invalid timer"); break; + if (writeOrRead == WRITE) { + start = 0; + stop = 6; + strcpy(accessType, "WRITE"); + } else if (writeOrRead == READ) { + start = 6; + stop = 12; + strcpy(accessType, "READ"); + } else { + ERR("incorrect WRITE/READ option"); } - fprintf(stdout, "Test %d: Iter=%d, Task=%d, Time=%f, %s\n", - test->id, iteration, (int)rank, timer[i][iteration], timerName); - } -} /* WriteTimes() */ + for (i = start; i < stop; i++) { + switch (i) { + case 0: + strcpy(timerName, "write open start"); + break; + case 1: + strcpy(timerName, "write open stop"); + break; + case 2: + strcpy(timerName, "write start"); + break; + case 3: + strcpy(timerName, "write stop"); + break; + case 4: + strcpy(timerName, "write close start"); + break; + case 5: + strcpy(timerName, "write close stop"); + break; + case 6: + strcpy(timerName, "read open start"); + break; + case 7: + strcpy(timerName, "read open stop"); + break; + case 8: + strcpy(timerName, "read start"); + break; + case 9: + strcpy(timerName, "read stop"); + break; + case 10: + strcpy(timerName, "read close start"); + break; + case 11: + strcpy(timerName, "read close stop"); + break; + default: + strcpy(timerName, "invalid timer"); + break; + } + fprintf(stdout, "Test %d: Iter=%d, Task=%d, Time=%f, %s\n", + test->id, iteration, (int)rank, timer[i][iteration], + timerName); + } +} /* WriteTimes() */ diff --git a/src/parse_options.c b/src/parse_options.c index 80f842d..f45b03f 100644 --- a/src/parse_options.c +++ b/src/parse_options.c @@ -23,211 +23,211 @@ IOR_param_t initialTestParams; * Check and correct all settings of each test in queue for correctness. */ -void CheckRunSettings(IOR_queue_t *tests) { - while (tests != NULL) { - /* If no write/read/check action requested, set both write and read */ - if (tests->testParameters.writeFile == FALSE - && tests->testParameters.readFile == FALSE - && tests->testParameters.checkWrite == FALSE - && tests->testParameters.checkRead == FALSE) { - tests->testParameters.readFile = TRUE; - tests->testParameters.writeFile = TRUE; +void CheckRunSettings(IOR_queue_t * tests) +{ + while (tests != NULL) { + /* If no write/read/check action requested, set both write and read */ + if (tests->testParameters.writeFile == FALSE + && tests->testParameters.readFile == FALSE + && tests->testParameters.checkWrite == FALSE + && tests->testParameters.checkRead == FALSE) { + tests->testParameters.readFile = TRUE; + tests->testParameters.writeFile = TRUE; + } + /* If numTasks set to 0, use all tasks */ + if (tests->testParameters.numTasks == 0) { + MPI_CHECK(MPI_Comm_size(MPI_COMM_WORLD, + &tests-> + testParameters.numTasks), + "MPI_Comm_size() error"); + } + tests = tests->nextTest; } - /* If numTasks set to 0, use all tasks */ - if (tests->testParameters.numTasks == 0) { - MPI_CHECK(MPI_Comm_size(MPI_COMM_WORLD, - &tests->testParameters.numTasks), - "MPI_Comm_size() error"); - } - tests = tests->nextTest; - } -} /* CheckRunSettings() */ - +} /* CheckRunSettings() */ /******************************************************************************/ /* * Set flags from commandline string/value pairs. */ -void DecodeDirective(char *line, IOR_param_t *test) +void DecodeDirective(char *line, IOR_param_t * test) { - char option[MAX_STR]; - char value[MAX_STR]; - int rc; + char option[MAX_STR]; + char value[MAX_STR]; + int rc; - rc = sscanf(line, " %[^=# \t\r\n] = %[^# \t\r\n] ", option, value); - if (rc != 2 && rank == 0) { - fprintf(stdout, "Syntax error in configuration options: %s\n", line); - MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); - } - if (strcasecmp(option, "api") == 0) { - strcpy(test->api, value); - } else if (strcasecmp(option, "testnum") == 0) { - test->TestNum = atoi(value); - } else if (strcasecmp(option, "debug") == 0) { - strcpy(test->debug, value); - } else if (strcasecmp(option, "platform") == 0) { - strcpy(test->platform, value); - } else if (strcasecmp(option, "testfile") == 0) { - strcpy(test->testFileName, value); - } else if (strcasecmp(option, "hintsfilename") == 0) { - strcpy(test->hintsFileName, value); - } else if (strcasecmp(option, "deadlineforstonewalling") == 0) { - test->deadlineForStonewalling = atoi(value); - } else if (strcasecmp(option, "maxtimeduration") == 0) { - test->maxTimeDuration = atoi(value); - } else if (strcasecmp(option, "outlierthreshold") == 0) { - test->outlierThreshold = atoi(value); - } else if (strcasecmp(option, "nodes") == 0) { - test->nodes = atoi(value); - } else if (strcasecmp(option, "repetitions") == 0) { - test->repetitions = atoi(value); - } else if (strcasecmp(option, "intertestdelay") == 0) { - test->interTestDelay = atoi(value); - } else if (strcasecmp(option, "readfile") == 0) { - test->readFile = atoi(value); - } else if (strcasecmp(option, "writefile") == 0) { - test->writeFile = atoi(value); - } else if (strcasecmp(option, "fileperproc") == 0) { - test->filePerProc = atoi(value); - } else if (strcasecmp(option, "reordertasksconstant") == 0) { - test->reorderTasks = atoi(value); - } else if (strcasecmp(option, "taskpernodeoffset") == 0) { - test->taskPerNodeOffset = atoi(value); - } else if (strcasecmp(option, "reordertasksrandom") == 0) { - test->reorderTasksRandom = atoi(value); - } else if (strcasecmp(option, "reordertasksrandomSeed") == 0) { - test->reorderTasksRandomSeed = atoi(value); - } else if (strcasecmp(option, "checkwrite") == 0) { - test->checkWrite = atoi(value); - } else if (strcasecmp(option, "checkread") == 0) { - test->checkRead = atoi(value); - } else if (strcasecmp(option, "keepfile") == 0) { - test->keepFile = atoi(value); - } else if (strcasecmp(option, "keepfilewitherror") == 0) { - test->keepFileWithError = atoi(value); - } else if (strcasecmp(option, "multiFile") == 0) { - test->multiFile = atoi(value); - } else if (strcasecmp(option, "quitonerror") == 0) { - test->quitOnError = atoi(value); - } else if (strcasecmp(option, "segmentcount") == 0) { - test->segmentCount = StringToBytes(value); - } else if (strcasecmp(option, "blocksize") == 0) { - test->blockSize = StringToBytes(value); - } else if (strcasecmp(option, "transfersize") == 0) { - test->transferSize = StringToBytes(value); - } else if (strcasecmp(option, "setalignment") == 0) { - test->setAlignment = StringToBytes(value); - } else if (strcasecmp(option, "singlexferattempt") == 0) { - test->singleXferAttempt = atoi(value); - } else if (strcasecmp(option, "individualdatasets") == 0) { - test->individualDataSets = atoi(value); - } else if (strcasecmp(option, "intraTestBarriers") == 0) { - test->intraTestBarriers = atoi(value); - } else if (strcasecmp(option, "nofill") == 0) { - test->noFill = atoi(value); - } else if (strcasecmp(option, "verbose") == 0) { - test->verbose = atoi(value); - } else if (strcasecmp(option, "settimestampsignature") == 0) { - test->setTimeStampSignature = atoi(value); - } else if (strcasecmp(option, "collective") == 0) { - test->collective = atoi(value); - } else if (strcasecmp(option, "preallocate") == 0) { - test->preallocate = atoi(value); - } else if (strcasecmp(option, "storefileoffset") == 0) { - test->storeFileOffset = atoi(value); - } else if (strcasecmp(option, "usefileview") == 0) { - test->useFileView = atoi(value); - } else if (strcasecmp(option, "usesharedfilepointer") == 0) { - test->useSharedFilePointer = atoi(value); - } else if (strcasecmp(option, "useo_direct") == 0) { - test->useO_DIRECT = atoi(value); - } else if (strcasecmp(option, "usestrideddatatype") == 0) { - test->useStridedDatatype = atoi(value); - } else if (strcasecmp(option, "showhints") == 0) { - test->showHints = atoi(value); - } else if (strcasecmp(option, "showhelp") == 0) { - test->showHelp = atoi(value); - } else if (strcasecmp(option, "uniqueDir") == 0) { - test->uniqueDir = atoi(value); - } else if (strcasecmp(option, "useexistingtestfile") == 0) { - test->useExistingTestFile = atoi(value); - } else if (strcasecmp(option, "fsyncperwrite") == 0) { - test->fsyncPerWrite = atoi(value); - } else if (strcasecmp(option, "fsync") == 0) { - test->fsync = atoi(value); - } else if (strcasecmp(option, "randomoffset") == 0) { - test->randomOffset = atoi(value); - } else if (strcasecmp(option, "lustrestripecount") == 0) { + rc = sscanf(line, " %[^=# \t\r\n] = %[^# \t\r\n] ", option, value); + if (rc != 2 && rank == 0) { + fprintf(stdout, "Syntax error in configuration options: %s\n", + line); + MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); + } + if (strcasecmp(option, "api") == 0) { + strcpy(test->api, value); + } else if (strcasecmp(option, "testnum") == 0) { + test->TestNum = atoi(value); + } else if (strcasecmp(option, "debug") == 0) { + strcpy(test->debug, value); + } else if (strcasecmp(option, "platform") == 0) { + strcpy(test->platform, value); + } else if (strcasecmp(option, "testfile") == 0) { + strcpy(test->testFileName, value); + } else if (strcasecmp(option, "hintsfilename") == 0) { + strcpy(test->hintsFileName, value); + } else if (strcasecmp(option, "deadlineforstonewalling") == 0) { + test->deadlineForStonewalling = atoi(value); + } else if (strcasecmp(option, "maxtimeduration") == 0) { + test->maxTimeDuration = atoi(value); + } else if (strcasecmp(option, "outlierthreshold") == 0) { + test->outlierThreshold = atoi(value); + } else if (strcasecmp(option, "nodes") == 0) { + test->nodes = atoi(value); + } else if (strcasecmp(option, "repetitions") == 0) { + test->repetitions = atoi(value); + } else if (strcasecmp(option, "intertestdelay") == 0) { + test->interTestDelay = atoi(value); + } else if (strcasecmp(option, "readfile") == 0) { + test->readFile = atoi(value); + } else if (strcasecmp(option, "writefile") == 0) { + test->writeFile = atoi(value); + } else if (strcasecmp(option, "fileperproc") == 0) { + test->filePerProc = atoi(value); + } else if (strcasecmp(option, "reordertasksconstant") == 0) { + test->reorderTasks = atoi(value); + } else if (strcasecmp(option, "taskpernodeoffset") == 0) { + test->taskPerNodeOffset = atoi(value); + } else if (strcasecmp(option, "reordertasksrandom") == 0) { + test->reorderTasksRandom = atoi(value); + } else if (strcasecmp(option, "reordertasksrandomSeed") == 0) { + test->reorderTasksRandomSeed = atoi(value); + } else if (strcasecmp(option, "checkwrite") == 0) { + test->checkWrite = atoi(value); + } else if (strcasecmp(option, "checkread") == 0) { + test->checkRead = atoi(value); + } else if (strcasecmp(option, "keepfile") == 0) { + test->keepFile = atoi(value); + } else if (strcasecmp(option, "keepfilewitherror") == 0) { + test->keepFileWithError = atoi(value); + } else if (strcasecmp(option, "multiFile") == 0) { + test->multiFile = atoi(value); + } else if (strcasecmp(option, "quitonerror") == 0) { + test->quitOnError = atoi(value); + } else if (strcasecmp(option, "segmentcount") == 0) { + test->segmentCount = StringToBytes(value); + } else if (strcasecmp(option, "blocksize") == 0) { + test->blockSize = StringToBytes(value); + } else if (strcasecmp(option, "transfersize") == 0) { + test->transferSize = StringToBytes(value); + } else if (strcasecmp(option, "setalignment") == 0) { + test->setAlignment = StringToBytes(value); + } else if (strcasecmp(option, "singlexferattempt") == 0) { + test->singleXferAttempt = atoi(value); + } else if (strcasecmp(option, "individualdatasets") == 0) { + test->individualDataSets = atoi(value); + } else if (strcasecmp(option, "intraTestBarriers") == 0) { + test->intraTestBarriers = atoi(value); + } else if (strcasecmp(option, "nofill") == 0) { + test->noFill = atoi(value); + } else if (strcasecmp(option, "verbose") == 0) { + test->verbose = atoi(value); + } else if (strcasecmp(option, "settimestampsignature") == 0) { + test->setTimeStampSignature = atoi(value); + } else if (strcasecmp(option, "collective") == 0) { + test->collective = atoi(value); + } else if (strcasecmp(option, "preallocate") == 0) { + test->preallocate = atoi(value); + } else if (strcasecmp(option, "storefileoffset") == 0) { + test->storeFileOffset = atoi(value); + } else if (strcasecmp(option, "usefileview") == 0) { + test->useFileView = atoi(value); + } else if (strcasecmp(option, "usesharedfilepointer") == 0) { + test->useSharedFilePointer = atoi(value); + } else if (strcasecmp(option, "useo_direct") == 0) { + test->useO_DIRECT = atoi(value); + } else if (strcasecmp(option, "usestrideddatatype") == 0) { + test->useStridedDatatype = atoi(value); + } else if (strcasecmp(option, "showhints") == 0) { + test->showHints = atoi(value); + } else if (strcasecmp(option, "showhelp") == 0) { + test->showHelp = atoi(value); + } else if (strcasecmp(option, "uniqueDir") == 0) { + test->uniqueDir = atoi(value); + } else if (strcasecmp(option, "useexistingtestfile") == 0) { + test->useExistingTestFile = atoi(value); + } else if (strcasecmp(option, "fsyncperwrite") == 0) { + test->fsyncPerWrite = atoi(value); + } else if (strcasecmp(option, "fsync") == 0) { + test->fsync = atoi(value); + } else if (strcasecmp(option, "randomoffset") == 0) { + test->randomOffset = atoi(value); + } else if (strcasecmp(option, "lustrestripecount") == 0) { #ifndef HAVE_LUSTRE_LUSTRE_USER_H - ERR("ior was not compiled with Lustre support"); + ERR("ior was not compiled with Lustre support"); #endif - test->lustre_stripe_count = atoi(value); - test->lustre_set_striping = 1; - } else if (strcasecmp(option, "lustrestripesize") == 0) { + test->lustre_stripe_count = atoi(value); + test->lustre_set_striping = 1; + } else if (strcasecmp(option, "lustrestripesize") == 0) { #ifndef HAVE_LUSTRE_LUSTRE_USER_H - ERR("ior was not compiled with Lustre support"); + ERR("ior was not compiled with Lustre support"); #endif - test->lustre_stripe_size = StringToBytes(value); - test->lustre_set_striping = 1; - } else if (strcasecmp(option, "lustrestartost") == 0) { + test->lustre_stripe_size = StringToBytes(value); + test->lustre_set_striping = 1; + } else if (strcasecmp(option, "lustrestartost") == 0) { #ifndef HAVE_LUSTRE_LUSTRE_USER_H - ERR("ior was not compiled with Lustre support"); + ERR("ior was not compiled with Lustre support"); #endif - test->lustre_start_ost = atoi(value); - test->lustre_set_striping = 1; - } else if (strcasecmp(option, "lustreignorelocks") == 0) { + test->lustre_start_ost = atoi(value); + test->lustre_set_striping = 1; + } else if (strcasecmp(option, "lustreignorelocks") == 0) { #ifndef HAVE_LUSTRE_LUSTRE_USER_H - ERR("ior was not compiled with Lustre support"); + ERR("ior was not compiled with Lustre support"); #endif - test->lustre_ignore_locks = atoi(value); + test->lustre_ignore_locks = atoi(value); #if USE_UNDOC_OPT - } else if (strcasecmp(option, "corruptFile") == 0) { - test->corruptFile = atoi(value); - } else if (strcasecmp(option, "fillTheFileSystem") == 0) { - test->fillTheFileSystem = atoi(value); - } else if (strcasecmp(option, "includeDeleteTime") == 0) { - test->includeDeleteTime = atoi(value); - } else if (strcasecmp(option, "multiReRead") == 0) { - test->multiReRead = atoi(value); - } else if (strcasecmp(option, "nfs_rootpath") == 0) { - strcpy(test->NFS_rootPath, value); - } else if (strcasecmp(option, "nfs_servername") == 0) { - strcpy(test->NFS_serverName, value); - } else if (strcasecmp(option, "nfs_servercount") == 0) { - test->NFS_serverCount = atoi(value); -#endif /* USE_UNDOC_OPT */ - } else if (strcasecmp(option, "numtasks") == 0) { - test->numTasks = atoi(value); - } else { - if (rank == 0) - fprintf(stdout, "Unrecognized parameter \"%s\"\n", option); - MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); - } -} /* DecodeDirective() */ - + } else if (strcasecmp(option, "corruptFile") == 0) { + test->corruptFile = atoi(value); + } else if (strcasecmp(option, "fillTheFileSystem") == 0) { + test->fillTheFileSystem = atoi(value); + } else if (strcasecmp(option, "includeDeleteTime") == 0) { + test->includeDeleteTime = atoi(value); + } else if (strcasecmp(option, "multiReRead") == 0) { + test->multiReRead = atoi(value); + } else if (strcasecmp(option, "nfs_rootpath") == 0) { + strcpy(test->NFS_rootPath, value); + } else if (strcasecmp(option, "nfs_servername") == 0) { + strcpy(test->NFS_serverName, value); + } else if (strcasecmp(option, "nfs_servercount") == 0) { + test->NFS_serverCount = atoi(value); +#endif /* USE_UNDOC_OPT */ + } else if (strcasecmp(option, "numtasks") == 0) { + test->numTasks = atoi(value); + } else { + if (rank == 0) + fprintf(stdout, "Unrecognized parameter \"%s\"\n", + option); + MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); + } +} /* DecodeDirective() */ /******************************************************************************/ /* * Parse a single line, which may contain multiple comma-seperated directives */ -void -ParseLine(char *line, IOR_param_t *test) +void ParseLine(char *line, IOR_param_t * test) { - char *start, *end; + char *start, *end; - start = line; - do { - end = strchr(start, ','); - if (end != NULL) - *end = '\0'; - DecodeDirective(start, test); - start = end + 1; - } while (end != NULL); - -} /* ParseLine() */ + start = line; + do { + end = strchr(start, ','); + if (end != NULL) + *end = '\0'; + DecodeDirective(start, test); + start = end + 1; + } while (end != NULL); +} /* ParseLine() */ /******************************************************************************/ /* @@ -235,29 +235,27 @@ ParseLine(char *line, IOR_param_t *test) * possibly whitespace before and after needle. Function is case insensitive. */ -int -contains_only(char *haystack, char *needle) +int contains_only(char *haystack, char *needle) { - char *ptr, *end; + char *ptr, *end; - end = haystack + strlen(haystack); - /* skip over leading shitspace */ - for (ptr = haystack; ptr < end; ptr++) { - if (!isspace(*ptr)) - break; - } - /* check for "needle" */ - if (strncasecmp(ptr, needle, strlen(needle)) != 0) - return 0; - /* make sure the rest of the line is only whitspace as well */ - for (ptr += strlen(needle); ptr < end; ptr++) { - if (!isspace(*ptr)) - return 0; - } - - return 1; -} /* contains_only() */ + end = haystack + strlen(haystack); + /* skip over leading shitspace */ + for (ptr = haystack; ptr < end; ptr++) { + if (!isspace(*ptr)) + break; + } + /* check for "needle" */ + if (strncasecmp(ptr, needle, strlen(needle)) != 0) + return 0; + /* make sure the rest of the line is only whitspace as well */ + for (ptr += strlen(needle); ptr < end; ptr++) { + if (!isspace(*ptr)) + return 0; + } + return 1; +} /* contains_only() */ /******************************************************************************/ /* @@ -265,169 +263,262 @@ contains_only(char *haystack, char *needle) * global parameters. */ -IOR_queue_t * -ReadConfigScript(char * scriptName) +IOR_queue_t *ReadConfigScript(char *scriptName) { - int test_num = 0; - int runflag = 0; - char linebuf[MAX_STR]; - char empty[MAX_STR]; - FILE *file; - IOR_queue_t *head = NULL; - IOR_queue_t *tail = NULL; - IOR_queue_t *newTest = NULL; + int test_num = 0; + int runflag = 0; + char linebuf[MAX_STR]; + char empty[MAX_STR]; + FILE *file; + IOR_queue_t *head = NULL; + IOR_queue_t *tail = NULL; + IOR_queue_t *newTest = NULL; - /* Initialize the first test */ - head = CreateNewTest(test_num++); - tail = head; + /* Initialize the first test */ + head = CreateNewTest(test_num++); + tail = head; - /* open the script */ - file = fopen(scriptName, "r"); - if (file == NULL) - ERR("fopen() failed"); + /* open the script */ + file = fopen(scriptName, "r"); + if (file == NULL) + ERR("fopen() failed"); - /* search for the "IOR START" line */ - while(fgets(linebuf, MAX_STR, file) != NULL) { - if (contains_only(linebuf, "ior start")) { - break; + /* search for the "IOR START" line */ + while (fgets(linebuf, MAX_STR, file) != NULL) { + if (contains_only(linebuf, "ior start")) { + break; + } } - } - /* Iterate over a block of IOR commands */ - while(fgets(linebuf, MAX_STR, file) != NULL) { - /* skip empty lines */ - if (sscanf(linebuf, "%s", empty) == -1) - continue; - /* skip lines containing only comments */ - if (sscanf(linebuf, " #%s", empty) == 1) - continue; - if (contains_only(linebuf, "ior stop")) { - break; - } else if (contains_only(linebuf, "run")) { - runflag = 1; - } else { - /* If this directive was preceded by a "run" line, then - create and initialize a new test structure */ - if (runflag) { - newTest = (IOR_queue_t *)malloc(sizeof(IOR_queue_t)); - if (newTest == NULL) - ERR("malloc() failed"); - newTest->testParameters = tail->testParameters; - newTest->testParameters.id = test_num++; - tail->nextTest = newTest; - tail = newTest; - tail->nextTest = NULL; - runflag = 0; - } - ParseLine(linebuf, &tail->testParameters); + /* Iterate over a block of IOR commands */ + while (fgets(linebuf, MAX_STR, file) != NULL) { + /* skip empty lines */ + if (sscanf(linebuf, "%s", empty) == -1) + continue; + /* skip lines containing only comments */ + if (sscanf(linebuf, " #%s", empty) == 1) + continue; + if (contains_only(linebuf, "ior stop")) { + break; + } else if (contains_only(linebuf, "run")) { + runflag = 1; + } else { + /* If this directive was preceded by a "run" line, then + create and initialize a new test structure */ + if (runflag) { + newTest = + (IOR_queue_t *) malloc(sizeof(IOR_queue_t)); + if (newTest == NULL) + ERR("malloc() failed"); + newTest->testParameters = tail->testParameters; + newTest->testParameters.id = test_num++; + tail->nextTest = newTest; + tail = newTest; + tail->nextTest = NULL; + runflag = 0; + } + ParseLine(linebuf, &tail->testParameters); + } } - } - /* close the script */ - if (fclose(file) != 0) - ERR("fclose() of script file failed"); + /* close the script */ + if (fclose(file) != 0) + ERR("fclose() of script file failed"); - return(head); -} /* ReadConfigScript() */ + return (head); +} /* ReadConfigScript() */ /******************************************************************************/ /* * Parse Commandline. */ -IOR_queue_t * -ParseCommandLine(int argc, char ** argv) +IOR_queue_t *ParseCommandLine(int argc, char **argv) { - static const char * opts - = "A:a:b:BcCQ:ZX:d:D:YeEf:FgG:hHi:j:J:IkKlmnN:o:O:pPqrRs:St:T:uU:vVwWxz"; - int c, i; - static IOR_queue_t *tests = NULL; + static const char *opts + = + "A:a:b:BcCQ:ZX:d:D:YeEf:FgG:hHi:j:J:IkKlmnN:o:O:pPqrRs:St:T:uU:vVwWxz"; + int c, i; + static IOR_queue_t *tests = NULL; - /* suppress getopt() error message when a character is unrecognized */ - opterr = 0; + /* suppress getopt() error message when a character is unrecognized */ + opterr = 0; - init_IOR_Param_t(&initialTestParams); - GetPlatformName(initialTestParams.platform); - initialTestParams.writeFile = initialTestParams.readFile = FALSE; - initialTestParams.checkWrite = initialTestParams.checkRead = FALSE; + init_IOR_Param_t(&initialTestParams); + GetPlatformName(initialTestParams.platform); + initialTestParams.writeFile = initialTestParams.readFile = FALSE; + initialTestParams.checkWrite = initialTestParams.checkRead = FALSE; - while ((c = getopt(argc, argv, opts)) != -1) { - switch (c) { - case 'A': initialTestParams.TestNum = atoi(optarg); break; - case 'a': strcpy(initialTestParams.api, optarg); break; - case 'b': initialTestParams.blockSize = - StringToBytes(optarg); break; - case 'B': initialTestParams.useO_DIRECT = TRUE; break; - case 'c': initialTestParams.collective = TRUE; break; - case 'C': initialTestParams.reorderTasks = TRUE; break; - case 'Q': initialTestParams.taskPerNodeOffset = - atoi(optarg); break; - case 'Z': initialTestParams.reorderTasksRandom = TRUE; break; - case 'X': initialTestParams.reorderTasksRandomSeed = - atoi(optarg); break; - case 'd': initialTestParams.interTestDelay = atoi(optarg); break; - case 'D': initialTestParams.deadlineForStonewalling = - atoi(optarg); break; - case 'Y': initialTestParams.fsyncPerWrite = TRUE; break; - case 'e': initialTestParams.fsync = TRUE; break; - case 'E': initialTestParams.useExistingTestFile = TRUE; break; - case 'f': tests = ReadConfigScript(optarg); break; - case 'F': initialTestParams.filePerProc = TRUE; break; - case 'g': initialTestParams.intraTestBarriers = TRUE; break; - case 'G': initialTestParams.setTimeStampSignature = - atoi(optarg); break; - case 'h': initialTestParams.showHelp = TRUE; break; - case 'H': initialTestParams.showHints = TRUE; break; - case 'i': initialTestParams.repetitions = atoi(optarg); break; - case 'I': initialTestParams.individualDataSets = TRUE; break; - case 'j': initialTestParams.outlierThreshold = - atoi(optarg); break; - case 'J': initialTestParams.setAlignment = - StringToBytes(optarg); break; - case 'k': initialTestParams.keepFile = TRUE; break; - case 'K': initialTestParams.keepFileWithError = TRUE; break; - case 'l': initialTestParams.storeFileOffset = TRUE; break; - case 'm': initialTestParams.multiFile = TRUE; break; - case 'n': initialTestParams.noFill = TRUE; break; - case 'N': initialTestParams.numTasks = atoi(optarg); break; - case 'o': strcpy(initialTestParams.testFileName, optarg); break; - case 'O': ParseLine(optarg, &initialTestParams); break; - case 'p': initialTestParams.preallocate = TRUE; break; - case 'P': initialTestParams.useSharedFilePointer = TRUE; break; - case 'q': initialTestParams.quitOnError = TRUE; break; - case 'r': initialTestParams.readFile = TRUE; break; - case 'R': initialTestParams.checkRead = TRUE; break; - case 's': initialTestParams.segmentCount = atoi(optarg); break; - case 'S': initialTestParams.useStridedDatatype = TRUE; break; - case 't': initialTestParams.transferSize = - StringToBytes(optarg); break; - case 'T': initialTestParams.maxTimeDuration = atoi(optarg);break; - case 'u': initialTestParams.uniqueDir = TRUE; break; - case 'U': strcpy(initialTestParams.hintsFileName, optarg); break; - case 'v': initialTestParams.verbose++; break; - case 'V': initialTestParams.useFileView = TRUE; break; - case 'w': initialTestParams.writeFile = TRUE; break; - case 'W': initialTestParams.checkWrite = TRUE; break; - case 'x': initialTestParams.singleXferAttempt = TRUE; break; - case 'z': initialTestParams.randomOffset = TRUE; break; - default: fprintf (stdout, "ParseCommandLine: unknown option `-%c'.\n", optopt); + while ((c = getopt(argc, argv, opts)) != -1) { + switch (c) { + case 'A': + initialTestParams.TestNum = atoi(optarg); + break; + case 'a': + strcpy(initialTestParams.api, optarg); + break; + case 'b': + initialTestParams.blockSize = StringToBytes(optarg); + break; + case 'B': + initialTestParams.useO_DIRECT = TRUE; + break; + case 'c': + initialTestParams.collective = TRUE; + break; + case 'C': + initialTestParams.reorderTasks = TRUE; + break; + case 'Q': + initialTestParams.taskPerNodeOffset = atoi(optarg); + break; + case 'Z': + initialTestParams.reorderTasksRandom = TRUE; + break; + case 'X': + initialTestParams.reorderTasksRandomSeed = atoi(optarg); + break; + case 'd': + initialTestParams.interTestDelay = atoi(optarg); + break; + case 'D': + initialTestParams.deadlineForStonewalling = + atoi(optarg); + break; + case 'Y': + initialTestParams.fsyncPerWrite = TRUE; + break; + case 'e': + initialTestParams.fsync = TRUE; + break; + case 'E': + initialTestParams.useExistingTestFile = TRUE; + break; + case 'f': + tests = ReadConfigScript(optarg); + break; + case 'F': + initialTestParams.filePerProc = TRUE; + break; + case 'g': + initialTestParams.intraTestBarriers = TRUE; + break; + case 'G': + initialTestParams.setTimeStampSignature = atoi(optarg); + break; + case 'h': + initialTestParams.showHelp = TRUE; + break; + case 'H': + initialTestParams.showHints = TRUE; + break; + case 'i': + initialTestParams.repetitions = atoi(optarg); + break; + case 'I': + initialTestParams.individualDataSets = TRUE; + break; + case 'j': + initialTestParams.outlierThreshold = atoi(optarg); + break; + case 'J': + initialTestParams.setAlignment = StringToBytes(optarg); + break; + case 'k': + initialTestParams.keepFile = TRUE; + break; + case 'K': + initialTestParams.keepFileWithError = TRUE; + break; + case 'l': + initialTestParams.storeFileOffset = TRUE; + break; + case 'm': + initialTestParams.multiFile = TRUE; + break; + case 'n': + initialTestParams.noFill = TRUE; + break; + case 'N': + initialTestParams.numTasks = atoi(optarg); + break; + case 'o': + strcpy(initialTestParams.testFileName, optarg); + break; + case 'O': + ParseLine(optarg, &initialTestParams); + break; + case 'p': + initialTestParams.preallocate = TRUE; + break; + case 'P': + initialTestParams.useSharedFilePointer = TRUE; + break; + case 'q': + initialTestParams.quitOnError = TRUE; + break; + case 'r': + initialTestParams.readFile = TRUE; + break; + case 'R': + initialTestParams.checkRead = TRUE; + break; + case 's': + initialTestParams.segmentCount = atoi(optarg); + break; + case 'S': + initialTestParams.useStridedDatatype = TRUE; + break; + case 't': + initialTestParams.transferSize = StringToBytes(optarg); + break; + case 'T': + initialTestParams.maxTimeDuration = atoi(optarg); + break; + case 'u': + initialTestParams.uniqueDir = TRUE; + break; + case 'U': + strcpy(initialTestParams.hintsFileName, optarg); + break; + case 'v': + initialTestParams.verbose++; + break; + case 'V': + initialTestParams.useFileView = TRUE; + break; + case 'w': + initialTestParams.writeFile = TRUE; + break; + case 'W': + initialTestParams.checkWrite = TRUE; + break; + case 'x': + initialTestParams.singleXferAttempt = TRUE; + break; + case 'z': + initialTestParams.randomOffset = TRUE; + break; + default: + fprintf(stdout, + "ParseCommandLine: unknown option `-%c'.\n", + optopt); + } } - } - for (i = optind; i < argc; i++) - fprintf (stdout, "non-option argument: %s\n", argv[i]); + for (i = optind; i < argc; i++) + fprintf(stdout, "non-option argument: %s\n", argv[i]); - /* If an IOR script was not used, initialize test queue to the defaults */ - if (tests == NULL) { - tests = (IOR_queue_t *) malloc (sizeof(IOR_queue_t)); - if (!tests) - ERR("malloc() failed"); - tests->testParameters = initialTestParams; - tests->nextTest = NULL; - } + /* If an IOR script was not used, initialize test queue to the defaults */ + if (tests == NULL) { + tests = (IOR_queue_t *) malloc(sizeof(IOR_queue_t)); + if (!tests) + ERR("malloc() failed"); + tests->testParameters = initialTestParams; + tests->nextTest = NULL; + } - CheckRunSettings(tests); - - return(tests); -} /* ParseCommandLine() */ + CheckRunSettings(tests); + return (tests); +} /* ParseCommandLine() */ diff --git a/src/utilities.c b/src/utilities.c index 85a3f4c..7e64407 100644 --- a/src/utilities.c +++ b/src/utilities.c @@ -9,35 +9,32 @@ * \******************************************************************************/ -#include "aiori.h" /* abstract IOR interface */ -#include "ior.h" /* IOR functions */ -#include /* sys_errlist */ -#include /* open() */ -#include /* pow() */ -#include /* only for fprintf() */ +#include "aiori.h" /* abstract IOR interface */ +#include "ior.h" /* IOR functions */ +#include /* sys_errlist */ +#include /* open() */ +#include /* pow() */ +#include /* only for fprintf() */ #include #include #include #include #include #ifndef _WIN32 -# include -# ifdef __sun /* SunOS does not support statfs(), instead uses statvfs() */ -# include -# else /* !__sun */ -# include -# endif /* __sun */ -# include /* gettimeofday() */ +#include +#ifdef __sun /* SunOS does not support statfs(), instead uses statvfs() */ +#include +#else /* !__sun */ +#include +#endif /* __sun */ +#include /* gettimeofday() */ #endif /************************** D E C L A R A T I O N S ***************************/ -extern int errno, /* error number */ - numTasks, /* MPI variables */ - rank, - rankOffset, - verbose; /* verbose output */ - +extern int errno, /* error number */ + numTasks, /* MPI variables */ + rank, rankOffset, verbose; /* verbose output */ /***************************** F U N C T I O N S ******************************/ @@ -46,207 +43,201 @@ extern int errno, /* error number */ * Returns string containing the current time. */ -char * -CurrentTimeString(void) +char *CurrentTimeString(void) { - static time_t currentTime; - char * currentTimePtr; - - if ((currentTime = time(NULL)) == -1) ERR("cannot get current time"); - if ((currentTimePtr = ctime(¤tTime)) == NULL) { - ERR("cannot read current time"); - } - /* ctime string ends in \n */ - return (currentTimePtr); -} /* CurrentTimeString() */ + static time_t currentTime; + char *currentTimePtr; + if ((currentTime = time(NULL)) == -1) + ERR("cannot get current time"); + if ((currentTimePtr = ctime(¤tTime)) == NULL) { + ERR("cannot read current time"); + } + /* ctime string ends in \n */ + return (currentTimePtr); +} /* CurrentTimeString() */ /******************************************************************************/ /* * Dump transfer buffer. */ -void -DumpBuffer(void *buffer, - size_t size) +void DumpBuffer(void *buffer, size_t size) { - size_t i, j; - unsigned long long *dumpBuf = (unsigned long long *)buffer; + size_t i, j; + unsigned long long *dumpBuf = (unsigned long long *)buffer; - for (i = 0; i < ((size/sizeof(IOR_size_t))/4); i++) { - for (j = 0; j < 4; j++) { - fprintf(stdout, "%016llx ", dumpBuf[4*i+j]); + for (i = 0; i < ((size / sizeof(IOR_size_t)) / 4); i++) { + for (j = 0; j < 4; j++) { + fprintf(stdout, "%016llx ", dumpBuf[4 * i + j]); + } + fprintf(stdout, "\n"); } - fprintf(stdout, "\n"); - } - return; -} /* DumpBuffer() */ - + return; +} /* DumpBuffer() */ /******************************************************************************/ /* * Sends all strings to root nodes and displays. */ -void -OutputToRoot(int numTasks, MPI_Comm comm, char * stringToDisplay) +void OutputToRoot(int numTasks, MPI_Comm comm, char *stringToDisplay) { - int i; - int swapNeeded = TRUE; - int pairsToSwap; - char ** stringArray; - char tmpString[MAX_STR]; - MPI_Status status; + int i; + int swapNeeded = TRUE; + int pairsToSwap; + char **stringArray; + char tmpString[MAX_STR]; + MPI_Status status; - /* malloc string array */ - stringArray = (char **)malloc(sizeof(char *) * numTasks); - if (stringArray == NULL) ERR("out of memory"); - for (i = 0; i < numTasks; i++) { - stringArray[i] = (char *)malloc(sizeof(char) * MAX_STR); - if (stringArray[i] == NULL) ERR("out of memory"); - } - - strcpy(stringArray[rank], stringToDisplay); - - if (rank == 0) { - /* MPI_receive all strings */ - for (i = 1; i < numTasks; i++) { - MPI_CHECK(MPI_Recv(stringArray[i], MAX_STR, MPI_CHAR, - MPI_ANY_SOURCE, MPI_ANY_TAG, comm, &status), - "MPI_Recv() error"); - } - } else { - /* MPI_send string to root node */ - MPI_CHECK(MPI_Send(stringArray[rank], MAX_STR, MPI_CHAR, 0, 0, comm), - "MPI_Send() error"); - } - MPI_CHECK(MPI_Barrier(comm), "barrier error"); - - /* sort strings using bubblesort */ - if (rank == 0) { - pairsToSwap = numTasks-1; - while (swapNeeded) { - swapNeeded = FALSE; - for (i = 0; i < pairsToSwap; i++) { - if (strcmp(stringArray[i], stringArray[i+1]) > 0) { - strcpy(tmpString, stringArray[i]); - strcpy(stringArray[i], stringArray[i+1]); - strcpy(stringArray[i+1], tmpString); - swapNeeded = TRUE; - } - } - pairsToSwap--; - } - } - - /* display strings */ - if (rank == 0) { + /* malloc string array */ + stringArray = (char **)malloc(sizeof(char *) * numTasks); + if (stringArray == NULL) + ERR("out of memory"); for (i = 0; i < numTasks; i++) { - fprintf(stdout, "%s\n", stringArray[i]); + stringArray[i] = (char *)malloc(sizeof(char) * MAX_STR); + if (stringArray[i] == NULL) + ERR("out of memory"); } - } - /* free strings */ - for (i = 0; i < numTasks; i++) { - free(stringArray[i]); - } - free(stringArray); -} /* OutputToRoot() */ + strcpy(stringArray[rank], stringToDisplay); + if (rank == 0) { + /* MPI_receive all strings */ + for (i = 1; i < numTasks; i++) { + MPI_CHECK(MPI_Recv(stringArray[i], MAX_STR, MPI_CHAR, + MPI_ANY_SOURCE, MPI_ANY_TAG, comm, + &status), "MPI_Recv() error"); + } + } else { + /* MPI_send string to root node */ + MPI_CHECK(MPI_Send + (stringArray[rank], MAX_STR, MPI_CHAR, 0, 0, comm), + "MPI_Send() error"); + } + MPI_CHECK(MPI_Barrier(comm), "barrier error"); + + /* sort strings using bubblesort */ + if (rank == 0) { + pairsToSwap = numTasks - 1; + while (swapNeeded) { + swapNeeded = FALSE; + for (i = 0; i < pairsToSwap; i++) { + if (strcmp(stringArray[i], stringArray[i + 1]) > + 0) { + strcpy(tmpString, stringArray[i]); + strcpy(stringArray[i], + stringArray[i + 1]); + strcpy(stringArray[i + 1], tmpString); + swapNeeded = TRUE; + } + } + pairsToSwap--; + } + } + + /* display strings */ + if (rank == 0) { + for (i = 0; i < numTasks; i++) { + fprintf(stdout, "%s\n", stringArray[i]); + } + } + + /* free strings */ + for (i = 0; i < numTasks; i++) { + free(stringArray[i]); + } + free(stringArray); +} /* OutputToRoot() */ /******************************************************************************/ /* * Set hints for MPIIO, HDF5, or NCMPI. */ -void -SetHints(MPI_Info * mpiHints, char * hintsFileName) +void SetHints(MPI_Info * mpiHints, char *hintsFileName) { - char hintString[MAX_STR], - settingVal[MAX_STR], - valueVal[MAX_STR]; - extern char ** environ; - int i; - FILE * fd; + char hintString[MAX_STR], settingVal[MAX_STR], valueVal[MAX_STR]; + extern char **environ; + int i; + FILE *fd; - /* - * This routine checks for hints from the environment and/or from the - * hints files. The hints are of the form: - * 'IOR_HINT____=', where is either 'MPI' - * or 'GPFS', is the full name of the hint to be set, and - * is the hint value. E.g., 'setenv IOR_HINT__MPI__IBM_largeblock_io true' - * or 'IOR_HINT__GPFS__hint=value' in the hints file. - */ - MPI_CHECK(MPI_Info_create(mpiHints), "cannot create info object"); + /* + * This routine checks for hints from the environment and/or from the + * hints files. The hints are of the form: + * 'IOR_HINT____=', where is either 'MPI' + * or 'GPFS', is the full name of the hint to be set, and + * is the hint value. E.g., 'setenv IOR_HINT__MPI__IBM_largeblock_io true' + * or 'IOR_HINT__GPFS__hint=value' in the hints file. + */ + MPI_CHECK(MPI_Info_create(mpiHints), "cannot create info object"); - /* get hints from environment */ - for (i = 0; environ[i] != NULL; i++) { - /* if this is an IOR_HINT, pass the hint to the info object */ - if (strncmp(environ[i], "IOR_HINT", strlen("IOR_HINT")) == 0) { - strcpy(hintString, environ[i]); - ExtractHint(settingVal, valueVal, hintString); - MPI_CHECK(MPI_Info_set(*mpiHints, settingVal, valueVal), - "cannot set info object"); - } - } - - /* get hints from hints file */ - if (strcmp(hintsFileName, "") != 0) { - - /* open the hint file */ - fd = fopen(hintsFileName, "r"); - if (fd == NULL) { - WARN("cannot open hints file"); - } else { - /* iterate over hints file */ - while(fgets(hintString, MAX_STR, fd) != NULL) { - if (strncmp(hintString, "IOR_HINT", strlen("IOR_HINT")) == 0) { - ExtractHint(settingVal, valueVal, hintString); - MPI_CHECK(MPI_Info_set(*mpiHints, settingVal, valueVal), - "cannot set info object"); + /* get hints from environment */ + for (i = 0; environ[i] != NULL; i++) { + /* if this is an IOR_HINT, pass the hint to the info object */ + if (strncmp(environ[i], "IOR_HINT", strlen("IOR_HINT")) == 0) { + strcpy(hintString, environ[i]); + ExtractHint(settingVal, valueVal, hintString); + MPI_CHECK(MPI_Info_set(*mpiHints, settingVal, valueVal), + "cannot set info object"); } - } - /* close the hints files */ - if (fclose(fd) != 0) ERR("cannot close hints file"); } - } -} /* SetHints() */ + /* get hints from hints file */ + if (strcmp(hintsFileName, "") != 0) { + + /* open the hint file */ + fd = fopen(hintsFileName, "r"); + if (fd == NULL) { + WARN("cannot open hints file"); + } else { + /* iterate over hints file */ + while (fgets(hintString, MAX_STR, fd) != NULL) { + if (strncmp + (hintString, "IOR_HINT", + strlen("IOR_HINT")) == 0) { + ExtractHint(settingVal, valueVal, + hintString); + MPI_CHECK(MPI_Info_set + (*mpiHints, settingVal, + valueVal), + "cannot set info object"); + } + } + /* close the hints files */ + if (fclose(fd) != 0) + ERR("cannot close hints file"); + } + } +} /* SetHints() */ /******************************************************************************/ /* * Extract key/value pair from hint string. */ -void -ExtractHint(char * settingVal, - char * valueVal, - char * hintString) +void ExtractHint(char *settingVal, char *valueVal, char *hintString) { - char * settingPtr, - * valuePtr, - * tmpPtr1, - * tmpPtr2; + char *settingPtr, *valuePtr, *tmpPtr1, *tmpPtr2; - settingPtr = (char *)strtok(hintString, "="); - valuePtr = (char *)strtok(NULL, " \t\r\n"); - tmpPtr1 = settingPtr; - tmpPtr2 = (char *)strstr(settingPtr, "IOR_HINT__MPI__"); - if (tmpPtr1 == tmpPtr2) { - settingPtr += strlen("IOR_HINT__MPI__"); - - } else { - tmpPtr2 = (char *)strstr(settingPtr, "IOR_HINT__GPFS__"); + settingPtr = (char *)strtok(hintString, "="); + valuePtr = (char *)strtok(NULL, " \t\r\n"); + tmpPtr1 = settingPtr; + tmpPtr2 = (char *)strstr(settingPtr, "IOR_HINT__MPI__"); if (tmpPtr1 == tmpPtr2) { - settingPtr += strlen("IOR_HINT__GPFS__"); - fprintf(stdout, - "WARNING: Unable to set GPFS hints (not implemented.)\n"); - } - } - strcpy(settingVal, settingPtr); - strcpy(valueVal, valuePtr); -} /* ExtractHint() */ + settingPtr += strlen("IOR_HINT__MPI__"); + } else { + tmpPtr2 = (char *)strstr(settingPtr, "IOR_HINT__GPFS__"); + if (tmpPtr1 == tmpPtr2) { + settingPtr += strlen("IOR_HINT__GPFS__"); + fprintf(stdout, + "WARNING: Unable to set GPFS hints (not implemented.)\n"); + } + } + strcpy(settingVal, settingPtr); + strcpy(valueVal, valuePtr); +} /* ExtractHint() */ /******************************************************************************/ /* @@ -255,261 +246,252 @@ ExtractHint(char * settingVal, void ShowHints(MPI_Info * mpiHints) { - char key[MPI_MAX_INFO_VAL], - value[MPI_MAX_INFO_VAL]; - int flag, - i, - nkeys; + char key[MPI_MAX_INFO_VAL], value[MPI_MAX_INFO_VAL]; + int flag, i, nkeys; - MPI_CHECK(MPI_Info_get_nkeys(*mpiHints, &nkeys), - "cannot get info object keys"); - - for (i = 0; i < nkeys; i++) { - MPI_CHECK(MPI_Info_get_nthkey(*mpiHints, i, key), - "cannot get info object key"); - MPI_CHECK(MPI_Info_get(*mpiHints, key, MPI_MAX_INFO_VAL-1, - value, &flag), - "cannot get info object value"); - fprintf(stdout,"\t%s = %s\n", key, value); - } -} /* ShowHints() */ + MPI_CHECK(MPI_Info_get_nkeys(*mpiHints, &nkeys), + "cannot get info object keys"); + for (i = 0; i < nkeys; i++) { + MPI_CHECK(MPI_Info_get_nthkey(*mpiHints, i, key), + "cannot get info object key"); + MPI_CHECK(MPI_Info_get(*mpiHints, key, MPI_MAX_INFO_VAL - 1, + value, &flag), + "cannot get info object value"); + fprintf(stdout, "\t%s = %s\n", key, value); + } +} /* ShowHints() */ /******************************************************************************/ /* * Takes a string of the form 64, 8m, 128k, 4g, etc. and converts to bytes. */ -IOR_offset_t -StringToBytes(char * size_str) +IOR_offset_t StringToBytes(char *size_str) { - IOR_offset_t size = 0; - char range; - int rc; + IOR_offset_t size = 0; + char range; + int rc; - rc = sscanf(size_str, "%lld%c", &size, &range); - if (rc == 2) { - switch ((int)range) { - case 'k': case 'K': size <<= 10; break; - case 'm': case 'M': size <<= 20; break; - case 'g': case 'G': size <<= 30; break; + rc = sscanf(size_str, "%lld%c", &size, &range); + if (rc == 2) { + switch ((int)range) { + case 'k': + case 'K': + size <<= 10; + break; + case 'm': + case 'M': + size <<= 20; + break; + case 'g': + case 'G': + size <<= 30; + break; + } + } else if (rc == 0) { + size = -1; } - } else if (rc == 0) { - size = -1; - } - return(size); -} /* StringToBytes() */ - + return (size); +} /* StringToBytes() */ /******************************************************************************/ /* * Displays size of file system and percent of data blocks and inodes used. */ -void -ShowFileSystemSize(char *fileSystem) +void ShowFileSystemSize(char *fileSystem) { -#ifndef _WIN32 /* FIXME */ - int error; - char realPath[PATH_MAX]; - char *fileSystemUnitStr = "GiB"; - long long int fileSystemUnitVal = 1024 * 1024 * 1024; - long long int inodeUnitVal = 1024 * 1024; - long long int totalFileSystemSize, - freeFileSystemSize, - totalInodes, - freeInodes; - double totalFileSystemSizeHR, - usedFileSystemPercentage, - usedInodePercentage; -#ifdef __sun /* SunOS does not support statfs(), instead uses statvfs() */ - struct statvfs statusBuffer; -#else /* !__sun */ - struct statfs statusBuffer; -#endif /* __sun */ +#ifndef _WIN32 /* FIXME */ + int error; + char realPath[PATH_MAX]; + char *fileSystemUnitStr = "GiB"; + long long int fileSystemUnitVal = 1024 * 1024 * 1024; + long long int inodeUnitVal = 1024 * 1024; + long long int totalFileSystemSize, + freeFileSystemSize, totalInodes, freeInodes; + double totalFileSystemSizeHR, + usedFileSystemPercentage, usedInodePercentage; +#ifdef __sun /* SunOS does not support statfs(), instead uses statvfs() */ + struct statvfs statusBuffer; +#else /* !__sun */ + struct statfs statusBuffer; +#endif /* __sun */ #ifdef __sun - if (statvfs(fileSystem, &statusBuffer) != 0) { - ERR("unable to statvfs() file system"); - } -#else /* !__sun */ - if (statfs(fileSystem, &statusBuffer) != 0) { - ERR("unable to statfs() file system"); - } -#endif /* __sun */ + if (statvfs(fileSystem, &statusBuffer) != 0) { + ERR("unable to statvfs() file system"); + } +#else /* !__sun */ + if (statfs(fileSystem, &statusBuffer) != 0) { + ERR("unable to statfs() file system"); + } +#endif /* __sun */ - /* data blocks */ + /* data blocks */ #ifdef __sun - totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_frsize; - freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_frsize; -#else /* !__sun */ - totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_bsize; - freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_bsize; -#endif /* __sun */ + totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_frsize; + freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_frsize; +#else /* !__sun */ + totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_bsize; + freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_bsize; +#endif /* __sun */ - usedFileSystemPercentage = (1 - ((double)freeFileSystemSize - / (double)totalFileSystemSize)) * 100; - totalFileSystemSizeHR = (double)totalFileSystemSize - / (double)fileSystemUnitVal; - if (totalFileSystemSizeHR > 1024) { - totalFileSystemSizeHR = totalFileSystemSizeHR / 1024; - fileSystemUnitStr = "TiB"; - } + usedFileSystemPercentage = (1 - ((double)freeFileSystemSize + / (double)totalFileSystemSize)) * 100; + totalFileSystemSizeHR = + (double)totalFileSystemSize / (double)fileSystemUnitVal; + if (totalFileSystemSizeHR > 1024) { + totalFileSystemSizeHR = totalFileSystemSizeHR / 1024; + fileSystemUnitStr = "TiB"; + } - /* inodes */ - totalInodes = statusBuffer.f_files; - freeInodes = statusBuffer.f_ffree; - usedInodePercentage = (1 - ((double)freeInodes/(double)totalInodes)) * 100; + /* inodes */ + totalInodes = statusBuffer.f_files; + freeInodes = statusBuffer.f_ffree; + usedInodePercentage = + (1 - ((double)freeInodes / (double)totalInodes)) * 100; - /* show results */ - if (realpath(fileSystem, realPath) == NULL) { - ERR("unable to use realpath()"); - } - fprintf(stdout, "Path: %s\n", realPath); - fprintf(stdout, "FS: %.1f %s Used FS: %2.1f%% ", totalFileSystemSizeHR, - fileSystemUnitStr, usedFileSystemPercentage); - fprintf(stdout, "Inodes: %.1f Mi Used Inodes: %2.1f%%\n", - (double)totalInodes / (double)inodeUnitVal, usedInodePercentage); - fflush(stdout); -#endif /* _WIN32 */ - - return; -} /* ShowFileSystemSize() */ + /* show results */ + if (realpath(fileSystem, realPath) == NULL) { + ERR("unable to use realpath()"); + } + fprintf(stdout, "Path: %s\n", realPath); + fprintf(stdout, "FS: %.1f %s Used FS: %2.1f%% ", + totalFileSystemSizeHR, fileSystemUnitStr, + usedFileSystemPercentage); + fprintf(stdout, "Inodes: %.1f Mi Used Inodes: %2.1f%%\n", + (double)totalInodes / (double)inodeUnitVal, + usedInodePercentage); + fflush(stdout); +#endif /* _WIN32 */ + return; +} /* ShowFileSystemSize() */ /******************************************************************************/ /* * Return match of regular expression -- 0 is failure, 1 is success. */ -int -Regex(char *string, char *pattern) +int Regex(char *string, char *pattern) { - int retValue = 0; -#ifndef _WIN32 /* Okay to always not match */ - regex_t regEx; - regmatch_t regMatch; + int retValue = 0; +#ifndef _WIN32 /* Okay to always not match */ + regex_t regEx; + regmatch_t regMatch; - regcomp(®Ex, pattern, REG_EXTENDED); - if (regexec(®Ex, string, 1, ®Match, 0) == 0) { - retValue = 1; - } - regfree(®Ex); + regcomp(®Ex, pattern, REG_EXTENDED); + if (regexec(®Ex, string, 1, ®Match, 0) == 0) { + retValue = 1; + } + regfree(®Ex); #endif - return(retValue); -} /* Regex() */ + return (retValue); +} /* Regex() */ - -#if USE_UNDOC_OPT /* corruptFile */ +#if USE_UNDOC_OPT /* corruptFile */ /******************************************************************************/ /* * Corrupt file to testing data checking options. */ - -void CorruptFile(char *testFileName, - IOR_param_t *test, - int rep, - int access) + +void CorruptFile(char *testFileName, IOR_param_t * test, int rep, int access) { - IOR_offset_t tmpOff, range, eof; - char fileName[MAX_STR]; + IOR_offset_t tmpOff, range, eof; + char fileName[MAX_STR]; - /* determine file name */ - strcpy(fileName, testFileName); - if (access == READCHECK && test->filePerProc) { - strcpy(fileName, test->testFileName_fppReadCheck); - } + /* determine file name */ + strcpy(fileName, testFileName); + if (access == READCHECK && test->filePerProc) { + strcpy(fileName, test->testFileName_fppReadCheck); + } - /* determine offset to modify */ - SeedRandGen(test->testComm); - eof = test->aggFileSizeFromCalc[rep] - / (test->filePerProc ? test->numTasks : 1); - if (access == WRITECHECK) { - range = eof - test->offset; - } else { /* READCHECK */ - range = test->transferSize; - } - tmpOff = (IOR_offset_t)((rand()/(float)RAND_MAX) * range) + test->offset; + /* determine offset to modify */ + SeedRandGen(test->testComm); + eof = test->aggFileSizeFromCalc[rep] + / (test->filePerProc ? test->numTasks : 1); + if (access == WRITECHECK) { + range = eof - test->offset; + } else { /* READCHECK */ + range = test->transferSize; + } + tmpOff = + (IOR_offset_t) ((rand() / (float)RAND_MAX) * range) + test->offset; - if (tmpOff >= eof) tmpOff = tmpOff / 2; + if (tmpOff >= eof) + tmpOff = tmpOff / 2; - /* corrupt at with */ - if (rank == 0 || test->filePerProc) { - ModifyByteInFile(fileName, tmpOff, 121); - } - - return; -} /* CorruptFile() */ + /* corrupt at with */ + if (rank == 0 || test->filePerProc) { + ModifyByteInFile(fileName, tmpOff, 121); + } + return; +} /* CorruptFile() */ /******************************************************************************/ /* * Modify byte in file - used to testing write/read data checking. */ -void -ModifyByteInFile(char * fileName, - IOR_offset_t offset, - int byteValue) +void ModifyByteInFile(char *fileName, IOR_offset_t offset, int byteValue) { - int fd; - int rc; - char old; - char new; + int fd; + int rc; + char old; + char new; - new = (char)byteValue; + new = (char)byteValue; - /* open file, show old value, update to new value */ - fd = open(fileName, O_RDWR); - rc = lseek(fd, offset, SEEK_SET); - if (rc == -1) - goto out; - rc = read(fd, &old, 1); - if (rc == -1) - goto out; - rc = lseek(fd, offset, SEEK_SET); - if (rc == -1) - goto out; - rc = write(fd, &new, 1); - if (rc == -1) - goto out; - fprintf(stdout, - "** DEBUG: offset %lld in %s changed from %d to %d **\n", offset, - fileName, (unsigned char)old, (unsigned char)new); - -out: - close(fd); - return; -} /* ModifyByteInFile() */ -#endif /* USE_UNDOC_OPT - corruptFile */ + /* open file, show old value, update to new value */ + fd = open(fileName, O_RDWR); + rc = lseek(fd, offset, SEEK_SET); + if (rc == -1) + goto out; + rc = read(fd, &old, 1); + if (rc == -1) + goto out; + rc = lseek(fd, offset, SEEK_SET); + if (rc == -1) + goto out; + rc = write(fd, &new, 1); + if (rc == -1) + goto out; + fprintf(stdout, + "** DEBUG: offset %lld in %s changed from %d to %d **\n", + offset, fileName, (unsigned char)old, (unsigned char)new); + out: + close(fd); + return; +} /* ModifyByteInFile() */ +#endif /* USE_UNDOC_OPT - corruptFile */ /******************************************************************************/ /* * Seed random generator. */ -void -SeedRandGen(MPI_Comm testComm) +void SeedRandGen(MPI_Comm testComm) { - unsigned int randomSeed; + unsigned int randomSeed; - if (rank == 0) { + if (rank == 0) { #ifdef _WIN32 - rand_s(&randomSeed); + rand_s(&randomSeed); #else - struct timeval randGenTimer; - gettimeofday(&randGenTimer, (struct timezone *)NULL); - randomSeed = randGenTimer.tv_usec; + struct timeval randGenTimer; + gettimeofday(&randGenTimer, (struct timezone *)NULL); + randomSeed = randGenTimer.tv_usec; #endif - } - MPI_CHECK(MPI_Bcast(&randomSeed, 1, MPI_INT, 0, - testComm), "cannot broadcast random seed value"); - srandom(randomSeed); - -} /* SeedRandGen() */ + } + MPI_CHECK(MPI_Bcast(&randomSeed, 1, MPI_INT, 0, + testComm), "cannot broadcast random seed value"); + srandom(randomSeed); +} /* SeedRandGen() */ /******************************************************************************/ /* @@ -519,18 +501,19 @@ SeedRandGen(MPI_Comm testComm) int uname(struct utsname *name) { - DWORD nodeNameSize = sizeof(name->nodename) - 1; + DWORD nodeNameSize = sizeof(name->nodename) - 1; - memset(name, 0, sizeof(struct utsname)); - if (!GetComputerNameEx(ComputerNameDnsFullyQualified, name->nodename, &nodeNameSize)) - ERR("GetComputerNameEx failed"); + memset(name, 0, sizeof(struct utsname)); + if (!GetComputerNameEx + (ComputerNameDnsFullyQualified, name->nodename, &nodeNameSize)) + ERR("GetComputerNameEx failed"); - strncpy(name->sysname, "Windows", sizeof(name->sysname)-1); - /* FIXME - these should be easy to fetch */ - strncpy(name->release, "-", sizeof(name->release)-1); - strncpy(name->version, "-", sizeof(name->version)-1); - strncpy(name->machine, "-", sizeof(name->machine)-1); - return 0; + strncpy(name->sysname, "Windows", sizeof(name->sysname) - 1); + /* FIXME - these should be easy to fetch */ + strncpy(name->release, "-", sizeof(name->release) - 1); + strncpy(name->version, "-", sizeof(name->version) - 1); + strncpy(name->machine, "-", sizeof(name->machine) - 1); + return 0; } -#endif /* _WIN32 */ +#endif /* _WIN32 */