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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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