Change the the One True Formatting (Linux style)

Ran the main ior code through "indent -linux --no-tabs".
master
Christopher J. Morrone 2011-11-11 14:22:17 -08:00
parent 3ff7a4a4ae
commit 240e5ce93f
7 changed files with 4276 additions and 4149 deletions

View File

@ -9,14 +9,14 @@
* *
\******************************************************************************/ \******************************************************************************/
#include "aiori.h" /* abstract IOR interface */ #include "aiori.h" /* abstract IOR interface */
#include <errno.h> /* sys_errlist */ #include <errno.h> /* sys_errlist */
#include <stdio.h> /* only for fprintf() */ #include <stdio.h> /* only for fprintf() */
#include <stdlib.h> #include <stdlib.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <hdf5.h> #include <hdf5.h>
#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); \ exit(-1); \
} \ } \
} while(0) } 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 { \ #define HDF5_CHECK(HDF5_RETURN, MSG) do { \
char resultString[1024]; \ char resultString[1024]; \
\ \
@ -66,258 +66,264 @@
exit(-1); \ exit(-1); \
} \ } \
} while(0) } 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 *****************************/ /**************************** P R O T O T Y P E S *****************************/
IOR_offset_t SeekOffset_HDF5 (void *, IOR_offset_t, IOR_param_t *); IOR_offset_t SeekOffset_HDF5(void *, IOR_offset_t, IOR_param_t *);
void SetHints (MPI_Info *, char *); void SetHints(MPI_Info *, char *);
void SetupDataSet_HDF5(void *, IOR_param_t *); void SetupDataSet_HDF5(void *, IOR_param_t *);
void ShowHints (MPI_Info *); void ShowHints(MPI_Info *);
void * IOR_Create_HDF5 (char *, IOR_param_t *); void *IOR_Create_HDF5(char *, IOR_param_t *);
void * IOR_Open_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_Xfer_HDF5(int, void *, IOR_size_t *,
IOR_offset_t, IOR_param_t *); IOR_offset_t, IOR_param_t *);
void IOR_Close_HDF5 (void *, IOR_param_t *); void IOR_Close_HDF5(void *, IOR_param_t *);
void IOR_Delete_HDF5 (char *, IOR_param_t *); void IOR_Delete_HDF5(char *, IOR_param_t *);
void IOR_SetVersion_HDF5 (IOR_param_t *); void IOR_SetVersion_HDF5(IOR_param_t *);
void IOR_Fsync_HDF5 (void *, IOR_param_t *); void IOR_Fsync_HDF5(void *, IOR_param_t *);
IOR_offset_t IOR_GetFileSize_HDF5 (IOR_param_t *, MPI_Comm, char *); IOR_offset_t IOR_GetFileSize_HDF5(IOR_param_t *, MPI_Comm, char *);
/************************** D E C L A R A T I O N S ***************************/ /************************** D E C L A R A T I O N S ***************************/
ior_aiori_t hdf5_aiori = { ior_aiori_t hdf5_aiori = {
"HDF5", "HDF5",
IOR_Create_HDF5, IOR_Create_HDF5,
IOR_Open_HDF5, IOR_Open_HDF5,
IOR_Xfer_HDF5, IOR_Xfer_HDF5,
IOR_Close_HDF5, IOR_Close_HDF5,
IOR_Delete_HDF5, IOR_Delete_HDF5,
IOR_SetVersion_HDF5, IOR_SetVersion_HDF5,
IOR_Fsync_HDF5, IOR_Fsync_HDF5,
IOR_GetFileSize_HDF5 IOR_GetFileSize_HDF5
}; };
extern int errno, /* error number */ extern int errno, /* error number */
rank, rank, rankOffset, verbose; /* verbose output */
rankOffset,
verbose; /* verbose output */
extern MPI_Comm testComm; extern MPI_Comm testComm;
static hid_t xferPropList; /* xfer property list */ static hid_t xferPropList; /* xfer property list */
hid_t dataSet; /* data set id */ hid_t dataSet; /* data set id */
hid_t dataSpace; /* data space id */ hid_t dataSpace; /* data space id */
hid_t fileDataSpace; /* file data space id */ hid_t fileDataSpace; /* file data space id */
hid_t memDataSpace; /* memory data space id */ hid_t memDataSpace; /* memory data space id */
int newlyOpenedFile; /* newly opened file */ int newlyOpenedFile; /* newly opened file */
/***************************** F U N C T I O N S ******************************/ /***************************** F U N C T I O N S ******************************/
/******************************************************************************/ /******************************************************************************/
/* /*
* Create and open a file through the HDF5 interface. * Create and open a file through the HDF5 interface.
*/ */
void * void *IOR_Create_HDF5(char *testFileName, IOR_param_t * param)
IOR_Create_HDF5(char * testFileName,
IOR_param_t * param)
{ {
return IOR_Open_HDF5(testFileName, param); return IOR_Open_HDF5(testFileName, param);
} /* IOR_Create_HDF5() */ } /* IOR_Create_HDF5() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Open a file through the HDF5 interface. * Open a file through the HDF5 interface.
*/ */
void * void *IOR_Open_HDF5(char *testFileName, IOR_param_t * param)
IOR_Open_HDF5(char * testFileName,
IOR_param_t * param)
{ {
hid_t accessPropList, hid_t accessPropList, createPropList;
createPropList; hsize_t memStart[NUM_DIMS],
hsize_t memStart[NUM_DIMS], dataSetDims[NUM_DIMS],
dataSetDims[NUM_DIMS], memStride[NUM_DIMS],
memStride[NUM_DIMS], memCount[NUM_DIMS], memBlock[NUM_DIMS], memDataSpaceDims[NUM_DIMS];
memCount[NUM_DIMS], int tasksPerDataSet;
memBlock[NUM_DIMS], unsigned fd_mode = (unsigned)0;
memDataSpaceDims[NUM_DIMS]; hid_t *fd;
int tasksPerDataSet; MPI_Comm comm;
unsigned fd_mode = (unsigned)0; MPI_Info mpiHints = MPI_INFO_NULL;
hid_t *fd;
MPI_Comm comm;
MPI_Info mpiHints = MPI_INFO_NULL;
fd = (hid_t *)malloc(sizeof(hid_t)); fd = (hid_t *) malloc(sizeof(hid_t));
if (fd == NULL) if (fd == NULL)
ERR("malloc() failed"); ERR("malloc() failed");
/* /*
* HDF5 uses different flags than those for POSIX/MPIIO * HDF5 uses different flags than those for POSIX/MPIIO
*/ */
if (param->open == WRITE) { /* WRITE flags */ if (param->open == WRITE) { /* WRITE flags */
param->openFlags = IOR_TRUNC; param->openFlags = IOR_TRUNC;
} else { /* READ or check WRITE/READ flags */ } else { /* READ or check WRITE/READ flags */
param->openFlags = IOR_RDONLY; 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");
} }
} else {
MPI_Info mpiHintsCheck = MPI_INFO_NULL; /* set IOR file flags to HDF5 flags */
hid_t apl; /* -- file open flags -- */
apl = H5Fget_access_plist(*fd); if (param->openFlags & IOR_RDONLY) {
HDF5_CHECK(H5Pget_fapl_mpio(apl, &comm, &mpiHintsCheck), fd_mode |= H5F_ACC_RDONLY;
"cannot get info object through HDF5"); }
if (rank == 0) { if (param->openFlags & IOR_WRONLY) {
fprintf(stdout, fprintf(stdout, "File write only not implemented in HDF5\n");
"\nhints returned from opened file (HDF5) {\n"); }
ShowHints(&mpiHintsCheck); if (param->openFlags & IOR_RDWR) {
fprintf(stdout, "}\n"); fd_mode |= H5F_ACC_RDWR;
if (1 == 1) { /* request the MPIIO file handle and its hints */ }
MPI_File * fd_mpiio; if (param->openFlags & IOR_APPEND) {
HDF5_CHECK(H5Fget_vfd_handle(*fd, apl, (void **)&fd_mpiio), fprintf(stdout, "File append not implemented in HDF5\n");
"cannot get MPIIO file handle"); }
MPI_CHECK(MPI_File_get_info(*fd_mpiio, &mpiHintsCheck), if (param->openFlags & IOR_CREAT) {
"cannot get info object through MPIIO"); fd_mode |= H5F_ACC_CREAT;
fprintf(stdout, }
"\nhints returned from opened file (MPIIO) {\n"); if (param->openFlags & IOR_EXCL) {
ShowHints(&mpiHintsCheck); fd_mode |= H5F_ACC_EXCL;
fprintf(stdout, "}\n"); }
} 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 /* set up file creation property list */
needed for reopening and checking the file */ createPropList = H5Pcreate(H5P_FILE_CREATE);
newlyOpenedFile = TRUE; 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"); /* set up file access property list */
HDF5_CHECK(H5Pclose(accessPropList), "cannot close 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); * someday HDF5 implementation will allow subsets of MPI_COMM_WORLD
HDF5_CHECK(xferPropList, "cannot create transfer property list"); */
/* store MPI communicator info for the file access property list */
/* set data transfer mode */ if (param->filePerProc) {
if (param->collective) { comm = MPI_COMM_SELF;
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 { } else {
/* share single data set across all tasks in segment */ comm = testComm;
tasksPerDataSet = param->numTasks;
} }
}
dataSetDims[0] = (hsize_t)((param->blockSize / sizeof(IOR_size_t))
* tasksPerDataSet);
/* create a simple data space containing information on size SetHints(&mpiHints, param->hintsFileName);
and shape of data set, and open it for access */ /*
dataSpace = H5Screate_simple(NUM_DIMS, dataSetDims, NULL); * note that with MP_HINTS_FILTERED=no, all key/value pairs will
HDF5_CHECK(dataSpace, "cannot create simple data space"); * be in the info object. The info object that is attached to
* the file during MPI_File_open() will only contain those pairs
return(fd); * deemed valid by the implementation.
} /* IOR_Open_HDF5() */ */
/* 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_offset_t
IOR_Xfer_HDF5(int access, IOR_Xfer_HDF5(int access,
void * fd, void *fd,
IOR_size_t * buffer, IOR_size_t * buffer, IOR_offset_t length, IOR_param_t * param)
IOR_offset_t length,
IOR_param_t * param)
{ {
static int firstReadCheck = FALSE, static int firstReadCheck = FALSE, startNewDataSet;
startNewDataSet; IOR_offset_t segmentPosition, segmentSize;
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 * this toggle is for the read check operation, which passes through
* second pass through during a read check * 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) {
if (access == READCHECK && firstReadCheck != TRUE) { if (firstReadCheck == TRUE) {
startNewDataSet = FALSE; firstReadCheck = FALSE;
} else {
firstReadCheck = TRUE;
}
} }
}
/* create new data set */ /* determine by offset if need to start new data set */
if (startNewDataSet == TRUE) { if (param->filePerProc == TRUE) {
/* if just opened this file, no data set to close yet */ segmentPosition = (IOR_offset_t) 0;
if (newlyOpenedFile != TRUE) { segmentSize = param->blockSize;
HDF5_CHECK(H5Dclose(dataSet), "cannot close data set"); } else {
HDF5_CHECK(H5Sclose(fileDataSpace), segmentPosition =
"cannot close file data space"); (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 */ SeekOffset_HDF5(fd, param->offset, param);
startNewDataSet = FALSE;
newlyOpenedFile = FALSE;
/* access the file */ /* this is necessary to reset variables for reaccessing file */
if (access == WRITE) { /* WRITE */ startNewDataSet = FALSE;
HDF5_CHECK(H5Dwrite(dataSet, H5T_NATIVE_LLONG, newlyOpenedFile = FALSE;
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() */
/* 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(). * Perform fsync().
*/ */
void void IOR_Fsync_HDF5(void *fd, IOR_param_t * param)
IOR_Fsync_HDF5(void * fd, IOR_param_t * param)
{ {
; ;
} /* IOR_Fsync_HDF5() */ } /* IOR_Fsync_HDF5() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Close a file through the HDF5 interface. * Close a file through the HDF5 interface.
*/ */
void void IOR_Close_HDF5(void *fd, IOR_param_t * param)
IOR_Close_HDF5(void * fd,
IOR_param_t * param)
{ {
if (param->fd_fppReadCheck == NULL) { if (param->fd_fppReadCheck == NULL) {
HDF5_CHECK(H5Dclose(dataSet), "cannot close data set"); HDF5_CHECK(H5Dclose(dataSet), "cannot close data set");
HDF5_CHECK(H5Sclose(dataSpace), "cannot close data space"); HDF5_CHECK(H5Sclose(dataSpace), "cannot close data space");
HDF5_CHECK(H5Sclose(fileDataSpace), "cannot close file data space"); HDF5_CHECK(H5Sclose(fileDataSpace),
HDF5_CHECK(H5Sclose(memDataSpace), "cannot close memory data space"); "cannot close file data space");
HDF5_CHECK(H5Pclose(xferPropList), HDF5_CHECK(H5Sclose(memDataSpace),
" cannot close transfer property list"); "cannot close memory data space");
} HDF5_CHECK(H5Pclose(xferPropList),
HDF5_CHECK(H5Fclose(*(hid_t *)fd), "cannot close file"); " cannot close transfer property list");
free(fd); }
} /* IOR_Close_HDF5() */ HDF5_CHECK(H5Fclose(*(hid_t *) fd), "cannot close file");
free(fd);
} /* IOR_Close_HDF5() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Delete a file through the HDF5 interface. * Delete a file through the HDF5 interface.
*/ */
void void IOR_Delete_HDF5(char *testFileName, IOR_param_t * param)
IOR_Delete_HDF5(char * testFileName, IOR_param_t * param)
{ {
if (unlink(testFileName) != 0) WARN("cannot delete file"); if (unlink(testFileName) != 0)
} /* IOR_Delete_HDF5() */ WARN("cannot delete file");
} /* IOR_Delete_HDF5() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Determine api version. * Determine api version.
*/ */
void void IOR_SetVersion_HDF5(IOR_param_t * test)
IOR_SetVersion_HDF5(IOR_param_t *test)
{ {
unsigned major, minor, release; unsigned major, minor, release;
if (H5get_libversion(&major, &minor, &release) < 0) { if (H5get_libversion(&major, &minor, &release) < 0) {
WARN("cannot get HDF5 library version"); WARN("cannot get HDF5 library version");
} else { } else {
sprintf(test->apiVersion, "%s-%u.%u.%u", sprintf(test->apiVersion, "%s-%u.%u.%u",
test->api, major, minor, release); test->api, major, minor, release);
} }
#ifndef H5_HAVE_PARALLEL #ifndef H5_HAVE_PARALLEL
strcat(test->apiVersion, " (Serial)"); strcat(test->apiVersion, " (Serial)");
#else /* H5_HAVE_PARALLEL */ #else /* H5_HAVE_PARALLEL */
strcat(test->apiVersion, " (Parallel)"); strcat(test->apiVersion, " (Parallel)");
#endif /* not H5_HAVE_PARALLEL */ #endif /* not H5_HAVE_PARALLEL */
} /* IOR_SetVersion_HDF5() */ } /* IOR_SetVersion_HDF5() */
/************************ L O C A L F U N C T I O N S ***********************/ /************************ 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. * Seek to offset in file using the HDF5 interface and set up hyperslab.
*/ */
IOR_offset_t IOR_offset_t SeekOffset_HDF5(void *fd, IOR_offset_t offset, IOR_param_t * param)
SeekOffset_HDF5(void *fd,
IOR_offset_t offset,
IOR_param_t * param)
{ {
IOR_offset_t segmentSize; IOR_offset_t segmentSize;
hsize_t hsStride[NUM_DIMS], hsize_t hsStride[NUM_DIMS], hsCount[NUM_DIMS], hsBlock[NUM_DIMS];
hsCount[NUM_DIMS], hsize_t hsStart[NUM_DIMS];
hsBlock[NUM_DIMS];
hsize_t hsStart[NUM_DIMS];
if (param->filePerProc == TRUE) { if (param->filePerProc == TRUE) {
segmentSize = (IOR_offset_t)param->blockSize; segmentSize = (IOR_offset_t) param->blockSize;
} else { } else {
segmentSize = (IOR_offset_t)(param->numTasks) * param->blockSize; segmentSize =
} (IOR_offset_t) (param->numTasks) * param->blockSize;
}
/* create a hyperslab representing the file data space */ /* create a hyperslab representing the file data space */
if (param->individualDataSets) { if (param->individualDataSets) {
/* start at zero offset if not */ /* start at zero offset if not */
hsStart[0] = (hsize_t)((offset % param->blockSize) hsStart[0] = (hsize_t) ((offset % param->blockSize)
/ sizeof(IOR_size_t)); / sizeof(IOR_size_t));
} else { } else {
/* start at a unique offset if shared */ /* start at a unique offset if shared */
hsStart[0] = (hsize_t)((offset % segmentSize) / sizeof(IOR_size_t)); 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)); hsCount[0] = (hsize_t) 1;
hsBlock[0] = (hsize_t)(param->transferSize / sizeof(IOR_size_t)); 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() */
/* 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. * Create HDF5 data set.
*/ */
void void SetupDataSet_HDF5(void *fd, IOR_param_t * param)
SetupDataSet_HDF5(void * fd,
IOR_param_t * param)
{ {
char dataSetName[MAX_STR]; char dataSetName[MAX_STR];
hid_t dataSetPropList; hid_t dataSetPropList;
int dataSetID; int dataSetID;
static int dataSetSuffix = 0; static int dataSetSuffix = 0;
/* may want to use an extendable dataset (H5S_UNLIMITED) someday */ /* may want to use an extendable dataset (H5S_UNLIMITED) someday */
/* may want to use a chunked dataset (H5S_CHUNKED) someday */ /* may want to use a chunked dataset (H5S_CHUNKED) someday */
/* need to reset suffix counter if newly-opened file */ /* need to reset suffix counter if newly-opened file */
if (newlyOpenedFile) dataSetSuffix = 0; if (newlyOpenedFile)
dataSetSuffix = 0;
/* may want to use individual access to each data set someday */ /* may want to use individual access to each data set someday */
if (param->individualDataSets) { if (param->individualDataSets) {
dataSetID = (rank + rankOffset) % param->numTasks; dataSetID = (rank + rankOffset) % param->numTasks;
} else { } else {
dataSetID = 0; dataSetID = 0;
} }
sprintf(dataSetName, "%s-%04d.%04d", "Dataset", dataSetID, dataSetSuffix++); sprintf(dataSetName, "%s-%04d.%04d", "Dataset", dataSetID,
dataSetSuffix++);
if (param->open == WRITE) { /* WRITE */ if (param->open == WRITE) { /* WRITE */
/* create data set */ /* create data set */
dataSetPropList = H5Pcreate(H5P_DATASET_CREATE); dataSetPropList = H5Pcreate(H5P_DATASET_CREATE);
/* check if hdf5 available */ /* check if hdf5 available */
#if defined (H5_VERS_MAJOR) && defined (H5_VERS_MINOR) #if defined (H5_VERS_MAJOR) && defined (H5_VERS_MINOR)
/* no-fill option not available until hdf5-1.6.x */ /* no-fill option not available until hdf5-1.6.x */
#if (H5_VERS_MAJOR > 0 && H5_VERS_MINOR > 5) #if (H5_VERS_MAJOR > 0 && H5_VERS_MINOR > 5)
if (param->noFill == TRUE) { if (param->noFill == TRUE) {
if (rank == 0 && verbose >= VERBOSE_1) { if (rank == 0 && verbose >= VERBOSE_1) {
fprintf(stdout, "\nusing 'no fill' option\n"); fprintf(stdout, "\nusing 'no fill' option\n");
} }
HDF5_CHECK(H5Pset_fill_time(dataSetPropList, HDF5_CHECK(H5Pset_fill_time(dataSetPropList,
H5D_FILL_TIME_NEVER), H5D_FILL_TIME_NEVER),
"cannot set fill time for property list"); "cannot set fill time for property list");
} }
#else #else
char errorString[MAX_STR]; char errorString[MAX_STR];
sprintf(errorString, "'no fill' option not available in %s", sprintf(errorString, "'no fill' option not available in %s",
test->apiVersion); test->apiVersion);
ERR(errorString); ERR(errorString);
#endif #endif
#else #else
WARN("unable to determine HDF5 version for 'no fill' usage"); WARN("unable to determine HDF5 version for 'no fill' usage");
#endif #endif
dataSet = H5Dcreate(*(hid_t *)fd, dataSetName, H5T_NATIVE_LLONG, dataSet =
dataSpace, dataSetPropList); H5Dcreate(*(hid_t *) fd, dataSetName, H5T_NATIVE_LLONG,
HDF5_CHECK(dataSet, "cannot create data set"); dataSpace, dataSetPropList);
} else { /* READ or CHECK */ HDF5_CHECK(dataSet, "cannot create data set");
dataSet = H5Dopen(*(hid_t *)fd, dataSetName); } else { /* READ or CHECK */
HDF5_CHECK(dataSet, "cannot create data set"); dataSet = H5Dopen(*(hid_t *) fd, dataSetName);
} HDF5_CHECK(dataSet, "cannot create data set");
}
} /* SetupDataSet_HDF5() */
} /* SetupDataSet_HDF5() */
/******************************************************************************/ /******************************************************************************/
/* /*
@ -588,9 +582,7 @@ SetupDataSet_HDF5(void * fd,
*/ */
IOR_offset_t IOR_offset_t
IOR_GetFileSize_HDF5(IOR_param_t * test, IOR_GetFileSize_HDF5(IOR_param_t * test, MPI_Comm testComm, char *testFileName)
MPI_Comm testComm,
char * testFileName)
{ {
return(IOR_GetFileSize_MPIIO(test, testComm, testFileName)); return (IOR_GetFileSize_MPIIO(test, testComm, testFileName));
} /* IOR_GetFileSize_HDF5() */ } /* IOR_GetFileSize_HDF5() */

View File

@ -9,53 +9,51 @@
* *
\******************************************************************************/ \******************************************************************************/
#include "aiori.h" /* abstract IOR interface */ #include "aiori.h" /* abstract IOR interface */
#include <errno.h> /* sys_errlist */ #include <errno.h> /* sys_errlist */
#include <stdio.h> /* only for fprintf() */ #include <stdio.h> /* only for fprintf() */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifndef MPIAPI #ifndef MPIAPI
# define MPIAPI /* defined as __stdcall on Windows */ #define MPIAPI /* defined as __stdcall on Windows */
#endif #endif
/**************************** P R O T O T Y P E S *****************************/ /**************************** P R O T O T Y P E S *****************************/
static IOR_offset_t SeekOffset_MPIIO (MPI_File, IOR_offset_t, static IOR_offset_t SeekOffset_MPIIO(MPI_File, IOR_offset_t, IOR_param_t *);
IOR_param_t *); void SetHints(MPI_Info *, char *);
void SetHints (MPI_Info *, char *); void ShowHints(MPI_Info *);
void ShowHints (MPI_Info *);
void * IOR_Create_MPIIO (char *, IOR_param_t *); void *IOR_Create_MPIIO(char *, IOR_param_t *);
void * IOR_Open_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_Xfer_MPIIO(int, void *, IOR_size_t *,
IOR_offset_t, IOR_param_t *); IOR_offset_t, IOR_param_t *);
void IOR_Close_MPIIO (void *, IOR_param_t *); void IOR_Close_MPIIO(void *, IOR_param_t *);
void IOR_Delete_MPIIO (char *, IOR_param_t *); void IOR_Delete_MPIIO(char *, IOR_param_t *);
void IOR_SetVersion_MPIIO (IOR_param_t *); void IOR_SetVersion_MPIIO(IOR_param_t *);
void IOR_Fsync_MPIIO (void *, IOR_param_t *); void IOR_Fsync_MPIIO(void *, IOR_param_t *);
IOR_offset_t IOR_GetFileSize_MPIIO (IOR_param_t *, MPI_Comm, char *); IOR_offset_t IOR_GetFileSize_MPIIO(IOR_param_t *, MPI_Comm, char *);
/************************** D E C L A R A T I O N S ***************************/ /************************** D E C L A R A T I O N S ***************************/
extern int errno; extern int errno;
extern int rank; extern int rank;
extern int rankOffset; extern int rankOffset;
extern int verbose; extern int verbose;
extern MPI_Comm testComm; extern MPI_Comm testComm;
ior_aiori_t mpiio_aiori = { ior_aiori_t mpiio_aiori = {
"MPIIO", "MPIIO",
IOR_Create_MPIIO, IOR_Create_MPIIO,
IOR_Open_MPIIO, IOR_Open_MPIIO,
IOR_Xfer_MPIIO, IOR_Xfer_MPIIO,
IOR_Close_MPIIO, IOR_Close_MPIIO,
IOR_Delete_MPIIO, IOR_Delete_MPIIO,
IOR_SetVersion_MPIIO, IOR_SetVersion_MPIIO,
IOR_Fsync_MPIIO, IOR_Fsync_MPIIO,
IOR_GetFileSize_MPIIO IOR_GetFileSize_MPIIO
}; };
/***************************** F U N C T I O N S ******************************/ /***************************** 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. * Create and open a file through the MPIIO interface.
*/ */
void * void *IOR_Create_MPIIO(char *testFileName, IOR_param_t * param)
IOR_Create_MPIIO(char * testFileName,
IOR_param_t * param)
{ {
return IOR_Open_MPIIO(testFileName, param); return IOR_Open_MPIIO(testFileName, param);
} /* IOR_Create_MPIIO() */ } /* IOR_Create_MPIIO() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Open a file through the MPIIO interface. Setup file view. * Open a file through the MPIIO interface. Setup file view.
*/ */
void * void *IOR_Open_MPIIO(char *testFileName, IOR_param_t * param)
IOR_Open_MPIIO(char * testFileName,
IOR_param_t * param)
{ {
int fd_mode = (int)0, int fd_mode = (int)0,
offsetFactor, offsetFactor,
tasksPerFile, tasksPerFile,
transfersPerBlock = param->blockSize transfersPerBlock = param->blockSize / param->transferSize;
/ param->transferSize; struct fileTypeStruct {
struct fileTypeStruct { int globalSizes[2], localSizes[2], startIndices[2];
int globalSizes[2], } fileTypeStruct;
localSizes[2], MPI_File *fd;
startIndices[2]; MPI_Comm comm;
} fileTypeStruct; MPI_Info mpiHints = MPI_INFO_NULL;
MPI_File * fd;
MPI_Comm comm;
MPI_Info mpiHints = MPI_INFO_NULL;
fd = (MPI_File *)malloc(sizeof(MPI_File)); fd = (MPI_File *) malloc(sizeof(MPI_File));
if (fd == NULL) if (fd == NULL)
ERR("malloc failed()"); ERR("malloc failed()");
*fd = 0; *fd = 0;
/* set IOR file flags to MPIIO flags */ /* set IOR file flags to MPIIO flags */
/* -- file open flags -- */ /* -- file open flags -- */
if (param->openFlags & IOR_RDONLY) {fd_mode |= MPI_MODE_RDONLY;} if (param->openFlags & IOR_RDONLY) {
if (param->openFlags & IOR_WRONLY) {fd_mode |= MPI_MODE_WRONLY;} fd_mode |= MPI_MODE_RDONLY;
if (param->openFlags & IOR_RDWR) {fd_mode |= MPI_MODE_RDWR;} }
if (param->openFlags & IOR_APPEND) {fd_mode |= MPI_MODE_APPEND;} if (param->openFlags & IOR_WRONLY) {
if (param->openFlags & IOR_CREAT) {fd_mode |= MPI_MODE_CREATE;} fd_mode |= MPI_MODE_WRONLY;
if (param->openFlags & IOR_EXCL) {fd_mode |= MPI_MODE_EXCL;} }
if (param->openFlags & IOR_TRUNC) { if (param->openFlags & IOR_RDWR) {
fprintf(stdout, "File truncation not implemented in MPIIO\n"); fd_mode |= MPI_MODE_RDWR;
} }
if (param->openFlags & IOR_DIRECT) { if (param->openFlags & IOR_APPEND) {
fprintf(stdout, "O_DIRECT not implemented in MPIIO\n"); fd_mode |= MPI_MODE_APPEND;
} }
if (param->openFlags & IOR_CREAT) {
/* fd_mode |= MPI_MODE_CREATE;
* 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- if (param->openFlags & IOR_EXCL) {
* currently opened elsewhere, either inside or outside the MPI environment. fd_mode |= MPI_MODE_EXCL;
*/ }
fd_mode |= MPI_MODE_UNIQUE_OPEN; if (param->openFlags & IOR_TRUNC) {
fprintf(stdout, "File truncation not implemented in MPIIO\n");
if (param->filePerProc) { }
comm = MPI_COMM_SELF; if (param->openFlags & IOR_DIRECT) {
} else { fprintf(stdout, "O_DIRECT not implemented in MPIIO\n");
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, &param->transferType),
"cannot create contiguous datatype");
MPI_CHECK(MPI_Type_commit(&param->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 * 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; fd_mode |= MPI_MODE_UNIQUE_OPEN;
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, if (param->filePerProc) {
fileTypeStruct.localSizes, comm = MPI_COMM_SELF;
fileTypeStruct.startIndices, } else {
MPI_ORDER_C, param->transferType, comm = testComm;
&param->fileType), }
"cannot create subarray");
MPI_CHECK(MPI_Type_commit(&param->fileType), "cannot commit datatype");
MPI_CHECK(MPI_File_set_view(*fd, (MPI_Offset)0, SetHints(&mpiHints, param->hintsFileName);
param->transferType, param->fileType, /*
"native", (MPI_Info)MPI_INFO_NULL), * note that with MP_HINTS_FILTERED=no, all key/value pairs will
"cannot set file view"); * be in the info object. The info object that is attached to
} * the file during MPI_File_open() will only contain those pairs
return((void *)fd); * deemed valid by the implementation.
} /* IOR_Open_MPIIO() */ */
/* 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, &param->transferType),
"cannot create contiguous datatype");
MPI_CHECK(MPI_Type_commit(&param->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, &param->fileType),
"cannot create subarray");
MPI_CHECK(MPI_Type_commit(&param->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_offset_t
IOR_Xfer_MPIIO(int access, IOR_Xfer_MPIIO(int access,
void * fd, void *fd,
IOR_size_t * buffer, IOR_size_t * buffer, IOR_offset_t length, IOR_param_t * param)
IOR_offset_t length,
IOR_param_t * param)
{ {
int (MPIAPI *Access) (MPI_File, void *, int, int (MPIAPI * Access) (MPI_File, void *, int,
MPI_Datatype, MPI_Status *); MPI_Datatype, MPI_Status *);
int (MPIAPI *Access_at) (MPI_File, MPI_Offset, void *, int, int (MPIAPI * Access_at) (MPI_File, MPI_Offset, void *, int,
MPI_Datatype,MPI_Status *); MPI_Datatype, MPI_Status *);
int (MPIAPI *Access_all) (MPI_File, void *, int, int (MPIAPI * Access_all) (MPI_File, void *, int,
MPI_Datatype, MPI_Status *); MPI_Datatype, MPI_Status *);
int (MPIAPI *Access_at_all) (MPI_File, MPI_Offset, void *, int, int (MPIAPI * Access_at_all) (MPI_File, MPI_Offset, void *, int,
MPI_Datatype, MPI_Status *); 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;
/* /*
* this needs to be properly implemented: * 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 */ MPI_Status status;
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;
*/
}
/* /* point functions to appropriate MPIIO calls */
* 'useFileView' uses derived datatypes and individual file pointers if (access == WRITE) { /* WRITE */
*/ Access = MPI_File_write;
if (param->useFileView) { Access_at = MPI_File_write_at;
/* find offset in file */ Access_all = MPI_File_write_all;
if (SeekOffset_MPIIO(*(MPI_File *)fd, param->offset, param) < 0) { Access_at_all = MPI_File_write_at_all;
/* 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: * this needs to be properly implemented:
* *
* MPI_CHECK(Access_ordered(fd.MPIIO, buffer, length, * Access_ordered = MPI_File_write_ordered;
* MPI_BYTE, &status), */
* "cannot access shared, collective"); } 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(). * Perform fsync().
*/ */
void void IOR_Fsync_MPIIO(void *fd, IOR_param_t * param)
IOR_Fsync_MPIIO(void * fd, IOR_param_t * param)
{ {
; ;
} /* IOR_Fsync_MPIIO() */ } /* IOR_Fsync_MPIIO() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Close a file through the MPIIO interface. * Close a file through the MPIIO interface.
*/ */
void void IOR_Close_MPIIO(void *fd, IOR_param_t * param)
IOR_Close_MPIIO(void * fd,
IOR_param_t * param)
{ {
MPI_CHECK(MPI_File_close((MPI_File *)fd), "cannot close file"); MPI_CHECK(MPI_File_close((MPI_File *) fd), "cannot close file");
if ((param->useFileView == TRUE) && (param->fd_fppReadCheck == NULL)) { if ((param->useFileView == TRUE) && (param->fd_fppReadCheck == NULL)) {
/* /*
* need to free the datatype, so done in the close process * need to free the datatype, so done in the close process
*/ */
MPI_CHECK(MPI_Type_free(&param->fileType), MPI_CHECK(MPI_Type_free(&param->fileType),
"cannot free MPI file datatype"); "cannot free MPI file datatype");
MPI_CHECK(MPI_Type_free(&param->transferType), MPI_CHECK(MPI_Type_free(&param->transferType),
"cannot free MPI transfer datatype"); "cannot free MPI transfer datatype");
} }
free(fd); free(fd);
} /* IOR_Close_MPIIO() */ } /* IOR_Close_MPIIO() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Delete a file through the MPIIO interface. * Delete a file through the MPIIO interface.
*/ */
void void IOR_Delete_MPIIO(char *testFileName, IOR_param_t * param)
IOR_Delete_MPIIO(char * testFileName, IOR_param_t * param)
{ {
MPI_CHECK(MPI_File_delete(testFileName, (MPI_Info)MPI_INFO_NULL), MPI_CHECK(MPI_File_delete(testFileName, (MPI_Info) MPI_INFO_NULL),
"cannot delete file"); "cannot delete file");
} /* IOR_Delete_MPIIO() */ } /* IOR_Delete_MPIIO() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Determine api version. * Determine api version.
*/ */
void void IOR_SetVersion_MPIIO(IOR_param_t * test)
IOR_SetVersion_MPIIO(IOR_param_t *test)
{ {
int version, subversion; int version, subversion;
MPI_CHECK(MPI_Get_version(&version, &subversion), MPI_CHECK(MPI_Get_version(&version, &subversion),
"cannot get MPI version"); "cannot get MPI version");
sprintf(test->apiVersion, "%s (version=%d, subversion=%d)", sprintf(test->apiVersion, "%s (version=%d, subversion=%d)",
test->api, version, subversion); test->api, version, subversion);
} /* IOR_SetVersion_MPIIO() */ } /* IOR_SetVersion_MPIIO() */
/************************ L O C A L F U N C T I O N S ***********************/ /************************ 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 static IOR_offset_t
SeekOffset_MPIIO(MPI_File fd, SeekOffset_MPIIO(MPI_File fd, IOR_offset_t offset, IOR_param_t * param)
IOR_offset_t offset,
IOR_param_t * param)
{ {
int offsetFactor, int offsetFactor, tasksPerFile;
tasksPerFile; IOR_offset_t tempOffset;
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) { if (param->filePerProc) {
tempOffset = tempOffset / param->transferSize; offsetFactor = 0;
tasksPerFile = 1;
} else { } else {
/* offsetFactor = (rank + rankOffset) % param->numTasks;
* this formula finds a file view offset for a task tasksPerFile = param->numTasks;
* from an absolute offset
*/
tempOffset = ((param->blockSize / param->transferSize)
* (tempOffset / (param->blockSize * tasksPerFile)))
+ (((tempOffset % (param->blockSize * tasksPerFile))
- (offsetFactor * param->blockSize))
/ param->transferSize);
} }
} if (param->useFileView) {
MPI_CHECK(MPI_File_seek(fd, tempOffset, MPI_SEEK_SET), /* recall that offsets in a file view are
"cannot seek offset"); counted in units of transfer size */
return(offset); if (param->filePerProc) {
} /* SeekOffset_MPIIO() */ 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_offset_t
IOR_GetFileSize_MPIIO(IOR_param_t * test, IOR_GetFileSize_MPIIO(IOR_param_t * test, MPI_Comm testComm, char *testFileName)
MPI_Comm testComm,
char * testFileName)
{ {
IOR_offset_t aggFileSizeFromStat, IOR_offset_t aggFileSizeFromStat, tmpMin, tmpMax, tmpSum;
tmpMin, tmpMax, tmpSum; MPI_File fd;
MPI_File fd;
MPI_CHECK(MPI_File_open(testComm, testFileName, MPI_MODE_RDONLY, MPI_CHECK(MPI_File_open(testComm, testFileName, MPI_MODE_RDONLY,
MPI_INFO_NULL, &fd), MPI_INFO_NULL, &fd),
"cannot open file to get file size"); "cannot open file to get file size");
MPI_CHECK(MPI_File_get_size(fd, (MPI_Offset *)&aggFileSizeFromStat), MPI_CHECK(MPI_File_get_size(fd, (MPI_Offset *) & aggFileSizeFromStat),
"cannot get file size"); "cannot get file size");
MPI_CHECK(MPI_File_close(&fd), "cannot close file"); MPI_CHECK(MPI_File_close(&fd), "cannot close file");
if (test->filePerProc == TRUE) { if (test->filePerProc == TRUE) {
MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpSum, 1, MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpSum, 1,
MPI_LONG_LONG_INT, MPI_SUM, testComm), MPI_LONG_LONG_INT, MPI_SUM, testComm),
"cannot total data moved"); "cannot total data moved");
aggFileSizeFromStat = tmpSum; aggFileSizeFromStat = tmpSum;
} else { } else {
MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMin, 1, MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMin, 1,
MPI_LONG_LONG_INT, MPI_MIN, testComm), MPI_LONG_LONG_INT, MPI_MIN, testComm),
"cannot total data moved"); "cannot total data moved");
MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMax, 1, MPI_CHECK(MPI_Allreduce(&aggFileSizeFromStat, &tmpMax, 1,
MPI_LONG_LONG_INT, MPI_MAX, testComm), MPI_LONG_LONG_INT, MPI_MAX, testComm),
"cannot total data moved"); "cannot total data moved");
if (tmpMin != tmpMax) { if (tmpMin != tmpMax) {
if (rank == 0) { if (rank == 0) {
WARN("inconsistent file size by different tasks"); WARN("inconsistent file size by different tasks");
} }
/* incorrect, but now consistent across tasks */ /* incorrect, but now consistent across tasks */
aggFileSizeFromStat = tmpMin; aggFileSizeFromStat = tmpMin;
}
} }
}
return(aggFileSizeFromStat); return (aggFileSizeFromStat);
} /* IOR_GetFileSize_MPIIO() */ } /* IOR_GetFileSize_MPIIO() */

View File

@ -9,14 +9,14 @@
* *
\******************************************************************************/ \******************************************************************************/
#include "aiori.h" /* abstract IOR interface */ #include "aiori.h" /* abstract IOR interface */
#include <errno.h> /* sys_errlist */ #include <errno.h> /* sys_errlist */
#include <stdio.h> /* only for fprintf() */ #include <stdio.h> /* only for fprintf() */
#include <stdlib.h> #include <stdlib.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <pnetcdf.h> #include <pnetcdf.h>
#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 *****************************/ /**************************** P R O T O T Y P E S *****************************/
int GetFileMode(IOR_param_t *); int GetFileMode(IOR_param_t *);
void SetHints (MPI_Info *, char *); void SetHints(MPI_Info *, char *);
void ShowHints (MPI_Info *); void ShowHints(MPI_Info *);
void * IOR_Create_NCMPI (char *, IOR_param_t *); void *IOR_Create_NCMPI(char *, IOR_param_t *);
void * IOR_Open_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_Xfer_NCMPI(int, void *, IOR_size_t *,
IOR_offset_t, IOR_param_t *); IOR_offset_t, IOR_param_t *);
void IOR_Close_NCMPI (void *, IOR_param_t *); void IOR_Close_NCMPI(void *, IOR_param_t *);
void IOR_Delete_NCMPI (char *, IOR_param_t *); void IOR_Delete_NCMPI(char *, IOR_param_t *);
void IOR_SetVersion_NCMPI (IOR_param_t *); void IOR_SetVersion_NCMPI(IOR_param_t *);
void IOR_Fsync_NCMPI (void *, IOR_param_t *); void IOR_Fsync_NCMPI(void *, IOR_param_t *);
IOR_offset_t IOR_GetFileSize_NCMPI (IOR_param_t *, MPI_Comm, char *); IOR_offset_t IOR_GetFileSize_NCMPI(IOR_param_t *, MPI_Comm, char *);
/************************** D E C L A R A T I O N S ***************************/ /************************** D E C L A R A T I O N S ***************************/
ior_aiori_t ncmpi_aiori = { ior_aiori_t ncmpi_aiori = {
"NCMPI", "NCMPI",
IOR_Create_NCMPI, IOR_Create_NCMPI,
IOR_Open_NCMPI, IOR_Open_NCMPI,
IOR_Xfer_NCMPI, IOR_Xfer_NCMPI,
IOR_Close_NCMPI, IOR_Close_NCMPI,
IOR_Delete_NCMPI, IOR_Delete_NCMPI,
IOR_SetVersion_NCMPI, IOR_SetVersion_NCMPI,
IOR_Fsync_NCMPI, IOR_Fsync_NCMPI,
IOR_GetFileSize_NCMPI IOR_GetFileSize_NCMPI
}; };
extern int errno, /* error number */ extern int errno, /* error number */
numTasksWorld, numTasksWorld, rank, rankOffset, verbose; /* verbose output */
rank,
rankOffset,
verbose; /* verbose output */
extern MPI_Comm testComm; extern MPI_Comm testComm;
/***************************** F U N C T I O N S ******************************/ /***************************** 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. * Create and open a file through the NCMPI interface.
*/ */
void * void *IOR_Create_NCMPI(char *testFileName, IOR_param_t * param)
IOR_Create_NCMPI(char * testFileName,
IOR_param_t * param)
{ {
int * fd; int *fd;
int fd_mode; int fd_mode;
MPI_Info mpiHints = MPI_INFO_NULL; MPI_Info mpiHints = MPI_INFO_NULL;
/* Wei-keng Liao: read and set MPI file hints from hintsFile */ /* Wei-keng Liao: read and set MPI file hints from hintsFile */
SetHints(&mpiHints, param->hintsFileName); SetHints(&mpiHints, param->hintsFileName);
if (rank == 0 && param->showHints) { if (rank == 0 && param->showHints) {
fprintf(stdout, "\nhints passed to MPI_File_open() {\n"); fprintf(stdout, "\nhints passed to MPI_File_open() {\n");
ShowHints(&mpiHints); ShowHints(&mpiHints);
fprintf(stdout, "}\n"); fprintf(stdout, "}\n");
} }
fd = (int *)malloc(sizeof(int)); fd = (int *)malloc(sizeof(int));
if (fd == NULL) if (fd == NULL)
ERR("malloc() failed"); ERR("malloc() failed");
fd_mode = GetFileMode(param); fd_mode = GetFileMode(param);
NCMPI_CHECK(ncmpi_create(testComm, testFileName, fd_mode, NCMPI_CHECK(ncmpi_create(testComm, testFileName, fd_mode,
mpiHints, fd), "cannot create file"); 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 /* WEL - add when ncmpi_get_file_info() is in current parallel-netcdf release
if (rank == 0 && param->showHints) { if (rank == 0 && param->showHints) {
MPI_CHECK(ncmpi_get_file_info(*fd, &mpiHints), 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 /* WEL - this needs future fix from next release of PnetCDF
if (mpiHints != MPI_INFO_NULL) if (mpiHints != MPI_INFO_NULL)
MPI_CHECK(MPI_Info_free(&mpiHints), "cannot free file info"); MPI_CHECK(MPI_Info_free(&mpiHints), "cannot free file info");
*/ */
return(fd); return (fd);
} /* IOR_Create_NCMPI() */ } /* IOR_Create_NCMPI() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Open a file through the NCMPI interface. * Open a file through the NCMPI interface.
*/ */
void * void *IOR_Open_NCMPI(char *testFileName, IOR_param_t * param)
IOR_Open_NCMPI(char * testFileName,
IOR_param_t * param)
{ {
int * fd; int *fd;
int fd_mode; int fd_mode;
MPI_Info mpiHints = MPI_INFO_NULL; MPI_Info mpiHints = MPI_INFO_NULL;
/* Wei-keng Liao: read and set MPI file hints from hintsFile */ /* Wei-keng Liao: read and set MPI file hints from hintsFile */
SetHints(&mpiHints, param->hintsFileName); SetHints(&mpiHints, param->hintsFileName);
if (rank == 0 && param->showHints) { if (rank == 0 && param->showHints) {
fprintf(stdout, "\nhints passed to MPI_File_open() {\n"); fprintf(stdout, "\nhints passed to MPI_File_open() {\n");
ShowHints(&mpiHints); ShowHints(&mpiHints);
fprintf(stdout, "}\n"); fprintf(stdout, "}\n");
} }
fd = (int *)malloc(sizeof(int)); fd = (int *)malloc(sizeof(int));
if (fd == NULL) if (fd == NULL)
ERR("malloc() failed"); ERR("malloc() failed");
fd_mode = GetFileMode(param); fd_mode = GetFileMode(param);
NCMPI_CHECK(ncmpi_open(testComm, testFileName, fd_mode, NCMPI_CHECK(ncmpi_open(testComm, testFileName, fd_mode,
mpiHints, fd), "cannot open file"); 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 /* WEL - add when ncmpi_get_file_info() is in current parallel-netcdf release
if (rank == 0 && param->showHints) { if (rank == 0 && param->showHints) {
MPI_CHECK(ncmpi_get_file_info(*fd, &mpiHints), 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 /* WEL - this needs future fix from next release of PnetCDF
if (mpiHints != MPI_INFO_NULL) if (mpiHints != MPI_INFO_NULL)
MPI_CHECK(MPI_Info_free(&mpiHints), "cannot free file info"); MPI_CHECK(MPI_Info_free(&mpiHints), "cannot free file info");
*/ */
return(fd); return (fd);
} /* IOR_Open_NCMPI() */ } /* IOR_Open_NCMPI() */
/******************************************************************************/ /******************************************************************************/
/* /*
@ -180,195 +171,189 @@ IOR_Open_NCMPI(char * testFileName,
*/ */
IOR_offset_t IOR_offset_t
IOR_Xfer_NCMPI(int access, IOR_Xfer_NCMPI(int access,
void * fd, void *fd,
IOR_size_t * buffer, IOR_size_t * buffer, IOR_offset_t length, IOR_param_t * param)
IOR_offset_t length,
IOR_param_t * param)
{ {
char * bufferPtr = (char *)buffer; char *bufferPtr = (char *)buffer;
static int firstReadCheck = FALSE, static int firstReadCheck = FALSE, startDataSet;
startDataSet; int var_id, dim_id[NUM_DIMS];
int var_id, MPI_Offset bufSize[NUM_DIMS], offset[NUM_DIMS];
dim_id[NUM_DIMS]; IOR_offset_t segmentPosition;
MPI_Offset bufSize[NUM_DIMS], int segmentNum, transferNum;
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 /* Wei-keng Liao: In ior.c line 1979 says "block size must be a multiple
of transfer size." Hence, length should always == param->transferSize of transfer size." Hence, length should always == param->transferSize
below. I leave it here to double check. 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
*/ */
if (access == READCHECK) { if (length != param->transferSize) {
if (firstReadCheck == TRUE) { char errMsg[256];
firstReadCheck = FALSE; sprintf(errMsg, "length(%lld) != param->transferSize(%lld)\n",
} else { length, param->transferSize);
firstReadCheck = TRUE; NCMPI_CHECK(-1, errMsg);
}
} }
}
if (startDataSet == TRUE && /* determine by offset if need to start data set */
(access != READCHECK || firstReadCheck == TRUE)) { if (param->filePerProc == TRUE) {
if (access == WRITE) { segmentPosition = (IOR_offset_t) 0;
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 { } else {
NCMPI_CHECK(ncmpi_inq_varid(*(int *)fd, "data_var", &var_id), segmentPosition =
"cannot retrieve data set variable"); (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) { if (startDataSet == TRUE &&
NCMPI_CHECK(ncmpi_begin_indep_data(*(int *)fd), (access != READCHECK || firstReadCheck == TRUE)) {
"cannot enable independent data mode"); 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; var_id = param->var_id;
startDataSet = FALSE;
}
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 */ /* Wei-keng Liao: calculate the transfer number in each block */
segmentNum = param->offset / (param->numTasks * param->blockSize); transferNum = param->offset % param->blockSize / param->transferSize;
/* Wei-keng Liao: calculate the transfer number in each block */ /* Wei-keng Liao: read/write the 3rd dim of the dataset, each is of
transferNum = param->offset % param->blockSize / param->transferSize; 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 offset[0] = segmentNum * numTasksWorld + rank;
amount param->transferSize */ offset[1] = transferNum;
bufSize[0] = 1; offset[2] = 0;
bufSize[1] = 1;
bufSize[2] = param->transferSize;
offset[0] = segmentNum * numTasksWorld + rank; /* access the file */
offset[1] = transferNum; if (access == WRITE) { /* WRITE */
offset[2] = 0; if (param->collective) {
NCMPI_CHECK(ncmpi_put_vara_all
/* access the file */ (*(int *)fd, var_id, offset, bufSize,
if (access == WRITE) { /* WRITE */ bufferPtr, length, MPI_BYTE),
if (param->collective) { "cannot write to data set");
NCMPI_CHECK(ncmpi_put_vara_all(*(int *)fd, var_id, offset, bufSize, } else {
bufferPtr, length, MPI_BYTE), NCMPI_CHECK(ncmpi_put_vara
"cannot write to data set"); (*(int *)fd, var_id, offset, bufSize,
} else { bufferPtr, length, MPI_BYTE),
NCMPI_CHECK(ncmpi_put_vara(*(int *)fd, var_id, offset, bufSize, "cannot write to data set");
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(). * Perform fsync().
*/ */
void void IOR_Fsync_NCMPI(void *fd, IOR_param_t * param)
IOR_Fsync_NCMPI(void * fd, IOR_param_t * param)
{ {
; ;
} /* IOR_Fsync_NCMPI() */ } /* IOR_Fsync_NCMPI() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Close a file through the NCMPI interface. * Close a file through the NCMPI interface.
*/ */
void void IOR_Close_NCMPI(void *fd, IOR_param_t * param)
IOR_Close_NCMPI(void * fd,
IOR_param_t * param)
{ {
if (param->collective == FALSE) { if (param->collective == FALSE) {
NCMPI_CHECK(ncmpi_end_indep_data(*(int *)fd), NCMPI_CHECK(ncmpi_end_indep_data(*(int *)fd),
"cannot disable independent data mode"); "cannot disable independent data mode");
} }
NCMPI_CHECK(ncmpi_close(*(int *)fd), "cannot close file"); NCMPI_CHECK(ncmpi_close(*(int *)fd), "cannot close file");
free(fd); free(fd);
} /* IOR_Close_NCMPI() */ } /* IOR_Close_NCMPI() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Delete a file through the NCMPI interface. * Delete a file through the NCMPI interface.
*/ */
void void IOR_Delete_NCMPI(char *testFileName, IOR_param_t * param)
IOR_Delete_NCMPI(char * testFileName, IOR_param_t * param)
{ {
if (unlink(testFileName) != 0) if (unlink(testFileName) != 0)
WARN("unlink() failed"); WARN("unlink() failed");
} /* IOR_Delete_NCMPI() */ } /* IOR_Delete_NCMPI() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Determine api version. * Determine api version.
*/ */
void void IOR_SetVersion_NCMPI(IOR_param_t * test)
IOR_SetVersion_NCMPI(IOR_param_t * test)
{ {
sprintf(test->apiVersion, "%s (%s)", sprintf(test->apiVersion, "%s (%s)", test->api, ncmpi_inq_libvers());
test->api, ncmpi_inq_libvers()); } /* IOR_SetVersion_NCMPI() */
} /* IOR_SetVersion_NCMPI() */
/************************ L O C A L F U N C T I O N S ***********************/ /************************ 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. * Return the correct file mode for NCMPI.
*/ */
int int GetFileMode(IOR_param_t * param)
GetFileMode(IOR_param_t * param)
{ {
int fd_mode = 0; int fd_mode = 0;
/* set IOR file flags to NCMPI flags */ /* set IOR file flags to NCMPI flags */
/* -- file open flags -- */ /* -- file open flags -- */
if (param->openFlags & IOR_RDONLY) {fd_mode |= NC_NOWRITE;} if (param->openFlags & IOR_RDONLY) {
if (param->openFlags & IOR_WRONLY) { fd_mode |= NC_NOWRITE;
fprintf(stdout, "File write only not implemented in NCMPI\n"); }
} if (param->openFlags & IOR_WRONLY) {
if (param->openFlags & IOR_RDWR) {fd_mode |= NC_WRITE;} fprintf(stdout, "File write only not implemented in NCMPI\n");
if (param->openFlags & IOR_APPEND) { }
fprintf(stdout, "File append not implemented in NCMPI\n"); if (param->openFlags & IOR_RDWR) {
} fd_mode |= NC_WRITE;
if (param->openFlags & IOR_CREAT) {fd_mode |= NC_CLOBBER;} }
if (param->openFlags & IOR_EXCL) { if (param->openFlags & IOR_APPEND) {
fprintf(stdout, "Exclusive access not implemented in NCMPI\n"); fprintf(stdout, "File append not implemented in NCMPI\n");
} }
if (param->openFlags & IOR_TRUNC) { if (param->openFlags & IOR_CREAT) {
fprintf(stdout, "File truncation not implemented in NCMPI\n"); fd_mode |= NC_CLOBBER;
} }
if (param->openFlags & IOR_DIRECT) { if (param->openFlags & IOR_EXCL) {
fprintf(stdout, "O_DIRECT not implemented in NCMPI\n"); 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 */ /* Wei-keng Liao: to enable > 4GB file size */
fd_mode |= NC_64BIT_OFFSET; fd_mode |= NC_64BIT_OFFSET;
return(fd_mode);
} /* GetFileMode() */
return (fd_mode);
} /* GetFileMode() */
/******************************************************************************/ /******************************************************************************/
/* /*
@ -416,9 +405,7 @@ GetFileMode(IOR_param_t * param)
*/ */
IOR_offset_t IOR_offset_t
IOR_GetFileSize_NCMPI(IOR_param_t * test, IOR_GetFileSize_NCMPI(IOR_param_t * test, MPI_Comm testComm, char *testFileName)
MPI_Comm testComm,
char * testFileName)
{ {
return(IOR_GetFileSize_MPIIO(test, testComm, testFileName)); return (IOR_GetFileSize_MPIIO(test, testComm, testFileName));
} /* IOR_GetFileSize_NCMPI() */ } /* IOR_GetFileSize_NCMPI() */

View File

@ -9,65 +9,64 @@
* *
\******************************************************************************/ \******************************************************************************/
#include "aiori.h" /* abstract IOR interface */ #include "aiori.h" /* abstract IOR interface */
#ifdef __linux__ #ifdef __linux__
# include <sys/ioctl.h> /* necessary for: */ #include <sys/ioctl.h> /* necessary for: */
# define __USE_GNU /* O_DIRECT and */ #define __USE_GNU /* O_DIRECT and */
# include <fcntl.h> /* IO operations */ #include <fcntl.h> /* IO operations */
# undef __USE_GNU #undef __USE_GNU
#endif /* __linux__ */ #endif /* __linux__ */
#include <errno.h> /* sys_errlist */ #include <errno.h> /* sys_errlist */
#include <fcntl.h> /* IO operations */ #include <fcntl.h> /* IO operations */
#include <stdio.h> /* only for fprintf() */ #include <stdio.h> /* only for fprintf() */
#include <stdlib.h> #include <stdlib.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <assert.h> #include <assert.h>
#ifdef HAVE_LUSTRE_LUSTRE_USER_H #ifdef HAVE_LUSTRE_LUSTRE_USER_H
# include <lustre/lustre_user.h> #include <lustre/lustre_user.h>
#endif /* HAVE_LUSTRE_LUSTRE_USER_H */ #endif /* HAVE_LUSTRE_LUSTRE_USER_H */
#ifndef open64 /* necessary for TRU64 -- */ #ifndef open64 /* necessary for TRU64 -- */
# define open64 open /* unlikely, but may pose */ #define open64 open /* unlikely, but may pose */
#endif /* not open64 */ /* conflicting prototypes */ #endif /* not open64 */ /* conflicting prototypes */
#ifndef lseek64 /* necessary for TRU64 -- */ #ifndef lseek64 /* necessary for TRU64 -- */
# define lseek64 lseek /* unlikely, but may pose */ #define lseek64 lseek /* unlikely, but may pose */
#endif /* not lseek64 */ /* conflicting prototypes */ #endif /* not lseek64 */ /* conflicting prototypes */
#ifndef O_BINARY /* Required on Windows */ #ifndef O_BINARY /* Required on Windows */
# define O_BINARY 0 #define O_BINARY 0
#endif #endif
/**************************** P R O T O T Y P E S *****************************/ /**************************** P R O T O T Y P E S *****************************/
void * IOR_Create_POSIX (char *, IOR_param_t *); void *IOR_Create_POSIX(char *, IOR_param_t *);
void * IOR_Open_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_Xfer_POSIX(int, void *, IOR_size_t *,
IOR_offset_t, IOR_param_t *); IOR_offset_t, IOR_param_t *);
void IOR_Close_POSIX (void *, IOR_param_t *); void IOR_Close_POSIX(void *, IOR_param_t *);
void IOR_Delete_POSIX (char *, IOR_param_t *); void IOR_Delete_POSIX(char *, IOR_param_t *);
void IOR_SetVersion_POSIX (IOR_param_t *); void IOR_SetVersion_POSIX(IOR_param_t *);
void IOR_Fsync_POSIX (void *, IOR_param_t *); void IOR_Fsync_POSIX(void *, IOR_param_t *);
IOR_offset_t IOR_GetFileSize_POSIX (IOR_param_t *, MPI_Comm, char *); IOR_offset_t IOR_GetFileSize_POSIX(IOR_param_t *, MPI_Comm, char *);
/************************** D E C L A R A T I O N S ***************************/ /************************** D E C L A R A T I O N S ***************************/
ior_aiori_t posix_aiori = { ior_aiori_t posix_aiori = {
"POSIX", "POSIX",
IOR_Create_POSIX, IOR_Create_POSIX,
IOR_Open_POSIX, IOR_Open_POSIX,
IOR_Xfer_POSIX, IOR_Xfer_POSIX,
IOR_Close_POSIX, IOR_Close_POSIX,
IOR_Delete_POSIX, IOR_Delete_POSIX,
IOR_SetVersion_POSIX, IOR_SetVersion_POSIX,
IOR_Fsync_POSIX, IOR_Fsync_POSIX,
IOR_GetFileSize_POSIX IOR_GetFileSize_POSIX
}; };
extern int errno; extern int errno;
extern int rank; extern int rank;
extern int rankOffset; extern int rankOffset;
extern int verbose; extern int verbose;
extern MPI_Comm testComm; extern MPI_Comm testComm;
/***************************** F U N C T I O N S ******************************/ /***************************** 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(), /* note that TRU64 needs O_DIRECTIO, SunOS uses directio(),
and everyone else needs O_DIRECT */ and everyone else needs O_DIRECT */
#ifndef O_DIRECT #ifndef O_DIRECT
# ifndef O_DIRECTIO #ifndef O_DIRECTIO
WARN("cannot use O_DIRECT"); WARN("cannot use O_DIRECT");
# define O_DIRECT 000000 #define O_DIRECT 000000
# else /* O_DIRECTIO */ #else /* O_DIRECTIO */
# define O_DIRECT O_DIRECTIO #define O_DIRECT O_DIRECTIO
# endif /* not O_DIRECTIO */ #endif /* not O_DIRECTIO */
#endif /* not O_DIRECT */ #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. * Creat and open a file through the POSIX interface.
*/ */
void * void *IOR_Create_POSIX(char *testFileName, IOR_param_t * param)
IOR_Create_POSIX(char * testFileName,
IOR_param_t * param)
{ {
int fd_oflag = O_BINARY; int fd_oflag = O_BINARY;
int *fd; int *fd;
fd = (int *)malloc(sizeof(int)); fd = (int *)malloc(sizeof(int));
if (fd == NULL) ERR("Unable to malloc file descriptor"); if (fd == NULL)
ERR("Unable to malloc file descriptor");
if (param->useO_DIRECT == TRUE) if (param->useO_DIRECT == TRUE)
set_o_direct_flag(&fd_oflag); set_o_direct_flag(&fd_oflag);
#ifdef HAVE_LUSTRE_LUSTRE_USER_H #ifdef HAVE_LUSTRE_LUSTRE_USER_H
if (param->lustre_set_striping) { if (param->lustre_set_striping) {
/* In the single-shared-file case, task 0 has to creat the /* In the single-shared-file case, task 0 has to creat the
file with the Lustre striping options before any other processes file with the Lustre striping options before any other processes
open the file */ open the file */
if (!param->filePerProc && rank != 0) { if (!param->filePerProc && rank != 0) {
MPI_CHECK(MPI_Barrier(testComm), "barrier error"); MPI_CHECK(MPI_Barrier(testComm), "barrier error");
fd_oflag |= O_RDWR; fd_oflag |= O_RDWR;
*fd = open64(testFileName, fd_oflag, 0664); *fd = open64(testFileName, fd_oflag, 0664);
if (*fd < 0) ERR("open64() failed"); 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 { } else {
struct lov_user_md opts = { 0 }; #endif /* HAVE_LUSTRE_LUSTRE_USER_H */
fd_oflag |= O_CREAT | O_RDWR;
/* Setup Lustre IOCTL striping pattern structure */ *fd = open64(testFileName, fd_oflag, 0664);
opts.lmm_magic = LOV_USER_MAGIC; if (*fd < 0)
opts.lmm_stripe_size = param->lustre_stripe_size; ERR("open64() failed");
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");
#ifdef HAVE_LUSTRE_LUSTRE_USER_H #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); if (param->lustre_ignore_locks) {
} /* IOR_Create_POSIX() */ 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. * Open a file through the POSIX interface.
*/ */
void * void *IOR_Open_POSIX(char *testFileName, IOR_param_t * param)
IOR_Open_POSIX(char * testFileName,
IOR_param_t * param)
{ {
int fd_oflag = O_BINARY; int fd_oflag = O_BINARY;
int *fd; int *fd;
fd = (int *)malloc(sizeof(int)); fd = (int *)malloc(sizeof(int));
if (fd == NULL) ERR("Unable to malloc file descriptor"); if (fd == NULL)
ERR("Unable to malloc file descriptor");
if (param->useO_DIRECT == TRUE) if (param->useO_DIRECT == TRUE)
set_o_direct_flag(&fd_oflag); set_o_direct_flag(&fd_oflag);
fd_oflag |= O_RDWR; fd_oflag |= O_RDWR;
*fd = open64(testFileName, fd_oflag); *fd = open64(testFileName, fd_oflag);
if (*fd < 0) ERR("open64 failed"); if (*fd < 0)
ERR("open64 failed");
#ifdef HAVE_LUSTRE_LUSTRE_USER_H #ifdef HAVE_LUSTRE_LUSTRE_USER_H
if (param->lustre_ignore_locks) { if (param->lustre_ignore_locks) {
int lustre_ioctl_flags = LL_FILE_IGNORE_LOCK; int lustre_ioctl_flags = LL_FILE_IGNORE_LOCK;
if (verbose >= VERBOSE_1) { if (verbose >= VERBOSE_1) {
fprintf(stdout, "** Disabling lustre range locking **\n"); 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) #endif /* HAVE_LUSTRE_LUSTRE_USER_H */
ERR("ioctl(LL_IOC_SETFLAGS) failed");
}
#endif /* HAVE_LUSTRE_LUSTRE_USER_H */
return((void *)fd);
} /* IOR_Open_POSIX() */
return ((void *)fd);
} /* IOR_Open_POSIX() */
/******************************************************************************/ /******************************************************************************/
/* /*
@ -206,123 +210,117 @@ IOR_Open_POSIX(char * testFileName,
*/ */
IOR_offset_t IOR_offset_t
IOR_Xfer_POSIX(int access, IOR_Xfer_POSIX(int access,
void * file, void *file,
IOR_size_t * buffer, IOR_size_t * buffer, IOR_offset_t length, IOR_param_t * param)
IOR_offset_t length,
IOR_param_t * param)
{ {
int xferRetries = 0; int xferRetries = 0;
long long remaining = (long long)length; long long remaining = (long long)length;
char * ptr = (char *)buffer; char *ptr = (char *)buffer;
long long rc; long long rc;
int fd; int fd;
fd = *(int *)file; fd = *(int *)file;
/* seek to offset */ /* seek to offset */
if (lseek64(fd, param->offset, SEEK_SET) == -1) if (lseek64(fd, param->offset, SEEK_SET) == -1)
ERR("lseek64() failed"); ERR("lseek64() failed");
while (remaining > 0) { while (remaining > 0) {
/* write/read file */ /* write/read file */
if (access == WRITE) { /* WRITE */ if (access == WRITE) { /* WRITE */
if (verbose >= VERBOSE_4) { if (verbose >= VERBOSE_4) {
fprintf(stdout, "task %d writing to offset %lld\n", fprintf(stdout,
rank, param->offset + length - remaining); "task %d writing to offset %lld\n",
} rank,
rc = write(fd, ptr, remaining); param->offset + length - remaining);
if (param->fsyncPerWrite == TRUE) }
IOR_Fsync_POSIX(&fd, param); rc = write(fd, ptr, remaining);
if (rc == -1) if (param->fsyncPerWrite == TRUE)
ERR("write() failed"); IOR_Fsync_POSIX(&fd, param);
} else { /* READ or CHECK */ if (rc == -1)
if (verbose >= VERBOSE_4) { ERR("write() failed");
fprintf(stdout, "task %d reading from offset %lld\n", } else { /* READ or CHECK */
rank, param->offset + length - remaining); if (verbose >= VERBOSE_4) {
} fprintf(stdout,
rc = read(fd, ptr, remaining); "task %d reading from offset %lld\n",
if (rc == 0) rank,
ERR("read() returned EOF prematurely"); param->offset + length - remaining);
if (rc == -1) }
ERR("read() failed"); 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) { return (length);
fprintf(stdout, } /* IOR_Xfer_POSIX() */
"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() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Perform fsync(). * Perform fsync().
*/ */
void void IOR_Fsync_POSIX(void *fd, IOR_param_t * param)
IOR_Fsync_POSIX(void * fd, IOR_param_t * param)
{ {
if (fsync(*(int *)fd) != 0) if (fsync(*(int *)fd) != 0)
WARN("fsync() failed"); WARN("fsync() failed");
} /* IOR_Fsync_POSIX() */ } /* IOR_Fsync_POSIX() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Close a file through the POSIX interface. * Close a file through the POSIX interface.
*/ */
void void IOR_Close_POSIX(void *fd, IOR_param_t * param)
IOR_Close_POSIX(void *fd,
IOR_param_t * param)
{ {
if (close(*(int *)fd) != 0) if (close(*(int *)fd) != 0)
ERR("close() failed"); ERR("close() failed");
free(fd); free(fd);
} /* IOR_Close_POSIX() */ } /* IOR_Close_POSIX() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Delete a file through the POSIX interface. * Delete a file through the POSIX interface.
*/ */
void void IOR_Delete_POSIX(char *testFileName, IOR_param_t * param)
IOR_Delete_POSIX(char * testFileName, IOR_param_t * param)
{ {
char errmsg[256]; char errmsg[256];
sprintf(errmsg,"[RANK %03d]: unlink() of file \"%s\" failed\n", sprintf(errmsg, "[RANK %03d]: unlink() of file \"%s\" failed\n",
rank, testFileName); rank, testFileName);
if (unlink(testFileName) != 0) WARN(errmsg); if (unlink(testFileName) != 0)
} /* IOR_Delete_POSIX() */ WARN(errmsg);
} /* IOR_Delete_POSIX() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Determine api version. * Determine api version.
*/ */
void void IOR_SetVersion_POSIX(IOR_param_t * test)
IOR_SetVersion_POSIX(IOR_param_t *test)
{ {
strcpy(test->apiVersion, test->api); strcpy(test->apiVersion, test->api);
} /* IOR_SetVersion_POSIX() */ } /* IOR_SetVersion_POSIX() */
/******************************************************************************/ /******************************************************************************/
/* /*
@ -330,39 +328,36 @@ IOR_SetVersion_POSIX(IOR_param_t *test)
*/ */
IOR_offset_t IOR_offset_t
IOR_GetFileSize_POSIX(IOR_param_t * test, IOR_GetFileSize_POSIX(IOR_param_t * test, MPI_Comm testComm, char *testFileName)
MPI_Comm testComm,
char * testFileName)
{ {
struct stat stat_buf; struct stat stat_buf;
IOR_offset_t aggFileSizeFromStat, IOR_offset_t aggFileSizeFromStat, tmpMin, tmpMax, tmpSum;
tmpMin, tmpMax, tmpSum;
if (stat(testFileName, &stat_buf) != 0) { if (stat(testFileName, &stat_buf) != 0) {
ERR("stat() failed"); 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;
} }
} aggFileSizeFromStat = stat_buf.st_size;
return(aggFileSizeFromStat); if (test->filePerProc == TRUE) {
} /* IOR_GetFileSize_POSIX() */ 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() */

4411
src/ior.c

File diff suppressed because it is too large Load Diff

View File

@ -23,211 +23,211 @@ IOR_param_t initialTestParams;
* Check and correct all settings of each test in queue for correctness. * Check and correct all settings of each test in queue for correctness.
*/ */
void CheckRunSettings(IOR_queue_t *tests) { void CheckRunSettings(IOR_queue_t * tests)
while (tests != NULL) { {
/* If no write/read/check action requested, set both write and read */ while (tests != NULL) {
if (tests->testParameters.writeFile == FALSE /* If no write/read/check action requested, set both write and read */
&& tests->testParameters.readFile == FALSE if (tests->testParameters.writeFile == FALSE
&& tests->testParameters.checkWrite == FALSE && tests->testParameters.readFile == FALSE
&& tests->testParameters.checkRead == FALSE) { && tests->testParameters.checkWrite == FALSE
tests->testParameters.readFile = TRUE; && tests->testParameters.checkRead == FALSE) {
tests->testParameters.writeFile = TRUE; 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 */ } /* CheckRunSettings() */
if (tests->testParameters.numTasks == 0) {
MPI_CHECK(MPI_Comm_size(MPI_COMM_WORLD,
&tests->testParameters.numTasks),
"MPI_Comm_size() error");
}
tests = tests->nextTest;
}
} /* CheckRunSettings() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Set flags from commandline string/value pairs. * 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 option[MAX_STR];
char value[MAX_STR]; char value[MAX_STR];
int rc; int rc;
rc = sscanf(line, " %[^=# \t\r\n] = %[^# \t\r\n] ", option, value); rc = sscanf(line, " %[^=# \t\r\n] = %[^# \t\r\n] ", option, value);
if (rc != 2 && rank == 0) { if (rc != 2 && rank == 0) {
fprintf(stdout, "Syntax error in configuration options: %s\n", line); fprintf(stdout, "Syntax error in configuration options: %s\n",
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); line);
} MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
if (strcasecmp(option, "api") == 0) { }
strcpy(test->api, value); if (strcasecmp(option, "api") == 0) {
} else if (strcasecmp(option, "testnum") == 0) { strcpy(test->api, value);
test->TestNum = atoi(value); } else if (strcasecmp(option, "testnum") == 0) {
} else if (strcasecmp(option, "debug") == 0) { test->TestNum = atoi(value);
strcpy(test->debug, value); } else if (strcasecmp(option, "debug") == 0) {
} else if (strcasecmp(option, "platform") == 0) { strcpy(test->debug, value);
strcpy(test->platform, value); } else if (strcasecmp(option, "platform") == 0) {
} else if (strcasecmp(option, "testfile") == 0) { strcpy(test->platform, value);
strcpy(test->testFileName, value); } else if (strcasecmp(option, "testfile") == 0) {
} else if (strcasecmp(option, "hintsfilename") == 0) { strcpy(test->testFileName, value);
strcpy(test->hintsFileName, value); } else if (strcasecmp(option, "hintsfilename") == 0) {
} else if (strcasecmp(option, "deadlineforstonewalling") == 0) { strcpy(test->hintsFileName, value);
test->deadlineForStonewalling = atoi(value); } else if (strcasecmp(option, "deadlineforstonewalling") == 0) {
} else if (strcasecmp(option, "maxtimeduration") == 0) { test->deadlineForStonewalling = atoi(value);
test->maxTimeDuration = atoi(value); } else if (strcasecmp(option, "maxtimeduration") == 0) {
} else if (strcasecmp(option, "outlierthreshold") == 0) { test->maxTimeDuration = atoi(value);
test->outlierThreshold = atoi(value); } else if (strcasecmp(option, "outlierthreshold") == 0) {
} else if (strcasecmp(option, "nodes") == 0) { test->outlierThreshold = atoi(value);
test->nodes = atoi(value); } else if (strcasecmp(option, "nodes") == 0) {
} else if (strcasecmp(option, "repetitions") == 0) { test->nodes = atoi(value);
test->repetitions = atoi(value); } else if (strcasecmp(option, "repetitions") == 0) {
} else if (strcasecmp(option, "intertestdelay") == 0) { test->repetitions = atoi(value);
test->interTestDelay = atoi(value); } else if (strcasecmp(option, "intertestdelay") == 0) {
} else if (strcasecmp(option, "readfile") == 0) { test->interTestDelay = atoi(value);
test->readFile = atoi(value); } else if (strcasecmp(option, "readfile") == 0) {
} else if (strcasecmp(option, "writefile") == 0) { test->readFile = atoi(value);
test->writeFile = atoi(value); } else if (strcasecmp(option, "writefile") == 0) {
} else if (strcasecmp(option, "fileperproc") == 0) { test->writeFile = atoi(value);
test->filePerProc = atoi(value); } else if (strcasecmp(option, "fileperproc") == 0) {
} else if (strcasecmp(option, "reordertasksconstant") == 0) { test->filePerProc = atoi(value);
test->reorderTasks = atoi(value); } else if (strcasecmp(option, "reordertasksconstant") == 0) {
} else if (strcasecmp(option, "taskpernodeoffset") == 0) { test->reorderTasks = atoi(value);
test->taskPerNodeOffset = atoi(value); } else if (strcasecmp(option, "taskpernodeoffset") == 0) {
} else if (strcasecmp(option, "reordertasksrandom") == 0) { test->taskPerNodeOffset = atoi(value);
test->reorderTasksRandom = atoi(value); } else if (strcasecmp(option, "reordertasksrandom") == 0) {
} else if (strcasecmp(option, "reordertasksrandomSeed") == 0) { test->reorderTasksRandom = atoi(value);
test->reorderTasksRandomSeed = atoi(value); } else if (strcasecmp(option, "reordertasksrandomSeed") == 0) {
} else if (strcasecmp(option, "checkwrite") == 0) { test->reorderTasksRandomSeed = atoi(value);
test->checkWrite = atoi(value); } else if (strcasecmp(option, "checkwrite") == 0) {
} else if (strcasecmp(option, "checkread") == 0) { test->checkWrite = atoi(value);
test->checkRead = atoi(value); } else if (strcasecmp(option, "checkread") == 0) {
} else if (strcasecmp(option, "keepfile") == 0) { test->checkRead = atoi(value);
test->keepFile = atoi(value); } else if (strcasecmp(option, "keepfile") == 0) {
} else if (strcasecmp(option, "keepfilewitherror") == 0) { test->keepFile = atoi(value);
test->keepFileWithError = atoi(value); } else if (strcasecmp(option, "keepfilewitherror") == 0) {
} else if (strcasecmp(option, "multiFile") == 0) { test->keepFileWithError = atoi(value);
test->multiFile = atoi(value); } else if (strcasecmp(option, "multiFile") == 0) {
} else if (strcasecmp(option, "quitonerror") == 0) { test->multiFile = atoi(value);
test->quitOnError = atoi(value); } else if (strcasecmp(option, "quitonerror") == 0) {
} else if (strcasecmp(option, "segmentcount") == 0) { test->quitOnError = atoi(value);
test->segmentCount = StringToBytes(value); } else if (strcasecmp(option, "segmentcount") == 0) {
} else if (strcasecmp(option, "blocksize") == 0) { test->segmentCount = StringToBytes(value);
test->blockSize = StringToBytes(value); } else if (strcasecmp(option, "blocksize") == 0) {
} else if (strcasecmp(option, "transfersize") == 0) { test->blockSize = StringToBytes(value);
test->transferSize = StringToBytes(value); } else if (strcasecmp(option, "transfersize") == 0) {
} else if (strcasecmp(option, "setalignment") == 0) { test->transferSize = StringToBytes(value);
test->setAlignment = StringToBytes(value); } else if (strcasecmp(option, "setalignment") == 0) {
} else if (strcasecmp(option, "singlexferattempt") == 0) { test->setAlignment = StringToBytes(value);
test->singleXferAttempt = atoi(value); } else if (strcasecmp(option, "singlexferattempt") == 0) {
} else if (strcasecmp(option, "individualdatasets") == 0) { test->singleXferAttempt = atoi(value);
test->individualDataSets = atoi(value); } else if (strcasecmp(option, "individualdatasets") == 0) {
} else if (strcasecmp(option, "intraTestBarriers") == 0) { test->individualDataSets = atoi(value);
test->intraTestBarriers = atoi(value); } else if (strcasecmp(option, "intraTestBarriers") == 0) {
} else if (strcasecmp(option, "nofill") == 0) { test->intraTestBarriers = atoi(value);
test->noFill = atoi(value); } else if (strcasecmp(option, "nofill") == 0) {
} else if (strcasecmp(option, "verbose") == 0) { test->noFill = atoi(value);
test->verbose = atoi(value); } else if (strcasecmp(option, "verbose") == 0) {
} else if (strcasecmp(option, "settimestampsignature") == 0) { test->verbose = atoi(value);
test->setTimeStampSignature = atoi(value); } else if (strcasecmp(option, "settimestampsignature") == 0) {
} else if (strcasecmp(option, "collective") == 0) { test->setTimeStampSignature = atoi(value);
test->collective = atoi(value); } else if (strcasecmp(option, "collective") == 0) {
} else if (strcasecmp(option, "preallocate") == 0) { test->collective = atoi(value);
test->preallocate = atoi(value); } else if (strcasecmp(option, "preallocate") == 0) {
} else if (strcasecmp(option, "storefileoffset") == 0) { test->preallocate = atoi(value);
test->storeFileOffset = atoi(value); } else if (strcasecmp(option, "storefileoffset") == 0) {
} else if (strcasecmp(option, "usefileview") == 0) { test->storeFileOffset = atoi(value);
test->useFileView = atoi(value); } else if (strcasecmp(option, "usefileview") == 0) {
} else if (strcasecmp(option, "usesharedfilepointer") == 0) { test->useFileView = atoi(value);
test->useSharedFilePointer = atoi(value); } else if (strcasecmp(option, "usesharedfilepointer") == 0) {
} else if (strcasecmp(option, "useo_direct") == 0) { test->useSharedFilePointer = atoi(value);
test->useO_DIRECT = atoi(value); } else if (strcasecmp(option, "useo_direct") == 0) {
} else if (strcasecmp(option, "usestrideddatatype") == 0) { test->useO_DIRECT = atoi(value);
test->useStridedDatatype = atoi(value); } else if (strcasecmp(option, "usestrideddatatype") == 0) {
} else if (strcasecmp(option, "showhints") == 0) { test->useStridedDatatype = atoi(value);
test->showHints = atoi(value); } else if (strcasecmp(option, "showhints") == 0) {
} else if (strcasecmp(option, "showhelp") == 0) { test->showHints = atoi(value);
test->showHelp = atoi(value); } else if (strcasecmp(option, "showhelp") == 0) {
} else if (strcasecmp(option, "uniqueDir") == 0) { test->showHelp = atoi(value);
test->uniqueDir = atoi(value); } else if (strcasecmp(option, "uniqueDir") == 0) {
} else if (strcasecmp(option, "useexistingtestfile") == 0) { test->uniqueDir = atoi(value);
test->useExistingTestFile = atoi(value); } else if (strcasecmp(option, "useexistingtestfile") == 0) {
} else if (strcasecmp(option, "fsyncperwrite") == 0) { test->useExistingTestFile = atoi(value);
test->fsyncPerWrite = atoi(value); } else if (strcasecmp(option, "fsyncperwrite") == 0) {
} else if (strcasecmp(option, "fsync") == 0) { test->fsyncPerWrite = atoi(value);
test->fsync = atoi(value); } else if (strcasecmp(option, "fsync") == 0) {
} else if (strcasecmp(option, "randomoffset") == 0) { test->fsync = atoi(value);
test->randomOffset = atoi(value); } else if (strcasecmp(option, "randomoffset") == 0) {
} else if (strcasecmp(option, "lustrestripecount") == 0) { test->randomOffset = atoi(value);
} else if (strcasecmp(option, "lustrestripecount") == 0) {
#ifndef HAVE_LUSTRE_LUSTRE_USER_H #ifndef HAVE_LUSTRE_LUSTRE_USER_H
ERR("ior was not compiled with Lustre support"); ERR("ior was not compiled with Lustre support");
#endif #endif
test->lustre_stripe_count = atoi(value); test->lustre_stripe_count = atoi(value);
test->lustre_set_striping = 1; test->lustre_set_striping = 1;
} else if (strcasecmp(option, "lustrestripesize") == 0) { } else if (strcasecmp(option, "lustrestripesize") == 0) {
#ifndef HAVE_LUSTRE_LUSTRE_USER_H #ifndef HAVE_LUSTRE_LUSTRE_USER_H
ERR("ior was not compiled with Lustre support"); ERR("ior was not compiled with Lustre support");
#endif #endif
test->lustre_stripe_size = StringToBytes(value); test->lustre_stripe_size = StringToBytes(value);
test->lustre_set_striping = 1; test->lustre_set_striping = 1;
} else if (strcasecmp(option, "lustrestartost") == 0) { } else if (strcasecmp(option, "lustrestartost") == 0) {
#ifndef HAVE_LUSTRE_LUSTRE_USER_H #ifndef HAVE_LUSTRE_LUSTRE_USER_H
ERR("ior was not compiled with Lustre support"); ERR("ior was not compiled with Lustre support");
#endif #endif
test->lustre_start_ost = atoi(value); test->lustre_start_ost = atoi(value);
test->lustre_set_striping = 1; test->lustre_set_striping = 1;
} else if (strcasecmp(option, "lustreignorelocks") == 0) { } else if (strcasecmp(option, "lustreignorelocks") == 0) {
#ifndef HAVE_LUSTRE_LUSTRE_USER_H #ifndef HAVE_LUSTRE_LUSTRE_USER_H
ERR("ior was not compiled with Lustre support"); ERR("ior was not compiled with Lustre support");
#endif #endif
test->lustre_ignore_locks = atoi(value); test->lustre_ignore_locks = atoi(value);
#if USE_UNDOC_OPT #if USE_UNDOC_OPT
} else if (strcasecmp(option, "corruptFile") == 0) { } else if (strcasecmp(option, "corruptFile") == 0) {
test->corruptFile = atoi(value); test->corruptFile = atoi(value);
} else if (strcasecmp(option, "fillTheFileSystem") == 0) { } else if (strcasecmp(option, "fillTheFileSystem") == 0) {
test->fillTheFileSystem = atoi(value); test->fillTheFileSystem = atoi(value);
} else if (strcasecmp(option, "includeDeleteTime") == 0) { } else if (strcasecmp(option, "includeDeleteTime") == 0) {
test->includeDeleteTime = atoi(value); test->includeDeleteTime = atoi(value);
} else if (strcasecmp(option, "multiReRead") == 0) { } else if (strcasecmp(option, "multiReRead") == 0) {
test->multiReRead = atoi(value); test->multiReRead = atoi(value);
} else if (strcasecmp(option, "nfs_rootpath") == 0) { } else if (strcasecmp(option, "nfs_rootpath") == 0) {
strcpy(test->NFS_rootPath, value); strcpy(test->NFS_rootPath, value);
} else if (strcasecmp(option, "nfs_servername") == 0) { } else if (strcasecmp(option, "nfs_servername") == 0) {
strcpy(test->NFS_serverName, value); strcpy(test->NFS_serverName, value);
} else if (strcasecmp(option, "nfs_servercount") == 0) { } else if (strcasecmp(option, "nfs_servercount") == 0) {
test->NFS_serverCount = atoi(value); test->NFS_serverCount = atoi(value);
#endif /* USE_UNDOC_OPT */ #endif /* USE_UNDOC_OPT */
} else if (strcasecmp(option, "numtasks") == 0) { } else if (strcasecmp(option, "numtasks") == 0) {
test->numTasks = atoi(value); test->numTasks = atoi(value);
} else { } else {
if (rank == 0) if (rank == 0)
fprintf(stdout, "Unrecognized parameter \"%s\"\n", option); fprintf(stdout, "Unrecognized parameter \"%s\"\n",
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error"); option);
} MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
} /* DecodeDirective() */ }
} /* DecodeDirective() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Parse a single line, which may contain multiple comma-seperated directives * Parse a single line, which may contain multiple comma-seperated directives
*/ */
void void ParseLine(char *line, IOR_param_t * test)
ParseLine(char *line, IOR_param_t *test)
{ {
char *start, *end; char *start, *end;
start = line; start = line;
do { do {
end = strchr(start, ','); end = strchr(start, ',');
if (end != NULL) if (end != NULL)
*end = '\0'; *end = '\0';
DecodeDirective(start, test); DecodeDirective(start, test);
start = end + 1; start = end + 1;
} while (end != NULL); } while (end != NULL);
} /* ParseLine() */
} /* ParseLine() */
/******************************************************************************/ /******************************************************************************/
/* /*
@ -235,29 +235,27 @@ ParseLine(char *line, IOR_param_t *test)
* possibly whitespace before and after needle. Function is case insensitive. * possibly whitespace before and after needle. Function is case insensitive.
*/ */
int int contains_only(char *haystack, char *needle)
contains_only(char *haystack, char *needle)
{ {
char *ptr, *end; char *ptr, *end;
end = haystack + strlen(haystack); end = haystack + strlen(haystack);
/* skip over leading shitspace */ /* skip over leading shitspace */
for (ptr = haystack; ptr < end; ptr++) { for (ptr = haystack; ptr < end; ptr++) {
if (!isspace(*ptr)) if (!isspace(*ptr))
break; break;
} }
/* check for "needle" */ /* check for "needle" */
if (strncasecmp(ptr, needle, strlen(needle)) != 0) if (strncasecmp(ptr, needle, strlen(needle)) != 0)
return 0; return 0;
/* make sure the rest of the line is only whitspace as well */ /* make sure the rest of the line is only whitspace as well */
for (ptr += strlen(needle); ptr < end; ptr++) { for (ptr += strlen(needle); ptr < end; ptr++) {
if (!isspace(*ptr)) if (!isspace(*ptr))
return 0; return 0;
} }
return 1;
} /* contains_only() */
return 1;
} /* contains_only() */
/******************************************************************************/ /******************************************************************************/
/* /*
@ -265,169 +263,262 @@ contains_only(char *haystack, char *needle)
* global parameters. * global parameters.
*/ */
IOR_queue_t * IOR_queue_t *ReadConfigScript(char *scriptName)
ReadConfigScript(char * scriptName)
{ {
int test_num = 0; int test_num = 0;
int runflag = 0; int runflag = 0;
char linebuf[MAX_STR]; char linebuf[MAX_STR];
char empty[MAX_STR]; char empty[MAX_STR];
FILE *file; FILE *file;
IOR_queue_t *head = NULL; IOR_queue_t *head = NULL;
IOR_queue_t *tail = NULL; IOR_queue_t *tail = NULL;
IOR_queue_t *newTest = NULL; IOR_queue_t *newTest = NULL;
/* Initialize the first test */ /* Initialize the first test */
head = CreateNewTest(test_num++); head = CreateNewTest(test_num++);
tail = head; tail = head;
/* open the script */ /* open the script */
file = fopen(scriptName, "r"); file = fopen(scriptName, "r");
if (file == NULL) if (file == NULL)
ERR("fopen() failed"); ERR("fopen() failed");
/* search for the "IOR START" line */ /* search for the "IOR START" line */
while(fgets(linebuf, MAX_STR, file) != NULL) { while (fgets(linebuf, MAX_STR, file) != NULL) {
if (contains_only(linebuf, "ior start")) { if (contains_only(linebuf, "ior start")) {
break; break;
}
} }
}
/* Iterate over a block of IOR commands */ /* Iterate over a block of IOR commands */
while(fgets(linebuf, MAX_STR, file) != NULL) { while (fgets(linebuf, MAX_STR, file) != NULL) {
/* skip empty lines */ /* skip empty lines */
if (sscanf(linebuf, "%s", empty) == -1) if (sscanf(linebuf, "%s", empty) == -1)
continue; continue;
/* skip lines containing only comments */ /* skip lines containing only comments */
if (sscanf(linebuf, " #%s", empty) == 1) if (sscanf(linebuf, " #%s", empty) == 1)
continue; continue;
if (contains_only(linebuf, "ior stop")) { if (contains_only(linebuf, "ior stop")) {
break; break;
} else if (contains_only(linebuf, "run")) { } else if (contains_only(linebuf, "run")) {
runflag = 1; runflag = 1;
} else { } else {
/* If this directive was preceded by a "run" line, then /* If this directive was preceded by a "run" line, then
create and initialize a new test structure */ create and initialize a new test structure */
if (runflag) { if (runflag) {
newTest = (IOR_queue_t *)malloc(sizeof(IOR_queue_t)); newTest =
if (newTest == NULL) (IOR_queue_t *) malloc(sizeof(IOR_queue_t));
ERR("malloc() failed"); if (newTest == NULL)
newTest->testParameters = tail->testParameters; ERR("malloc() failed");
newTest->testParameters.id = test_num++; newTest->testParameters = tail->testParameters;
tail->nextTest = newTest; newTest->testParameters.id = test_num++;
tail = newTest; tail->nextTest = newTest;
tail->nextTest = NULL; tail = newTest;
runflag = 0; tail->nextTest = NULL;
} runflag = 0;
ParseLine(linebuf, &tail->testParameters); }
ParseLine(linebuf, &tail->testParameters);
}
} }
}
/* close the script */ /* close the script */
if (fclose(file) != 0) if (fclose(file) != 0)
ERR("fclose() of script file failed"); ERR("fclose() of script file failed");
return(head); return (head);
} /* ReadConfigScript() */ } /* ReadConfigScript() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Parse Commandline. * Parse Commandline.
*/ */
IOR_queue_t * IOR_queue_t *ParseCommandLine(int argc, char **argv)
ParseCommandLine(int argc, char ** argv)
{ {
static const char * opts 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; "A:a:b:BcCQ:ZX:d:D:YeEf:FgG:hHi:j:J:IkKlmnN:o:O:pPqrRs:St:T:uU:vVwWxz";
static IOR_queue_t *tests = NULL; int c, i;
static IOR_queue_t *tests = NULL;
/* suppress getopt() error message when a character is unrecognized */ /* suppress getopt() error message when a character is unrecognized */
opterr = 0; opterr = 0;
init_IOR_Param_t(&initialTestParams); init_IOR_Param_t(&initialTestParams);
GetPlatformName(initialTestParams.platform); GetPlatformName(initialTestParams.platform);
initialTestParams.writeFile = initialTestParams.readFile = FALSE; initialTestParams.writeFile = initialTestParams.readFile = FALSE;
initialTestParams.checkWrite = initialTestParams.checkRead = FALSE; initialTestParams.checkWrite = initialTestParams.checkRead = FALSE;
while ((c = getopt(argc, argv, opts)) != -1) { while ((c = getopt(argc, argv, opts)) != -1) {
switch (c) { switch (c) {
case 'A': initialTestParams.TestNum = atoi(optarg); break; case 'A':
case 'a': strcpy(initialTestParams.api, optarg); break; initialTestParams.TestNum = atoi(optarg);
case 'b': initialTestParams.blockSize = break;
StringToBytes(optarg); break; case 'a':
case 'B': initialTestParams.useO_DIRECT = TRUE; break; strcpy(initialTestParams.api, optarg);
case 'c': initialTestParams.collective = TRUE; break; break;
case 'C': initialTestParams.reorderTasks = TRUE; break; case 'b':
case 'Q': initialTestParams.taskPerNodeOffset = initialTestParams.blockSize = StringToBytes(optarg);
atoi(optarg); break; break;
case 'Z': initialTestParams.reorderTasksRandom = TRUE; break; case 'B':
case 'X': initialTestParams.reorderTasksRandomSeed = initialTestParams.useO_DIRECT = TRUE;
atoi(optarg); break; break;
case 'd': initialTestParams.interTestDelay = atoi(optarg); break; case 'c':
case 'D': initialTestParams.deadlineForStonewalling = initialTestParams.collective = TRUE;
atoi(optarg); break; break;
case 'Y': initialTestParams.fsyncPerWrite = TRUE; break; case 'C':
case 'e': initialTestParams.fsync = TRUE; break; initialTestParams.reorderTasks = TRUE;
case 'E': initialTestParams.useExistingTestFile = TRUE; break; break;
case 'f': tests = ReadConfigScript(optarg); break; case 'Q':
case 'F': initialTestParams.filePerProc = TRUE; break; initialTestParams.taskPerNodeOffset = atoi(optarg);
case 'g': initialTestParams.intraTestBarriers = TRUE; break; break;
case 'G': initialTestParams.setTimeStampSignature = case 'Z':
atoi(optarg); break; initialTestParams.reorderTasksRandom = TRUE;
case 'h': initialTestParams.showHelp = TRUE; break; break;
case 'H': initialTestParams.showHints = TRUE; break; case 'X':
case 'i': initialTestParams.repetitions = atoi(optarg); break; initialTestParams.reorderTasksRandomSeed = atoi(optarg);
case 'I': initialTestParams.individualDataSets = TRUE; break; break;
case 'j': initialTestParams.outlierThreshold = case 'd':
atoi(optarg); break; initialTestParams.interTestDelay = atoi(optarg);
case 'J': initialTestParams.setAlignment = break;
StringToBytes(optarg); break; case 'D':
case 'k': initialTestParams.keepFile = TRUE; break; initialTestParams.deadlineForStonewalling =
case 'K': initialTestParams.keepFileWithError = TRUE; break; atoi(optarg);
case 'l': initialTestParams.storeFileOffset = TRUE; break; break;
case 'm': initialTestParams.multiFile = TRUE; break; case 'Y':
case 'n': initialTestParams.noFill = TRUE; break; initialTestParams.fsyncPerWrite = TRUE;
case 'N': initialTestParams.numTasks = atoi(optarg); break; break;
case 'o': strcpy(initialTestParams.testFileName, optarg); break; case 'e':
case 'O': ParseLine(optarg, &initialTestParams); break; initialTestParams.fsync = TRUE;
case 'p': initialTestParams.preallocate = TRUE; break; break;
case 'P': initialTestParams.useSharedFilePointer = TRUE; break; case 'E':
case 'q': initialTestParams.quitOnError = TRUE; break; initialTestParams.useExistingTestFile = TRUE;
case 'r': initialTestParams.readFile = TRUE; break; break;
case 'R': initialTestParams.checkRead = TRUE; break; case 'f':
case 's': initialTestParams.segmentCount = atoi(optarg); break; tests = ReadConfigScript(optarg);
case 'S': initialTestParams.useStridedDatatype = TRUE; break; break;
case 't': initialTestParams.transferSize = case 'F':
StringToBytes(optarg); break; initialTestParams.filePerProc = TRUE;
case 'T': initialTestParams.maxTimeDuration = atoi(optarg);break; break;
case 'u': initialTestParams.uniqueDir = TRUE; break; case 'g':
case 'U': strcpy(initialTestParams.hintsFileName, optarg); break; initialTestParams.intraTestBarriers = TRUE;
case 'v': initialTestParams.verbose++; break; break;
case 'V': initialTestParams.useFileView = TRUE; break; case 'G':
case 'w': initialTestParams.writeFile = TRUE; break; initialTestParams.setTimeStampSignature = atoi(optarg);
case 'W': initialTestParams.checkWrite = TRUE; break; break;
case 'x': initialTestParams.singleXferAttempt = TRUE; break; case 'h':
case 'z': initialTestParams.randomOffset = TRUE; break; initialTestParams.showHelp = TRUE;
default: fprintf (stdout, "ParseCommandLine: unknown option `-%c'.\n", optopt); 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++) for (i = optind; i < argc; i++)
fprintf (stdout, "non-option argument: %s\n", argv[i]); fprintf(stdout, "non-option argument: %s\n", argv[i]);
/* If an IOR script was not used, initialize test queue to the defaults */ /* If an IOR script was not used, initialize test queue to the defaults */
if (tests == NULL) { if (tests == NULL) {
tests = (IOR_queue_t *) malloc (sizeof(IOR_queue_t)); tests = (IOR_queue_t *) malloc(sizeof(IOR_queue_t));
if (!tests) if (!tests)
ERR("malloc() failed"); ERR("malloc() failed");
tests->testParameters = initialTestParams; tests->testParameters = initialTestParams;
tests->nextTest = NULL; tests->nextTest = NULL;
} }
CheckRunSettings(tests); CheckRunSettings(tests);
return(tests);
} /* ParseCommandLine() */
return (tests);
} /* ParseCommandLine() */

View File

@ -9,35 +9,32 @@
* *
\******************************************************************************/ \******************************************************************************/
#include "aiori.h" /* abstract IOR interface */ #include "aiori.h" /* abstract IOR interface */
#include "ior.h" /* IOR functions */ #include "ior.h" /* IOR functions */
#include <errno.h> /* sys_errlist */ #include <errno.h> /* sys_errlist */
#include <fcntl.h> /* open() */ #include <fcntl.h> /* open() */
#include <math.h> /* pow() */ #include <math.h> /* pow() */
#include <stdio.h> /* only for fprintf() */ #include <stdio.h> /* only for fprintf() */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <time.h> #include <time.h>
#ifndef _WIN32 #ifndef _WIN32
# include <regex.h> #include <regex.h>
# ifdef __sun /* SunOS does not support statfs(), instead uses statvfs() */ #ifdef __sun /* SunOS does not support statfs(), instead uses statvfs() */
# include <sys/statvfs.h> #include <sys/statvfs.h>
# else /* !__sun */ #else /* !__sun */
# include <sys/statfs.h> #include <sys/statfs.h>
# endif /* __sun */ #endif /* __sun */
# include <sys/time.h> /* gettimeofday() */ #include <sys/time.h> /* gettimeofday() */
#endif #endif
/************************** D E C L A R A T I O N S ***************************/ /************************** D E C L A R A T I O N S ***************************/
extern int errno, /* error number */ extern int errno, /* error number */
numTasks, /* MPI variables */ numTasks, /* MPI variables */
rank, rank, rankOffset, verbose; /* verbose output */
rankOffset,
verbose; /* verbose output */
/***************************** F U N C T I O N S ******************************/ /***************************** F U N C T I O N S ******************************/
@ -46,207 +43,201 @@ extern int errno, /* error number */
* Returns string containing the current time. * Returns string containing the current time.
*/ */
char * char *CurrentTimeString(void)
CurrentTimeString(void)
{ {
static time_t currentTime; static time_t currentTime;
char * currentTimePtr; char *currentTimePtr;
if ((currentTime = time(NULL)) == -1) ERR("cannot get current time");
if ((currentTimePtr = ctime(&currentTime)) == NULL) {
ERR("cannot read current time");
}
/* ctime string ends in \n */
return (currentTimePtr);
} /* CurrentTimeString() */
if ((currentTime = time(NULL)) == -1)
ERR("cannot get current time");
if ((currentTimePtr = ctime(&currentTime)) == NULL) {
ERR("cannot read current time");
}
/* ctime string ends in \n */
return (currentTimePtr);
} /* CurrentTimeString() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Dump transfer buffer. * Dump transfer buffer.
*/ */
void void DumpBuffer(void *buffer, size_t size)
DumpBuffer(void *buffer,
size_t size)
{ {
size_t i, j; size_t i, j;
unsigned long long *dumpBuf = (unsigned long long *)buffer; unsigned long long *dumpBuf = (unsigned long long *)buffer;
for (i = 0; i < ((size/sizeof(IOR_size_t))/4); i++) { for (i = 0; i < ((size / sizeof(IOR_size_t)) / 4); i++) {
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
fprintf(stdout, "%016llx ", dumpBuf[4*i+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. * Sends all strings to root nodes and displays.
*/ */
void void OutputToRoot(int numTasks, MPI_Comm comm, char *stringToDisplay)
OutputToRoot(int numTasks, MPI_Comm comm, char * stringToDisplay)
{ {
int i; int i;
int swapNeeded = TRUE; int swapNeeded = TRUE;
int pairsToSwap; int pairsToSwap;
char ** stringArray; char **stringArray;
char tmpString[MAX_STR]; char tmpString[MAX_STR];
MPI_Status status; MPI_Status status;
/* malloc string array */ /* malloc string array */
stringArray = (char **)malloc(sizeof(char *) * numTasks); stringArray = (char **)malloc(sizeof(char *) * numTasks);
if (stringArray == NULL) ERR("out of memory"); if (stringArray == NULL)
for (i = 0; i < numTasks; i++) { ERR("out of memory");
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) {
for (i = 0; i < numTasks; i++) { 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 */ strcpy(stringArray[rank], stringToDisplay);
for (i = 0; i < numTasks; i++) {
free(stringArray[i]);
}
free(stringArray);
} /* OutputToRoot() */
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. * Set hints for MPIIO, HDF5, or NCMPI.
*/ */
void void SetHints(MPI_Info * mpiHints, char *hintsFileName)
SetHints(MPI_Info * mpiHints, char * hintsFileName)
{ {
char hintString[MAX_STR], char hintString[MAX_STR], settingVal[MAX_STR], valueVal[MAX_STR];
settingVal[MAX_STR], extern char **environ;
valueVal[MAX_STR]; int i;
extern char ** environ; FILE *fd;
int i;
FILE * fd;
/* /*
* This routine checks for hints from the environment and/or from the * This routine checks for hints from the environment and/or from the
* hints files. The hints are of the form: * hints files. The hints are of the form:
* 'IOR_HINT__<layer>__<hint>=<value>', where <layer> is either 'MPI' * 'IOR_HINT__<layer>__<hint>=<value>', where <layer> is either 'MPI'
* or 'GPFS', <hint> is the full name of the hint to be set, and <value> * or 'GPFS', <hint> is the full name of the hint to be set, and <value>
* is the hint value. E.g., 'setenv IOR_HINT__MPI__IBM_largeblock_io true' * is the hint value. E.g., 'setenv IOR_HINT__MPI__IBM_largeblock_io true'
* or 'IOR_HINT__GPFS__hint=value' in the hints file. * or 'IOR_HINT__GPFS__hint=value' in the hints file.
*/ */
MPI_CHECK(MPI_Info_create(mpiHints), "cannot create info object"); MPI_CHECK(MPI_Info_create(mpiHints), "cannot create info object");
/* get hints from environment */ /* get hints from environment */
for (i = 0; environ[i] != NULL; i++) { for (i = 0; environ[i] != NULL; i++) {
/* if this is an IOR_HINT, pass the hint to the info object */ /* if this is an IOR_HINT, pass the hint to the info object */
if (strncmp(environ[i], "IOR_HINT", strlen("IOR_HINT")) == 0) { if (strncmp(environ[i], "IOR_HINT", strlen("IOR_HINT")) == 0) {
strcpy(hintString, environ[i]); strcpy(hintString, environ[i]);
ExtractHint(settingVal, valueVal, hintString); ExtractHint(settingVal, valueVal, hintString);
MPI_CHECK(MPI_Info_set(*mpiHints, settingVal, valueVal), MPI_CHECK(MPI_Info_set(*mpiHints, settingVal, valueVal),
"cannot set info object"); "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");
} }
}
/* 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. * Extract key/value pair from hint string.
*/ */
void void ExtractHint(char *settingVal, char *valueVal, char *hintString)
ExtractHint(char * settingVal,
char * valueVal,
char * hintString)
{ {
char * settingPtr, char *settingPtr, *valuePtr, *tmpPtr1, *tmpPtr2;
* valuePtr,
* tmpPtr1,
* tmpPtr2;
settingPtr = (char *)strtok(hintString, "="); settingPtr = (char *)strtok(hintString, "=");
valuePtr = (char *)strtok(NULL, " \t\r\n"); valuePtr = (char *)strtok(NULL, " \t\r\n");
tmpPtr1 = settingPtr; tmpPtr1 = settingPtr;
tmpPtr2 = (char *)strstr(settingPtr, "IOR_HINT__MPI__"); tmpPtr2 = (char *)strstr(settingPtr, "IOR_HINT__MPI__");
if (tmpPtr1 == tmpPtr2) {
settingPtr += strlen("IOR_HINT__MPI__");
} else {
tmpPtr2 = (char *)strstr(settingPtr, "IOR_HINT__GPFS__");
if (tmpPtr1 == tmpPtr2) { if (tmpPtr1 == tmpPtr2) {
settingPtr += strlen("IOR_HINT__GPFS__"); settingPtr += strlen("IOR_HINT__MPI__");
fprintf(stdout,
"WARNING: Unable to set GPFS hints (not implemented.)\n");
}
}
strcpy(settingVal, settingPtr);
strcpy(valueVal, valuePtr);
} /* ExtractHint() */
} 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) void ShowHints(MPI_Info * mpiHints)
{ {
char key[MPI_MAX_INFO_VAL], char key[MPI_MAX_INFO_VAL], value[MPI_MAX_INFO_VAL];
value[MPI_MAX_INFO_VAL]; int flag, i, nkeys;
int flag,
i,
nkeys;
MPI_CHECK(MPI_Info_get_nkeys(*mpiHints, &nkeys), MPI_CHECK(MPI_Info_get_nkeys(*mpiHints, &nkeys),
"cannot get info object keys"); "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() */
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. * Takes a string of the form 64, 8m, 128k, 4g, etc. and converts to bytes.
*/ */
IOR_offset_t IOR_offset_t StringToBytes(char *size_str)
StringToBytes(char * size_str)
{ {
IOR_offset_t size = 0; IOR_offset_t size = 0;
char range; char range;
int rc; int rc;
rc = sscanf(size_str, "%lld%c", &size, &range); rc = sscanf(size_str, "%lld%c", &size, &range);
if (rc == 2) { if (rc == 2) {
switch ((int)range) { switch ((int)range) {
case 'k': case 'K': size <<= 10; break; case 'k':
case 'm': case 'M': size <<= 20; break; case 'K':
case 'g': case 'G': size <<= 30; break; 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) { return (size);
size = -1; } /* StringToBytes() */
}
return(size);
} /* StringToBytes() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Displays size of file system and percent of data blocks and inodes used. * Displays size of file system and percent of data blocks and inodes used.
*/ */
void void ShowFileSystemSize(char *fileSystem)
ShowFileSystemSize(char *fileSystem)
{ {
#ifndef _WIN32 /* FIXME */ #ifndef _WIN32 /* FIXME */
int error; int error;
char realPath[PATH_MAX]; char realPath[PATH_MAX];
char *fileSystemUnitStr = "GiB"; char *fileSystemUnitStr = "GiB";
long long int fileSystemUnitVal = 1024 * 1024 * 1024; long long int fileSystemUnitVal = 1024 * 1024 * 1024;
long long int inodeUnitVal = 1024 * 1024; long long int inodeUnitVal = 1024 * 1024;
long long int totalFileSystemSize, long long int totalFileSystemSize,
freeFileSystemSize, freeFileSystemSize, totalInodes, freeInodes;
totalInodes, double totalFileSystemSizeHR,
freeInodes; usedFileSystemPercentage, usedInodePercentage;
double totalFileSystemSizeHR, #ifdef __sun /* SunOS does not support statfs(), instead uses statvfs() */
usedFileSystemPercentage, struct statvfs statusBuffer;
usedInodePercentage; #else /* !__sun */
#ifdef __sun /* SunOS does not support statfs(), instead uses statvfs() */ struct statfs statusBuffer;
struct statvfs statusBuffer; #endif /* __sun */
#else /* !__sun */
struct statfs statusBuffer;
#endif /* __sun */
#ifdef __sun #ifdef __sun
if (statvfs(fileSystem, &statusBuffer) != 0) { if (statvfs(fileSystem, &statusBuffer) != 0) {
ERR("unable to statvfs() file system"); ERR("unable to statvfs() file system");
} }
#else /* !__sun */ #else /* !__sun */
if (statfs(fileSystem, &statusBuffer) != 0) { if (statfs(fileSystem, &statusBuffer) != 0) {
ERR("unable to statfs() file system"); ERR("unable to statfs() file system");
} }
#endif /* __sun */ #endif /* __sun */
/* data blocks */ /* data blocks */
#ifdef __sun #ifdef __sun
totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_frsize; totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_frsize;
freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_frsize; freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_frsize;
#else /* !__sun */ #else /* !__sun */
totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_bsize; totalFileSystemSize = statusBuffer.f_blocks * statusBuffer.f_bsize;
freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_bsize; freeFileSystemSize = statusBuffer.f_bfree * statusBuffer.f_bsize;
#endif /* __sun */ #endif /* __sun */
usedFileSystemPercentage = (1 - ((double)freeFileSystemSize usedFileSystemPercentage = (1 - ((double)freeFileSystemSize
/ (double)totalFileSystemSize)) * 100; / (double)totalFileSystemSize)) * 100;
totalFileSystemSizeHR = (double)totalFileSystemSize totalFileSystemSizeHR =
/ (double)fileSystemUnitVal; (double)totalFileSystemSize / (double)fileSystemUnitVal;
if (totalFileSystemSizeHR > 1024) { if (totalFileSystemSizeHR > 1024) {
totalFileSystemSizeHR = totalFileSystemSizeHR / 1024; totalFileSystemSizeHR = totalFileSystemSizeHR / 1024;
fileSystemUnitStr = "TiB"; fileSystemUnitStr = "TiB";
} }
/* inodes */ /* inodes */
totalInodes = statusBuffer.f_files; totalInodes = statusBuffer.f_files;
freeInodes = statusBuffer.f_ffree; freeInodes = statusBuffer.f_ffree;
usedInodePercentage = (1 - ((double)freeInodes/(double)totalInodes)) * 100; usedInodePercentage =
(1 - ((double)freeInodes / (double)totalInodes)) * 100;
/* show results */ /* show results */
if (realpath(fileSystem, realPath) == NULL) { if (realpath(fileSystem, realPath) == NULL) {
ERR("unable to use realpath()"); ERR("unable to use realpath()");
} }
fprintf(stdout, "Path: %s\n", realPath); fprintf(stdout, "Path: %s\n", realPath);
fprintf(stdout, "FS: %.1f %s Used FS: %2.1f%% ", totalFileSystemSizeHR, fprintf(stdout, "FS: %.1f %s Used FS: %2.1f%% ",
fileSystemUnitStr, usedFileSystemPercentage); totalFileSystemSizeHR, fileSystemUnitStr,
fprintf(stdout, "Inodes: %.1f Mi Used Inodes: %2.1f%%\n", usedFileSystemPercentage);
(double)totalInodes / (double)inodeUnitVal, usedInodePercentage); fprintf(stdout, "Inodes: %.1f Mi Used Inodes: %2.1f%%\n",
fflush(stdout); (double)totalInodes / (double)inodeUnitVal,
#endif /* _WIN32 */ usedInodePercentage);
fflush(stdout);
return; #endif /* _WIN32 */
} /* ShowFileSystemSize() */
return;
} /* ShowFileSystemSize() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Return match of regular expression -- 0 is failure, 1 is success. * Return match of regular expression -- 0 is failure, 1 is success.
*/ */
int int Regex(char *string, char *pattern)
Regex(char *string, char *pattern)
{ {
int retValue = 0; int retValue = 0;
#ifndef _WIN32 /* Okay to always not match */ #ifndef _WIN32 /* Okay to always not match */
regex_t regEx; regex_t regEx;
regmatch_t regMatch; regmatch_t regMatch;
regcomp(&regEx, pattern, REG_EXTENDED); regcomp(&regEx, pattern, REG_EXTENDED);
if (regexec(&regEx, string, 1, &regMatch, 0) == 0) { if (regexec(&regEx, string, 1, &regMatch, 0) == 0) {
retValue = 1; retValue = 1;
} }
regfree(&regEx); regfree(&regEx);
#endif #endif
return(retValue); return (retValue);
} /* Regex() */ } /* Regex() */
#if USE_UNDOC_OPT /* corruptFile */
#if USE_UNDOC_OPT /* corruptFile */
/******************************************************************************/ /******************************************************************************/
/* /*
* Corrupt file to testing data checking options. * Corrupt file to testing data checking options.
*/ */
void CorruptFile(char *testFileName, void CorruptFile(char *testFileName, IOR_param_t * test, int rep, int access)
IOR_param_t *test,
int rep,
int access)
{ {
IOR_offset_t tmpOff, range, eof; IOR_offset_t tmpOff, range, eof;
char fileName[MAX_STR]; char fileName[MAX_STR];
/* determine file name */ /* determine file name */
strcpy(fileName, testFileName); strcpy(fileName, testFileName);
if (access == READCHECK && test->filePerProc) { if (access == READCHECK && test->filePerProc) {
strcpy(fileName, test->testFileName_fppReadCheck); strcpy(fileName, test->testFileName_fppReadCheck);
} }
/* determine offset to modify */ /* determine offset to modify */
SeedRandGen(test->testComm); SeedRandGen(test->testComm);
eof = test->aggFileSizeFromCalc[rep] eof = test->aggFileSizeFromCalc[rep]
/ (test->filePerProc ? test->numTasks : 1); / (test->filePerProc ? test->numTasks : 1);
if (access == WRITECHECK) { if (access == WRITECHECK) {
range = eof - test->offset; range = eof - test->offset;
} else { /* READCHECK */ } else { /* READCHECK */
range = test->transferSize; range = test->transferSize;
} }
tmpOff = (IOR_offset_t)((rand()/(float)RAND_MAX) * range) + test->offset; tmpOff =
(IOR_offset_t) ((rand() / (float)RAND_MAX) * range) + test->offset;
if (tmpOff >= eof) tmpOff = tmpOff / 2; if (tmpOff >= eof)
tmpOff = tmpOff / 2;
/* corrupt <fileName> at <offset> with <value> */ /* corrupt <fileName> at <offset> with <value> */
if (rank == 0 || test->filePerProc) { if (rank == 0 || test->filePerProc) {
ModifyByteInFile(fileName, tmpOff, 121); ModifyByteInFile(fileName, tmpOff, 121);
} }
return;
} /* CorruptFile() */
return;
} /* CorruptFile() */
/******************************************************************************/ /******************************************************************************/
/* /*
* Modify byte in file - used to testing write/read data checking. * Modify byte in file - used to testing write/read data checking.
*/ */
void void ModifyByteInFile(char *fileName, IOR_offset_t offset, int byteValue)
ModifyByteInFile(char * fileName,
IOR_offset_t offset,
int byteValue)
{ {
int fd; int fd;
int rc; int rc;
char old; char old;
char new; char new;
new = (char)byteValue; new = (char)byteValue;
/* open file, show old value, update to new value */ /* open file, show old value, update to new value */
fd = open(fileName, O_RDWR); fd = open(fileName, O_RDWR);
rc = lseek(fd, offset, SEEK_SET); rc = lseek(fd, offset, SEEK_SET);
if (rc == -1) if (rc == -1)
goto out; goto out;
rc = read(fd, &old, 1); rc = read(fd, &old, 1);
if (rc == -1) if (rc == -1)
goto out; goto out;
rc = lseek(fd, offset, SEEK_SET); rc = lseek(fd, offset, SEEK_SET);
if (rc == -1) if (rc == -1)
goto out; goto out;
rc = write(fd, &new, 1); rc = write(fd, &new, 1);
if (rc == -1) if (rc == -1)
goto out; goto out;
fprintf(stdout, fprintf(stdout,
"** DEBUG: offset %lld in %s changed from %d to %d **\n", offset, "** DEBUG: offset %lld in %s changed from %d to %d **\n",
fileName, (unsigned char)old, (unsigned char)new); offset, fileName, (unsigned char)old, (unsigned char)new);
out:
close(fd);
return;
} /* ModifyByteInFile() */
#endif /* USE_UNDOC_OPT - corruptFile */
out:
close(fd);
return;
} /* ModifyByteInFile() */
#endif /* USE_UNDOC_OPT - corruptFile */
/******************************************************************************/ /******************************************************************************/
/* /*
* Seed random generator. * Seed random generator.
*/ */
void void SeedRandGen(MPI_Comm testComm)
SeedRandGen(MPI_Comm testComm)
{ {
unsigned int randomSeed; unsigned int randomSeed;
if (rank == 0) { if (rank == 0) {
#ifdef _WIN32 #ifdef _WIN32
rand_s(&randomSeed); rand_s(&randomSeed);
#else #else
struct timeval randGenTimer; struct timeval randGenTimer;
gettimeofday(&randGenTimer, (struct timezone *)NULL); gettimeofday(&randGenTimer, (struct timezone *)NULL);
randomSeed = randGenTimer.tv_usec; randomSeed = randGenTimer.tv_usec;
#endif #endif
} }
MPI_CHECK(MPI_Bcast(&randomSeed, 1, MPI_INT, 0, MPI_CHECK(MPI_Bcast(&randomSeed, 1, MPI_INT, 0,
testComm), "cannot broadcast random seed value"); testComm), "cannot broadcast random seed value");
srandom(randomSeed); srandom(randomSeed);
} /* SeedRandGen() */
} /* SeedRandGen() */
/******************************************************************************/ /******************************************************************************/
/* /*
@ -519,18 +501,19 @@ SeedRandGen(MPI_Comm testComm)
int uname(struct utsname *name) int uname(struct utsname *name)
{ {
DWORD nodeNameSize = sizeof(name->nodename) - 1; DWORD nodeNameSize = sizeof(name->nodename) - 1;
memset(name, 0, sizeof(struct utsname)); memset(name, 0, sizeof(struct utsname));
if (!GetComputerNameEx(ComputerNameDnsFullyQualified, name->nodename, &nodeNameSize)) if (!GetComputerNameEx
ERR("GetComputerNameEx failed"); (ComputerNameDnsFullyQualified, name->nodename, &nodeNameSize))
ERR("GetComputerNameEx failed");
strncpy(name->sysname, "Windows", sizeof(name->sysname)-1); strncpy(name->sysname, "Windows", sizeof(name->sysname) - 1);
/* FIXME - these should be easy to fetch */ /* FIXME - these should be easy to fetch */
strncpy(name->release, "-", sizeof(name->release)-1); strncpy(name->release, "-", sizeof(name->release) - 1);
strncpy(name->version, "-", sizeof(name->version)-1); strncpy(name->version, "-", sizeof(name->version) - 1);
strncpy(name->machine, "-", sizeof(name->machine)-1); strncpy(name->machine, "-", sizeof(name->machine) - 1);
return 0; return 0;
} }
#endif /* _WIN32 */ #endif /* _WIN32 */