Change the the One True Formatting (Linux style)
Ran the main ior code through "indent -linux --no-tabs".master
parent
3ff7a4a4ae
commit
240e5ce93f
812
src/aiori-HDF5.c
812
src/aiori-HDF5.c
|
@ -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() */
|
||||||
|
|
|
@ -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, ¶m->transferType),
|
|
||||||
"cannot create contiguous datatype");
|
|
||||||
MPI_CHECK(MPI_Type_commit(¶m->transferType),
|
|
||||||
"cannot commit datatype");
|
|
||||||
if (param->filePerProc) {
|
|
||||||
offsetFactor = 0;
|
|
||||||
tasksPerFile = 1;
|
|
||||||
} else {
|
|
||||||
offsetFactor = (rank + rankOffset) % param->numTasks;
|
|
||||||
tasksPerFile = param->numTasks;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create file type using subarray
|
* 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;
|
||||||
¶m->fileType),
|
}
|
||||||
"cannot create subarray");
|
|
||||||
MPI_CHECK(MPI_Type_commit(¶m->fileType), "cannot commit datatype");
|
|
||||||
|
|
||||||
MPI_CHECK(MPI_File_set_view(*fd, (MPI_Offset)0,
|
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, ¶m->transferType),
|
||||||
|
"cannot create contiguous datatype");
|
||||||
|
MPI_CHECK(MPI_Type_commit(¶m->transferType),
|
||||||
|
"cannot commit datatype");
|
||||||
|
if (param->filePerProc) {
|
||||||
|
offsetFactor = 0;
|
||||||
|
tasksPerFile = 1;
|
||||||
|
} else {
|
||||||
|
offsetFactor = (rank + rankOffset) % param->numTasks;
|
||||||
|
tasksPerFile = param->numTasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create file type using subarray
|
||||||
|
*/
|
||||||
|
fileTypeStruct.globalSizes[0] = 1;
|
||||||
|
fileTypeStruct.globalSizes[1] =
|
||||||
|
transfersPerBlock * tasksPerFile;
|
||||||
|
fileTypeStruct.localSizes[0] = 1;
|
||||||
|
fileTypeStruct.localSizes[1] = transfersPerBlock;
|
||||||
|
fileTypeStruct.startIndices[0] = 0;
|
||||||
|
fileTypeStruct.startIndices[1] =
|
||||||
|
transfersPerBlock * offsetFactor;
|
||||||
|
|
||||||
|
MPI_CHECK(MPI_Type_create_subarray
|
||||||
|
(2, fileTypeStruct.globalSizes,
|
||||||
|
fileTypeStruct.localSizes,
|
||||||
|
fileTypeStruct.startIndices, MPI_ORDER_C,
|
||||||
|
param->transferType, ¶m->fileType),
|
||||||
|
"cannot create subarray");
|
||||||
|
MPI_CHECK(MPI_Type_commit(¶m->fileType),
|
||||||
|
"cannot commit datatype");
|
||||||
|
|
||||||
|
MPI_CHECK(MPI_File_set_view(*fd, (MPI_Offset) 0,
|
||||||
|
param->transferType,
|
||||||
|
param->fileType, "native",
|
||||||
|
(MPI_Info) MPI_INFO_NULL),
|
||||||
|
"cannot set file view");
|
||||||
|
}
|
||||||
|
return ((void *)fd);
|
||||||
|
} /* IOR_Open_MPIIO() */
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*
|
/*
|
||||||
|
@ -210,186 +219,181 @@ IOR_Open_MPIIO(char * testFileName,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IOR_offset_t
|
IOR_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(¶m->fileType),
|
MPI_CHECK(MPI_Type_free(¶m->fileType),
|
||||||
"cannot free MPI file datatype");
|
"cannot free MPI file datatype");
|
||||||
MPI_CHECK(MPI_Type_free(¶m->transferType),
|
MPI_CHECK(MPI_Type_free(¶m->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() */
|
||||||
|
|
|
@ -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() */
|
||||||
|
|
|
@ -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() */
|
||||||
|
|
|
@ -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() */
|
||||||
|
|
727
src/utilities.c
727
src/utilities.c
|
@ -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(¤tTime)) == 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(¤tTime)) == 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(®Ex, pattern, REG_EXTENDED);
|
regcomp(®Ex, pattern, REG_EXTENDED);
|
||||||
if (regexec(®Ex, string, 1, ®Match, 0) == 0) {
|
if (regexec(®Ex, string, 1, ®Match, 0) == 0) {
|
||||||
retValue = 1;
|
retValue = 1;
|
||||||
}
|
}
|
||||||
regfree(®Ex);
|
regfree(®Ex);
|
||||||
#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 */
|
||||||
|
|
Loading…
Reference in New Issue