summaryrefslogtreecommitdiffstats
path: root/perform
diff options
context:
space:
mode:
authorBill Wendling <wendling@ncsa.uiuc.edu>2001-12-18 20:12:21 (GMT)
committerBill Wendling <wendling@ncsa.uiuc.edu>2001-12-18 20:12:21 (GMT)
commitd1d532069bd98ad37afb130fc9fba76be92d098b (patch)
treee14f5ea53679b8e36c6c0a992fbfe819c6cc0772 /perform
parent2b629eaceb37a14a9e33dafa6a2a50765fd7d629 (diff)
downloadhdf5-d1d532069bd98ad37afb130fc9fba76be92d098b.zip
hdf5-d1d532069bd98ad37afb130fc9fba76be92d098b.tar.gz
hdf5-d1d532069bd98ad37afb130fc9fba76be92d098b.tar.bz2
[svn-r4733]
Purpose: Feature Changes Description: Okay, I needed to add in more parameters so that the user can modify how things are supposed to work with the PIO programs. Also needed to change the algorithm a bit to make these work. And needed to add in timing for the READ option. Solution: Added the above things. The parameters took a major rewrite of the command-line parsing stuff. Here's the usage statement: usage: pio_perf [OPTIONS] OPTIONS -h, --help Print a usage message and exit -d N, --num-dsets=N Number of datasets per file [default:1] -f S, --file-size=S Size of a single file [default: 64M] -F N, --num-files=N Number of files [default: 1] -H, --hdf5 Run HDF5 performance test -i, --num-iterations Number of iterations to perform [default: 1] -m, --mpiio Run MPI/IO performance test -o F, --output=F Output raw data into file F [default: none] -P N, --max-num-processes=N Maximum number of processes to use [default: 1] -p N, --min-num-processes=N Minimum number of processes to use [default: 1] -r, --raw Run raw (UNIX) performance test -X S, --max-xfer-size=S Maximum transfer buffer size [default: 1M] -x S, --min-xfer-size=S Minimum transfer buffer size [default: 1K] F - is a filename. N - is an integer >=0. S - is a size specifier, an integer >=0 followed by a size indicator: K - Kilobyte M - Megabyte G - Gigabyte Example: 37M = 37 Megabytes Platforms tested: Linux, but not fully finished...
Diffstat (limited to 'perform')
-rw-r--r--perform/pio_engine.c415
-rw-r--r--perform/pio_perf.c383
-rw-r--r--perform/pio_perf.h12
3 files changed, 531 insertions, 279 deletions
diff --git a/perform/pio_engine.c b/perform/pio_engine.c
index f3530fc..c2e7ac4 100644
--- a/perform/pio_engine.c
+++ b/perform/pio_engine.c
@@ -35,13 +35,13 @@
#define GOTOERROR(errcode) { ret_code = errcode; goto done; }
#define GOTODONE { goto done; }
#define ERRMSG(mesg) { \
- fprintf(stderr, "Proc %d: ", pio_mpi_rank_g); \
+ fprintf(stderr, "Proc %d: ", pio_mpi_rank_g); \
fprintf(stderr, "*** Assertion failed (%s) at line %4d in %s\n", \
mesg, (int)__LINE__, __FILE__); \
}
#define MSG(mesg) { \
- fprintf(stderr, "Proc %d: ", pio_mpi_rank_g); \
+ fprintf(stderr, "Proc %d: ", pio_mpi_rank_g); \
fprintf(stderr, "(%s) at line %4d in %s\n", \
mesg, (int)__LINE__, __FILE__); \
}
@@ -93,13 +93,13 @@ enum {
};
/* Global variables */
-MPI_Comm pio_comm_g; /* Communicator to run the PIO */
-int pio_mpi_rank_g; /* MPI rank of pio_comm_g */
-int pio_mpi_nprocs_g; /* number of processes of pio_comm_g */
+MPI_Comm pio_comm_g; /* Communicator to run the PIO */
+int pio_mpi_rank_g; /* MPI rank of pio_comm_g */
+int pio_mpi_nprocs_g; /* number of processes of pio_comm_g */
-static int clean_file_g = -1; /*whether to cleanup temporary test */
- /*files. -1 is not defined; */
- /*0 is no cleanup; 1 is do cleanup */
+static int clean_file_g = -1; /*whether to cleanup temporary test */
+ /*files. -1 is not defined; */
+ /*0 is no cleanup; 1 is do cleanup */
@@ -152,7 +152,7 @@ results
do_pio(parameters param)
{
/* return codes */
- int rc; /*routine return code */
+ int rc; /*routine return code */
int mrc; /*MPI return code */
herr_t ret_code = 0; /*return code */
results res;
@@ -166,33 +166,34 @@ do_pio(parameters param)
long ndsets, nelmts;
int color; /*for communicator creation */
char *buffer = NULL; /*data buffer pointer */
- long buf_size; /*data buffer size in bytes */
+ long buf_size; /*data buffer size in bytes */
/* HDF5 variables */
- herr_t hrc; /*HDF5 return code */
+ herr_t hrc; /*HDF5 return code */
/* MPI variables */
int myrank, nprocs = 1;
pio_comm_g = MPI_COMM_NULL;
- /* parameters sanity check */
+ /* Sanity check parameters */
+
+ /* IO type */
iot = param.io_type;
switch (iot) {
case MPIO:
- fd.mpifd = MPI_FILE_NULL;
+ fd.mpifd = MPI_FILE_NULL;
res.timers = pio_time_new(MPI_TIMER);
break;
case RAW:
- fd.rawfd = -1;
+ fd.rawfd = -1;
res.timers = pio_time_new(SYS_TIMER);
- break;
+ break;
case PHDF5:
- fd.h5fd = -1;
+ fd.h5fd = -1;
res.timers = pio_time_new(SYS_TIMER);
break;
-
default:
/* unknown request */
fprintf(stderr, "Unknown IO type request (%d)\n", iot);
@@ -202,7 +203,7 @@ do_pio(parameters param)
nfiles = param.num_files; /* number of files */
ndsets = param.num_dsets; /* number of datasets per file */
nelmts = param.num_elmts; /* number of elements per dataset */
- maxprocs = param.max_num_procs; /* max number of mpi-processes to use */
+ maxprocs = param.num_procs; /* max number of mpi-processes to use */
buf_size = param.buf_size;
if (nfiles < 0 ) {
@@ -295,7 +296,7 @@ buf_size=MIN(1024*1024, buf_size);
for (nf = 1; nf <= nfiles; nf++) {
/*
- * Wirte performance measurement
+ * Write performance measurement
*/
/* Open file for write */
char base_name[256];
@@ -329,15 +330,25 @@ fprintf(stderr, "filename=%s\n", fname);
* Read performance measurement
*/
/* Open file for read */
+ set_time(res.timers, HDF5_FILE_OPENCLOSE, START);
hrc = do_fopen(iot, fname, &fd, PIO_READ);
+ set_time(res.timers, HDF5_FILE_OPENCLOSE, STOP);
+
VRFY((hrc == SUCCESS), "do_fopen failed");
- hrc = do_read(&fd, iot, ndsets, nelmts, buf_size, buffer);
- VRFY((hrc == SUCCESS), "do_read failed");
+ set_time(res.timers, HDF5_READ_FIXED_DIMS, START);
+ hrc = do_read(&fd, iot, ndsets, nelmts, buf_size, buffer);
+ set_time(res.timers, HDF5_READ_FIXED_DIMS, STOP);
+
+ VRFY((hrc == SUCCESS), "do_read failed");
/* Close file for read */
+ set_time(res.timers, HDF5_FILE_OPENCLOSE, START);
hrc = do_fclose(iot, &fd);
+ set_time(res.timers, HDF5_FILE_OPENCLOSE, STOP);
+
VRFY((hrc == SUCCESS), "do_fclose failed");
+
do_cleanupfile(iot, fname);
}
@@ -349,26 +360,27 @@ done:
/* no remove(fname) because that should have happened normally. */
switch (iot) {
case RAW:
- if (fd.rawfd != -1)
- hrc = do_fclose(iot, &fd);
+ if (fd.rawfd != -1)
+ hrc = do_fclose(iot, &fd);
break;
case MPIO:
if (fd.mpifd != MPI_FILE_NULL)
- hrc = do_fclose(iot, &fd);
+ hrc = do_fclose(iot, &fd);
break;
case PHDF5:
if (fd.h5fd != -1)
- hrc = do_fclose(iot, &fd);
+ hrc = do_fclose(iot, &fd);
break;
}
/* release MPI resources */
if (pio_comm_g != MPI_COMM_NULL){
mrc = MPI_Comm_free(&pio_comm_g);
- if (mrc != MPI_SUCCESS) {
- fprintf(stderr, "MPI_Comm_free failed\n");
- ret_code = FAIL;
- }
+
+ if (mrc != MPI_SUCCESS) {
+ fprintf(stderr, "MPI_Comm_free failed\n");
+ ret_code = FAIL;
+ }
}
/* release generic resources */
@@ -499,27 +511,27 @@ static herr_t
do_write(file_descr *fd, iotype iot, long ndsets,
long nelmts, long buf_size, void *buffer)
{
- int ret_code = SUCCESS;
- int rc; /*routine return code */
+ int ret_code = SUCCESS;
+ int rc; /*routine return code */
int mrc; /*MPI return code */
MPI_Offset mpi_offset;
MPI_Status mpi_status;
- long ndset;
- long nelmts_towrite, nelmts_written;
- char dname[64];
- off_t dset_offset; /*dataset offset in a file */
- off_t file_offset; /*file offset of the next transfer */
- long dset_size; /*one dataset size in bytes */
- long nelmts_in_buf;
- long elmts_begin; /*first elmt this process transfer */
- long elmts_count; /*number of elmts this process transfer */
+ long ndset;
+ long nelmts_towrite, nelmts_written;
+ char dname[64];
+ off_t dset_offset; /*dataset offset in a file */
+ off_t file_offset; /*file offset of the next transfer */
+ long dset_size; /*one dataset size in bytes */
+ long nelmts_in_buf;
+ long elmts_begin; /*first elmt this process transfer */
+ long elmts_count; /*number of elmts this process transfer */
/* HDF5 variables */
herr_t hrc; /*HDF5 return code */
hsize_t h5dims[1]; /*dataset dim sizes */
hid_t h5dset_space_id = -1; /*dataset space ID */
hid_t h5mem_space_id = -1; /*memory dataspace ID */
- hid_t h5ds_id = -1; /* dataset handle */
+ hid_t h5ds_id = -1; /*dataset handle */
#if AKCDEBUG
fprintf(stderr, "In do_write\n");
@@ -527,6 +539,7 @@ fprintf(stderr, "ndsets=%ld\n", ndsets);
fprintf(stderr, "nelmts=%ld\n", nelmts);
fprintf(stderr, "buffer size=%ld\n", buf_size);
#endif
+
/* calculate dataset parameters. data type is always native C int */
dset_size = nelmts * ELMT_SIZE;
nelmts_in_buf = buf_size/ELMT_SIZE;
@@ -569,19 +582,19 @@ fprintf(stderr, "buffer size=%ld\n", buf_size);
break;
}
- /* Calculate the first element and how many elements this process
- * transfer. First calculate the beginning element of this process
- * and the next process. Count of elements is the difference between
- * these two beginnings. This way, it avoids any rounding errors.
- */
- elmts_begin = (nelmts*1.0)/pio_mpi_nprocs_g*pio_mpi_rank_g;
- if (pio_mpi_rank_g < (pio_mpi_nprocs_g - 1)){
- elmts_count = ((nelmts*1.0)/pio_mpi_nprocs_g*(pio_mpi_rank_g+1)) -
- elmts_begin;
- }else{
- /* last process. Take whatever are left */
- elmts_count = nelmts - elmts_begin;
- }
+ /* Calculate the first element and how many elements this process
+ * transfer. First calculate the beginning element of this process
+ * and the next process. Count of elements is the difference between
+ * these two beginnings. This way, it avoids any rounding errors.
+ */
+ elmts_begin = (nelmts*1.0)/pio_mpi_nprocs_g*pio_mpi_rank_g;
+
+ if (pio_mpi_rank_g < (pio_mpi_nprocs_g - 1))
+ elmts_count = ((nelmts * 1.0) / pio_mpi_nprocs_g * (pio_mpi_rank_g + 1))
+ - elmts_begin;
+ else
+ /* last process. Take whatever are left */
+ elmts_count = nelmts - elmts_begin;
#if AKCDEBUG
fprintf(stderr, "proc %d: elmts_begin=%ld, elmts_count=%ld\n",
@@ -589,6 +602,7 @@ fprintf(stderr, "proc %d: elmts_begin=%ld, elmts_count=%ld\n",
#endif
nelmts_written = 0 ;
+
while (nelmts_written < elmts_count){
nelmts_towrite = elmts_count - nelmts_written;
@@ -612,56 +626,60 @@ fprintf(stderr, "proc %d: elmts_begin=%ld, elmts_count=%ld\n",
/* Write */
/* Calculate offset of write within a dataset/file */
- switch (iot){
+ switch (iot) {
case RAW:
- file_offset = dset_offset +
- (elmts_begin + nelmts_written)*ELMT_SIZE;
+ file_offset = dset_offset + (elmts_begin + nelmts_written)*ELMT_SIZE;
+
#if AKCDEBUG
fprintf(stderr, "proc %d: writes %ld bytes at file-offset %ld\n",
- pio_mpi_rank_g, nelmts_towrite*ELMT_SIZE, file_offset);
+ pio_mpi_rank_g, nelmts_towrite*ELMT_SIZE, file_offset);
#endif
+
rc = RAWSEEK(fd->rawfd, file_offset);
- VRFY((rc>=0), "RAWSEEK");
+ VRFY((rc>=0), "RAWSEEK");
rc = RAWWRITE(fd->rawfd, buffer, nelmts_towrite*ELMT_SIZE);
- VRFY((rc==(nelmts_towrite*ELMT_SIZE)), "RAWWRITE");
+ VRFY((rc==(nelmts_towrite*ELMT_SIZE)), "RAWWRITE");
break;
case MPIO:
- mpi_offset = dset_offset +
- (elmts_begin + nelmts_written)*ELMT_SIZE;
+ mpi_offset = dset_offset + (elmts_begin + nelmts_written)*ELMT_SIZE;
+
#if AKCDEBUG
fprintf(stderr, "proc %d: writes %ld bytes at mpi-offset %ld\n",
- pio_mpi_rank_g, nelmts_towrite*ELMT_SIZE, mpi_offset);
+ pio_mpi_rank_g, nelmts_towrite*ELMT_SIZE, mpi_offset);
#endif
- mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buffer,
- nelmts_towrite*ELMT_SIZE, MPI_CHAR, &mpi_status);
- VRFY((mrc==MPI_SUCCESS), "MPIO_WRITE");
- break;
+
+ mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buffer,
+ nelmts_towrite * ELMT_SIZE, MPI_CHAR,
+ &mpi_status);
+ VRFY((mrc==MPI_SUCCESS), "MPIO_WRITE");
+ break;
case PHDF5:
- /*set up the dset space id to select the segment to process */
- {
- hsize_t block[1], stride[1], count[1];
- hssize_t start[1];
-
- start[0] = elmts_begin + nelmts_written;
- stride[0] = block[0] = nelmts_towrite;
- count[0] = 1;
- hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET,
- start, stride, count, block);
- VRFY((hrc >= 0), "H5Sset_hyperslab");
-
- /*setup the memory space id too. Only start is different */
- start[0] = 0;
- hrc = H5Sselect_hyperslab(h5mem_space_id, H5S_SELECT_SET,
- start, stride, count, block);
- VRFY((hrc >= 0), "H5Sset_hyperslab");
- }
- MPI_Barrier(pio_comm_g);
-
- /* set write time here */
- hrc = H5Dwrite(h5ds_id, H5T_NATIVE_INT, h5mem_space_id,
- h5dset_space_id, H5P_DEFAULT, buffer);
- VRFY((hrc >= 0), "H5Dwrite");
+ /*set up the dset space id to select the segment to process */
+ {
+ hsize_t block[1], stride[1], count[1];
+ hssize_t start[1];
+
+ start[0] = elmts_begin + nelmts_written;
+ stride[0] = block[0] = nelmts_towrite;
+ count[0] = 1;
+ hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET,
+ start, stride, count, block);
+ VRFY((hrc >= 0), "H5Sset_hyperslab");
+
+ /*setup the memory space id too. Only start is different */
+ start[0] = 0;
+ hrc = H5Sselect_hyperslab(h5mem_space_id, H5S_SELECT_SET,
+ start, stride, count, block);
+ VRFY((hrc >= 0), "H5Sset_hyperslab");
+ }
+
+ MPI_Barrier(pio_comm_g);
+
+ /* set write time here */
+ hrc = H5Dwrite(h5ds_id, H5T_NATIVE_INT, h5mem_space_id,
+ h5dset_space_id, H5P_DEFAULT, buffer);
+ VRFY((hrc >= 0), "H5Dwrite");
break;
}
@@ -708,7 +726,6 @@ done:
return ret_code;
}
-
/*
* Function: do_read
* Purpose: read the required amount of data from the file.
@@ -720,27 +737,27 @@ static herr_t
do_read(file_descr *fd, iotype iot, long ndsets,
long nelmts, long buf_size, void *buffer /*out*/)
{
- int ret_code = SUCCESS;
- int rc; /*routine return code */
+ int ret_code = SUCCESS;
+ int rc; /*routine return code */
int mrc; /*MPI return code */
- MPI_Offset mpi_offset;
- MPI_Status mpi_status;
- long ndset;
- long nelmts_toread, nelmts_read;
- char dname[64];
- off_t dset_offset; /*dataset offset in a file */
- off_t file_offset; /*file offset of the next transfer */
- long dset_size; /*one dataset size in bytes */
- long nelmts_in_buf;
- long elmts_begin; /*first elmt this process transfer */
- long elmts_count; /*number of elmts this process transfer */
+ MPI_Offset mpi_offset;
+ MPI_Status mpi_status;
+ long ndset;
+ long nelmts_toread, nelmts_read;
+ char dname[64];
+ off_t dset_offset; /*dataset offset in a file */
+ off_t file_offset; /*file offset of the next transfer */
+ long dset_size; /*one dataset size in bytes */
+ long nelmts_in_buf;
+ long elmts_begin; /*first elmt this process transfer */
+ long elmts_count; /*number of elmts this process transfer */
/* HDF5 variables */
- herr_t hrc; /*HDF5 return code */
- hsize_t h5dims[1]; /*dataset dim sizes */
- hid_t h5dset_space_id = -1; /*dataset space ID */
- hid_t h5mem_space_id = -1; /*memory dataspace ID */
- hid_t h5ds_id = -1; /* dataset handle */
+ herr_t hrc; /*HDF5 return code */
+ hsize_t h5dims[1]; /*dataset dim sizes */
+ hid_t h5dset_space_id = -1; /*dataset space ID */
+ hid_t h5mem_space_id = -1; /*memory dataspace ID */
+ hid_t h5ds_id = -1; /*dataset handle */
#if AKCDEBUG
fprintf(stderr, "In do_read\n");
@@ -748,6 +765,7 @@ fprintf(stderr, "ndsets=%ld\n", ndsets);
fprintf(stderr, "nelmts=%ld\n", nelmts);
fprintf(stderr, "buffer size=%ld\n", buf_size);
#endif
+
/* calculate dataset parameters. data type is always native C int */
dset_size = nelmts * ELMT_SIZE;
nelmts_in_buf = buf_size/ELMT_SIZE;
@@ -766,7 +784,6 @@ fprintf(stderr, "buffer size=%ld\n", buf_size);
}
for (ndset = 1; ndset <= ndsets; ++ndset) {
-
/* Calculate dataset offset within a file */
/* create dataset */
@@ -788,88 +805,94 @@ fprintf(stderr, "buffer size=%ld\n", buf_size);
break;
}
- /* Calculate the first element and how many elements this process
- * transfer. First calculate the beginning element of this process
- * and the next process. Count of elements is the difference between
- * these two beginnings. This way, it avoids any rounding errors.
- */
- elmts_begin = (nelmts*1.0)/pio_mpi_nprocs_g*pio_mpi_rank_g;
- if (pio_mpi_rank_g < (pio_mpi_nprocs_g - 1)){
- elmts_count = ((nelmts*1.0)/pio_mpi_nprocs_g*(pio_mpi_rank_g+1)) -
- elmts_begin;
- }else{
- /* last process. Take whatever are left */
- elmts_count = nelmts - elmts_begin;
- }
+ /*
+ * Calculate the first element and how many elements this process
+ * transfer. First calculate the beginning element of this process
+ * and the next process. Count of elements is the difference between
+ * these two beginnings. This way, it avoids any rounding errors.
+ */
+ elmts_begin = (nelmts*1.0)/pio_mpi_nprocs_g*pio_mpi_rank_g;
+
+ if (pio_mpi_rank_g < (pio_mpi_nprocs_g - 1))
+ elmts_count = ((nelmts * 1.0) / pio_mpi_nprocs_g * (pio_mpi_rank_g + 1)) -
+ elmts_begin;
+ else
+ /* last process. Take whatever are left */
+ elmts_count = nelmts - elmts_begin;
#if AKCDEBUG
fprintf(stderr, "proc %d: elmts_begin=%ld, elmts_count=%ld\n",
- pio_mpi_rank_g, elmts_begin, elmts_count);
+ pio_mpi_rank_g, elmts_begin, elmts_count);
#endif
nelmts_read = 0 ;
+
while (nelmts_read < elmts_count){
nelmts_toread = elmts_count - nelmts_read;
- if (elmts_count - nelmts_read >= nelmts_in_buf) {
+ if (elmts_count - nelmts_read >= nelmts_in_buf)
nelmts_toread = nelmts_in_buf;
- } else {
+ else
/* last read of a partial buffer */
nelmts_toread = elmts_count - nelmts_read;
- }
/* read */
/* Calculate offset of read within a dataset/file */
switch (iot){
case RAW:
- file_offset = dset_offset +
- (elmts_begin + nelmts_read)*ELMT_SIZE;
+ file_offset = dset_offset + (elmts_begin + nelmts_read)*ELMT_SIZE;
+
#if AKCDEBUG
fprintf(stderr, "proc %d: read %ld bytes at file-offset %ld\n",
- pio_mpi_rank_g, nelmts_toread*ELMT_SIZE, file_offset);
+ pio_mpi_rank_g, nelmts_toread*ELMT_SIZE, file_offset);
#endif
+
rc = RAWSEEK(fd->rawfd, file_offset);
- VRFY((rc>=0), "RAWSEEK");
+ VRFY((rc>=0), "RAWSEEK");
rc = RAWREAD(fd->rawfd, buffer, nelmts_toread*ELMT_SIZE);
- VRFY((rc==(nelmts_toread*ELMT_SIZE)), "RAWREAD");
+ VRFY((rc==(nelmts_toread*ELMT_SIZE)), "RAWREAD");
break;
case MPIO:
- mpi_offset = dset_offset +
- (elmts_begin + nelmts_read)*ELMT_SIZE;
+ mpi_offset = dset_offset + (elmts_begin + nelmts_read)*ELMT_SIZE;
+
#if AKCDEBUG
fprintf(stderr, "proc %d: read %ld bytes at mpi-offset %ld\n",
pio_mpi_rank_g, nelmts_toread*ELMT_SIZE, mpi_offset);
#endif
- mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buffer,
- nelmts_toread*ELMT_SIZE, MPI_CHAR, &mpi_status);
- VRFY((mrc==MPI_SUCCESS), "MPIO_read");
- break;
+
+ mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buffer,
+ nelmts_toread*ELMT_SIZE, MPI_CHAR,
+ &mpi_status);
+ VRFY((mrc==MPI_SUCCESS), "MPIO_read");
+ break;
+
case PHDF5:
- /*set up the dset space id to select the segment to process */
- {
- hsize_t block[1], stride[1], count[1];
- hssize_t start[1];
-
- start[0] = elmts_begin + nelmts_read;
- stride[0] = block[0] = nelmts_toread;
- count[0] = 1;
- hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET,
- start, stride, count, block);
- VRFY((hrc >= 0), "H5Sset_hyperslab");
-
- /*setup the memory space id too. Only start is different */
- start[0] = 0;
- hrc = H5Sselect_hyperslab(h5mem_space_id, H5S_SELECT_SET,
- start, stride, count, block);
- VRFY((hrc >= 0), "H5Sset_hyperslab");
- }
- MPI_Barrier(pio_comm_g);
-
- /* set read time here */
- hrc = H5Dread(h5ds_id, H5T_NATIVE_INT, h5mem_space_id,
- h5dset_space_id, H5P_DEFAULT, buffer);
- VRFY((hrc >= 0), "H5Dread");
+ /*set up the dset space id to select the segment to process */
+ {
+ hsize_t block[1], stride[1], count[1];
+ hssize_t start[1];
+
+ start[0] = elmts_begin + nelmts_read;
+ stride[0] = block[0] = nelmts_toread;
+ count[0] = 1;
+ hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET,
+ start, stride, count, block);
+ VRFY((hrc >= 0), "H5Sset_hyperslab");
+
+ /*setup the memory space id too. Only start is different */
+ start[0] = 0;
+ hrc = H5Sselect_hyperslab(h5mem_space_id, H5S_SELECT_SET,
+ start, stride, count, block);
+ VRFY((hrc >= 0), "H5Sset_hyperslab");
+ }
+
+ MPI_Barrier(pio_comm_g);
+
+ /* set read time here */
+ hrc = H5Dread(h5ds_id, H5T_NATIVE_INT, h5mem_space_id,
+ h5dset_space_id, H5P_DEFAULT, buffer);
+ VRFY((hrc >= 0), "H5Dread");
break;
}
@@ -880,7 +903,7 @@ fprintf(stderr, "proc %d: read %ld bytes at mpi-offset %ld\n",
register int i;
for (i = 0; i < nelmts_towrite; ++i)
- /* TO BE IMPLEMENTED */
+ /* TO BE IMPLEMENTED */
;
}
#endif
@@ -928,7 +951,6 @@ done:
return ret_code;
}
-
/*
* Function: do_fopen
* Purpose: Open the specified file.
@@ -945,11 +967,10 @@ do_fopen(iotype iot, char *fname, file_descr *fd /*out*/, int flags)
switch (iot) {
case RAW:
- if (flags & (PIO_CREATE | PIO_WRITE)) {
+ if (flags & (PIO_CREATE | PIO_WRITE))
fd->rawfd = RAWCREATE(fname);
- } else {
+ else
fd->rawfd = RAWOPEN(fname, O_RDONLY);
- }
if (fd->rawfd < 0 ) {
fprintf(stderr, "Raw File Open failed(%s)\n", fname);
@@ -960,30 +981,32 @@ do_fopen(iotype iot, char *fname, file_descr *fd /*out*/, int flags)
case MPIO:
if (flags & (PIO_CREATE | PIO_WRITE)) {
- MPI_File_delete(fname, MPI_INFO_NULL);
+ MPI_File_delete(fname, MPI_INFO_NULL);
mrc = MPI_File_open(pio_comm_g, fname, MPI_MODE_CREATE | MPI_MODE_RDWR,
MPI_INFO_NULL, &fd->mpifd);
- if (mrc != MPI_SUCCESS) {
- fprintf(stderr, "MPI File Open failed(%s)\n", fname);
- GOTOERROR(FAIL);
- }
- /*since MPI_File_open with MPI_MODE_CREATE does not truncate */
- /*filesize , set size to 0 explicitedly. */
- mrc = MPI_File_set_size(fd->mpifd, 0);
- if (mrc != MPI_SUCCESS) {
- fprintf(stderr, "MPI_File_set_size failed\n");
- GOTOERROR(FAIL);
- }
+ if (mrc != MPI_SUCCESS) {
+ fprintf(stderr, "MPI File Open failed(%s)\n", fname);
+ GOTOERROR(FAIL);
+ }
+
+ /*since MPI_File_open with MPI_MODE_CREATE does not truncate */
+ /*filesize , set size to 0 explicitedly. */
+ mrc = MPI_File_set_size(fd->mpifd, 0);
+
+ if (mrc != MPI_SUCCESS) {
+ fprintf(stderr, "MPI_File_set_size failed\n");
+ GOTOERROR(FAIL);
+ }
} else {
mrc = MPI_File_open(pio_comm_g, fname, MPI_MODE_RDONLY,
MPI_INFO_NULL, &fd->mpifd);
- if (mrc != MPI_SUCCESS) {
- fprintf(stderr, "MPI File Open failed(%s)\n", fname);
- GOTOERROR(FAIL);
- }
- }
+ if (mrc != MPI_SUCCESS) {
+ fprintf(stderr, "MPI File Open failed(%s)\n", fname);
+ GOTOERROR(FAIL);
+ }
+ }
break;
@@ -1095,21 +1118,21 @@ static void
do_cleanupfile(iotype iot, char *fname)
{
if (pio_mpi_rank_g != 0)
- return;
+ return;
if (clean_file_g == -1)
- clean_file_g = (getenv("HDF5_NOCLEANUP")==NULL) ? 1 : 0;
+ clean_file_g = (getenv("HDF5_NOCLEANUP")==NULL) ? 1 : 0;
if (clean_file_g){
- switch (iot){
- case RAW:
- remove(fname);
- break;
- case MPIO:
- case PHDF5:
- MPI_File_delete(fname, MPI_INFO_NULL);
- break;
- }
+ switch (iot){
+ case RAW:
+ remove(fname);
+ break;
+ case MPIO:
+ case PHDF5:
+ MPI_File_delete(fname, MPI_INFO_NULL);
+ break;
+ }
}
}
#endif /* H5_HAVE_PARALLEL */
diff --git a/perform/pio_perf.c b/perform/pio_perf.c
index a195d25..a4602f8 100644
--- a/perform/pio_perf.c
+++ b/perform/pio_perf.c
@@ -71,6 +71,10 @@
#define ONE_MB (ONE_KB * ONE_KB)
#define ONE_GB (ONE_MB * ONE_KB)
+#define PIO_RAW 020
+#define PIO_MPI 040
+#define PIO_HDF5 060
+
#define MB_PER_SEC(bytes,t) (((bytes) / ONE_MB) / t)
#define MIN_HDF5_BUF_SIZE (ONE_MB >> 1)
@@ -85,9 +89,9 @@ static const char *progname = "pio_perf";
* adding more, make sure that they don't clash with each other.
*/
#if 1
-static const char *s_opts = "ho:m:";
+static const char *s_opts = "hf:HP:p:X:x:md:F:i:o:r";
#else
-static const char *s_opts = "hbo:m:";
+static const char *s_opts = "hbf:HP:p:X:x:md:F:i:o:r";
#endif /* 1 */
static struct long_options l_opts[] = {
{ "help", no_arg, 'h' },
@@ -101,28 +105,102 @@ static struct long_options l_opts[] = {
{ "bin", no_arg, 'b' },
{ "bi", no_arg, 'b' },
#endif /* 0 */
- { "max-size", require_arg, 'm' },
- { "max-siz", require_arg, 'm' },
- { "max-si", require_arg, 'm' },
- { "max-s", require_arg, 'm' },
- { "max", require_arg, 'm' },
- { "ma", require_arg, 'm' },
+ { "file-size", require_arg, 'f' },
+ { "file-siz", require_arg, 'f' },
+ { "file-si", require_arg, 'f' },
+ { "file-s", require_arg, 'f' },
+ { "file", require_arg, 'f' },
+ { "fil", require_arg, 'f' },
+ { "fi", require_arg, 'f' },
+ { "hdf5", no_arg, 'H' },
+ { "hdf", no_arg, 'H' },
+ { "hd", no_arg, 'H' },
+ { "max-num-processes", require_arg, 'P' },
+ { "max-num-processe", require_arg, 'P' },
+ { "max-num-process", require_arg, 'P' },
+ { "max-num-proces", require_arg, 'P' },
+ { "max-num-proce", require_arg, 'P' },
+ { "max-num-proc", require_arg, 'P' },
+ { "max-num-pro", require_arg, 'P' },
+ { "max-num-pr", require_arg, 'P' },
+ { "max-num-p", require_arg, 'P' },
+ { "min-num-processes", require_arg, 'p' },
+ { "min-num-processe", require_arg, 'p' },
+ { "min-num-process", require_arg, 'p' },
+ { "min-num-proces", require_arg, 'p' },
+ { "min-num-proce", require_arg, 'p' },
+ { "min-num-proc", require_arg, 'p' },
+ { "min-num-pro", require_arg, 'p' },
+ { "min-num-pr", require_arg, 'p' },
+ { "min-num-p", require_arg, 'p' },
+ { "max-xfer-size", require_arg, 'X' },
+ { "max-xfer-siz", require_arg, 'X' },
+ { "max-xfer-si", require_arg, 'X' },
+ { "max-xfer-s", require_arg, 'X' },
+ { "max-xfer", require_arg, 'X' },
+ { "max-xfe", require_arg, 'X' },
+ { "max-xf", require_arg, 'X' },
+ { "max-x", require_arg, 'X' },
+ { "min-xfer-size", require_arg, 'x' },
+ { "min-xfer-siz", require_arg, 'x' },
+ { "min-xfer-si", require_arg, 'x' },
+ { "min-xfer-s", require_arg, 'x' },
+ { "min-xfer", require_arg, 'x' },
+ { "min-xfe", require_arg, 'x' },
+ { "min-xf", require_arg, 'x' },
+ { "min-x", require_arg, 'x' },
+ { "mpiio", no_arg, 'm' },
+ { "mpii", no_arg, 'm' },
+ { "mpi", no_arg, 'm' },
+ { "mp", no_arg, 'm' },
+ { "num-dsets", require_arg, 'd' },
+ { "num-dset", require_arg, 'd' },
+ { "num-dse", require_arg, 'd' },
+ { "num-ds", require_arg, 'd' },
+ { "num-d", require_arg, 'd' },
+ { "num-files", require_arg, 'F' },
+ { "num-file", require_arg, 'F' },
+ { "num-fil", require_arg, 'F' },
+ { "num-fi", require_arg, 'F' },
+ { "num-f", require_arg, 'F' },
+ { "num-iterations", require_arg, 'i' },
+ { "num-iteration", require_arg, 'i' },
+ { "num-iteratio", require_arg, 'i' },
+ { "num-iterati", require_arg, 'i' },
+ { "num-iterat", require_arg, 'i' },
+ { "num-itera", require_arg, 'i' },
+ { "num-iter", require_arg, 'i' },
+ { "num-ite", require_arg, 'i' },
+ { "num-it", require_arg, 'i' },
+ { "num-i", require_arg, 'i' },
{ "output", require_arg, 'o' },
{ "outpu", require_arg, 'o' },
{ "outp", require_arg, 'o' },
{ "out", require_arg, 'o' },
{ "ou", require_arg, 'o' },
+ { "raw", no_arg, 'r' },
+ { "ra", no_arg, 'r' },
{ NULL, 0, '\0' }
};
struct options {
+ long io_types; /* bitmask of which I/O types to test */
const char *output_file; /* file to print report to */
- long max_size; /* maximum size of file in gigabytes */
+ long file_size; /* size of file */
+ long num_dsets; /* number of datasets */
+ long num_files; /* number of files */
+ long num_iters; /* number of iterations */
+ long max_num_procs; /* maximum number of processes to use */
+ long min_num_procs; /* minimum number of processes to use */
+ long max_xfer_size; /* maximum transfer buffer size */
+ long min_xfer_size; /* minimum transfer buffer size */
};
/* local functions */
+static long parse_size_directive(const char *size);
static struct options *parse_command_line(int argc, char *argv[]);
-static void run_test_loop(FILE *output, int max_num_procs, long max_size);
+static void run_test_loop(FILE *output, struct options *options);
+static void run_test(FILE *output, iotype iot, parameters parms);
static void print_indent(register FILE *output, register int indent);
static void usage(const char *prog);
@@ -168,7 +246,7 @@ main(int argc, char **argv)
goto cheese_and;
}
- run_test_loop(output, world_size, opts->max_size);
+ run_test_loop(output, opts);
cheese_and:
MPI_Finalize();
@@ -199,96 +277,116 @@ onions:
* Modifications:
*/
static void
-run_test_loop(FILE *output, int max_num_procs, long max_size)
+run_test_loop(FILE *output, struct options *opts)
{
parameters parms;
+ long num_procs;
+ int io_runs = PIO_HDF5 | PIO_MPI | PIO_RAW; /* default to run all tests */
+
+ if (opts->io_types & ~07) {
+ /* we want to run only a select subset of these tests */
+ opts->io_types = 0;
+
+ if (opts->io_types | PIO_HDF5)
+ io_runs |= PIO_HDF5;
+
+ if (opts->io_types | PIO_MPI)
+ io_runs |= PIO_MPI;
+
+ if (opts->io_types | PIO_RAW)
+ io_runs |= PIO_RAW;
+ }
- /* num_files stays ``1'' for now but may change later */
- parms.num_files = 1;
- parms.num_iters = 1;
+ parms.num_files = opts->num_files;
+ parms.num_dsets = opts->num_dsets;
+ parms.num_iters = opts->num_iters;
/* divide the maximum number of processors by 2 for each loop iter */
- for (; max_num_procs > 0; max_num_procs /= 2) {
- register iotype i;
+ for (num_procs = opts->min_num_procs;
+ num_procs <= opts->max_num_procs; num_procs <<= 1) {
+ register long j;
- parms.max_num_procs = max_num_procs;
- fprintf(output, "Number of processors = %u\n", parms.max_num_procs);
+ parms.num_procs = num_procs;
+ fprintf(output, "Number of processors = %u\n", parms.num_procs);
- for (i = RAW; i <= PHDF5; ++i) {
- register unsigned long j;
+ for (j = opts->min_xfer_size; j <= opts->max_xfer_size; j <<= 1) {
+ parms.buf_size = j;
+ parms.num_elmts = opts->file_size / (parms.num_dsets * sizeof(int));
- parms.io_type = i;
print_indent(output, TAB_SPACE * 1);
- fprintf(output, "Type of IO = ");
-
- if (i == RAW)
- fprintf(output, "Raw\n");
- else if (i == MPIO)
- fprintf(output, "MPIO\n");
- else
- fprintf(output, "PHDF5\n");
-
- for (j = MIN_HDF5_BUF_SIZE; j <= MAX_HDF5_BUF_SIZE; j <<= 1) {
- results res;
-
- parms.buf_size = j;
- parms.num_dsets = MAX_HDF5_BUF_SIZE / j;
- parms.num_dsets = (parms.num_dsets ? parms.num_dsets : 1);
- parms.num_elmts = max_size / (parms.num_dsets * sizeof(int));
-
- print_indent(output, TAB_SPACE * 2);
- fprintf(output,
- "# of files: %u, # of dsets: %lu, Elements per dset: %lu\n",
- parms.num_files, parms.num_dsets, parms.num_elmts);
-
- /* call Albert's testing here */
- res = do_pio(parms);
-
- print_indent(output, TAB_SPACE * 3);
- fprintf(output, "Write Results = %.2f MB/s\n",
- MB_PER_SEC(parms.num_dsets * parms.num_elmts * sizeof(int),
- get_time(res.timers, HDF5_WRITE_FIXED_DIMS)));
-
- pio_time_destroy(res.timers);
- }
+ fprintf(output,
+ "# of files: %u, # of dsets: %lu, Elements per dset: %lu\n",
+ parms.num_files, parms.num_dsets, parms.num_elmts);
+
+ if (io_runs | PIO_RAW)
+ run_test(output, RAW, parms);
+
+ if (io_runs | PIO_MPI)
+ run_test(output, MPIO, parms);
+
+ if (io_runs | PIO_HDF5)
+ run_test(output, PHDF5, parms);
}
}
}
/*
- * Function: print_indent
- * Purpose: Print spaces to indent a new line of text for pretty printing
- * things.
+ * Function: run_test
+ * Purpose: Inner loop call to actually run the I/O test.
* Return: Nothing
- * Programmer: Bill Wendling, 29. October 2001
+ * Programmer: Bill Wendling, 18. December 2001
* Modifications:
*/
static void
-print_indent(register FILE *output, register int indent)
+run_test(FILE *output, iotype iot, parameters parms)
{
- for (; indent > 0; --indent)
- fputc(' ', output);
+ results res;
+
+ parms.io_type = iot;
+ print_indent(output, TAB_SPACE * 2);
+ fprintf(output, "Type of IO = ");
+
+ switch (iot) {
+ case RAW:
+ fprintf(output, "Raw\n");
+ break;
+ case MPIO:
+ fprintf(output, "MPIO\n");
+ break;
+ case PHDF5:
+ fprintf(output, "PHDF5\n");
+ break;
+ }
+
+ /* call Albert's testing here */
+ res = do_pio(parms);
+
+ print_indent(output, TAB_SPACE * 3);
+ fprintf(output, "Write Results = %.2f MB/s\n",
+ MB_PER_SEC(parms.num_dsets * parms.num_elmts * sizeof(int),
+ get_time(res.timers, HDF5_WRITE_FIXED_DIMS)));
+
+ print_indent(output, TAB_SPACE * 3);
+ fprintf(output, "Read Results = %.2f MB/s\n",
+ MB_PER_SEC(parms.num_dsets * parms.num_elmts * sizeof(int),
+ get_time(res.timers, HDF5_READ_FIXED_DIMS)));
+
+ pio_time_destroy(res.timers);
}
/*
- * Function: usage
- * Purpose: Print a usage message and then exit.
+ * Function: print_indent
+ * Purpose: Print spaces to indent a new line of text for pretty printing
+ * things.
* Return: Nothing
- * Programmer: Bill Wendling, 31. October 2001
+ * Programmer: Bill Wendling, 29. October 2001
* Modifications:
*/
static void
-usage(const char *prog)
+print_indent(register FILE *output, register int indent)
{
- fflush(stdout);
- fprintf(stdout, "usage: %s [OPTIONS]\n", prog);
- fprintf(stdout, " OPTIONS\n");
- fprintf(stdout, " -h, --help Print a usage message and exit\n");
- fprintf(stdout, " -m #, --max-size=# Maximum size of file in megabytes [default: 512]\n");
- fprintf(stdout, " -o F, --output=F Output raw data into file F\n");
- fprintf(stdout, "\n");
- fprintf(stdout, " F - is a filename.\n");
- fprintf(stdout, "\n");
+ for (; indent > 0; --indent)
+ fputc(' ', output);
}
/*
@@ -305,8 +403,18 @@ parse_command_line(int argc, char *argv[])
int opt;
struct options *cl_opts;
- cl_opts = (struct options *)calloc(1, sizeof(struct options));
- cl_opts->max_size = 512 * ONE_MB;
+ cl_opts = (struct options *)malloc(sizeof(struct options));
+
+ cl_opts->output_file = NULL;
+ cl_opts->file_size = 64 * ONE_MB;
+ cl_opts->io_types = 07; /* bottom bits indicate default type to run */
+ cl_opts->num_dsets = 1;
+ cl_opts->num_files = 1;
+ cl_opts->num_iters = 1;
+ cl_opts->max_num_procs = 1;
+ cl_opts->min_num_procs = 1;
+ cl_opts->max_xfer_size = 1 * ONE_MB;
+ cl_opts->min_xfer_size = 1 * ONE_KB;
while ((opt = get_option(argc, (const char **)argv, s_opts, l_opts)) != EOF) {
switch ((char)opt) {
@@ -315,12 +423,45 @@ parse_command_line(int argc, char *argv[])
/* the future "binary" option */
break;
#endif /* 0 */
+ case 'd':
+ cl_opts->num_dsets = strtol(opt_arg, NULL, 10);
+ break;
+ case 'f':
+ cl_opts->file_size = parse_size_directive(opt_arg);
+ break;
+ case 'F':
+ cl_opts->num_files = strtol(opt_arg, NULL, 10);
+ break;
+ case 'H':
+ cl_opts->io_types &= ~07;
+ cl_opts->io_types |= PIO_HDF5;
+ break;
+ case 'i':
+ cl_opts->num_iters = strtol(opt_arg, NULL, 10);
+ break;
case 'm':
- cl_opts->max_size = atol(opt_arg) * ONE_MB;
+ cl_opts->io_types &= ~07;
+ cl_opts->io_types |= PIO_MPI;
break;
case 'o':
cl_opts->output_file = opt_arg;
break;
+ case 'p':
+ cl_opts->min_num_procs = strtol(opt_arg, NULL, 10);
+ break;
+ case 'P':
+ cl_opts->max_num_procs = strtol(opt_arg, NULL, 10);
+ break;
+ case 'r':
+ cl_opts->io_types &= ~07;
+ cl_opts->io_types |= PIO_RAW;
+ break;
+ case 'x':
+ cl_opts->min_xfer_size = parse_size_directive(opt_arg);
+ break;
+ case 'X':
+ cl_opts->max_xfer_size = parse_size_directive(opt_arg);
+ break;
case 'h':
usage(progname);
exit(EXIT_SUCCESS);
@@ -335,6 +476,94 @@ parse_command_line(int argc, char *argv[])
return cl_opts;
}
+/*
+ * Function: parse_size_directive
+ * Purpose: Parse the size directive passed on the commandline. The size
+ * directive is an integer followed by a size indicator:
+ *
+ * K, k - Kilobyte
+ * M, m - Megabyte
+ * G, g - Gigabyte
+ *
+ * Return: The size as a LONG. If an unknown size indicator is used, then
+ * the program will exit with EXIT_FAILURE as the return value.
+ * Programmer: Bill Wendling, 18. December 2001
+ * Modifications:
+ */
+static long
+parse_size_directive(const char *size)
+{
+ long s;
+ char *endptr;
+
+ s = strtol(size, &endptr, 10);
+
+ if (endptr && *endptr) {
+ while (*endptr != '\0' && (*endptr == ' ' || *endptr == '\t'))
+ ++endptr;
+
+ switch (*endptr) {
+ case 'K':
+ case 'k':
+ s *= ONE_KB;
+ break;
+ case 'M':
+ case 'm':
+ s *= ONE_MB;
+ break;
+ case 'G':
+ case 'g':
+ s *= ONE_GB;
+ break;
+ default:
+ fprintf(stderr, "Illegal size specifier '%c'\n", *endptr);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ return s;
+}
+
+/*
+ * Function: usage
+ * Purpose: Print a usage message and then exit.
+ * Return: Nothing
+ * Programmer: Bill Wendling, 31. October 2001
+ * Modifications:
+ */
+static void
+usage(const char *prog)
+{
+ fflush(stdout);
+ fprintf(stdout, "usage: %s [OPTIONS]\n", prog);
+ fprintf(stdout, " OPTIONS\n");
+ fprintf(stdout, " -h, --help Print a usage message and exit\n");
+ fprintf(stdout, " -d N, --num-dsets=N Number of datasets per file [default:1]\n");
+ fprintf(stdout, " -f S, --file-size=S Size of a single file [default: 64M]\n");
+ fprintf(stdout, " -F N, --num-files=N Number of files [default: 1]\n");
+ fprintf(stdout, " -H, --hdf5 Run HDF5 performance test\n");
+ fprintf(stdout, " -i, --num-iterations Number of iterations to perform [default: 1]\n");
+ fprintf(stdout, " -m, --mpiio Run MPI/IO performance test\n");
+ fprintf(stdout, " -o F, --output=F Output raw data into file F [default: none]\n");
+ fprintf(stdout, " -P N, --max-num-processes=N Maximum number of processes to use [default: 1]\n");
+ fprintf(stdout, " -p N, --min-num-processes=N Minimum number of processes to use [default: 1]\n");
+ fprintf(stdout, " -r, --raw Run raw (UNIX) performance test\n");
+ fprintf(stdout, " -X S, --max-xfer-size=S Maximum transfer buffer size [default: 1M]\n");
+ fprintf(stdout, " -x S, --min-xfer-size=S Minimum transfer buffer size [default: 1K]\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, " F - is a filename.\n");
+ fprintf(stdout, " N - is an integer >=0.\n");
+ fprintf(stdout, " S - is a size specifier, an integer >=0 followed by a size indicator:\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, " K - Kilobyte\n");
+ fprintf(stdout, " M - Megabyte\n");
+ fprintf(stdout, " G - Gigabyte\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, " Example: 37M = 37 Megabytes\n");
+ fprintf(stdout, "\n");
+ fflush(stdout);
+}
+
#else /* H5_HAVE_PARALLEL */
/*
diff --git a/perform/pio_perf.h b/perform/pio_perf.h
index fb25f62..d954591 100644
--- a/perform/pio_perf.h
+++ b/perform/pio_perf.h
@@ -17,12 +17,12 @@ typedef enum iotype_ {
} iotype;
typedef struct parameters_ {
- int max_num_procs; /* Maximum number of processes to use */
- iotype io_type; /* The type of IO test to perform */
- int num_files; /* Number of files to create */
- long num_dsets; /* Number of datasets to create */
- long num_elmts; /* Number of native ints in each dset */
- int num_iters; /* Number of times to loop doing the IO */
+ iotype io_type; /* The type of IO test to perform */
+ int num_procs; /* Maximum number of processes to use */
+ int num_files; /* Number of files to create */
+ long num_dsets; /* Number of datasets to create */
+ long num_elmts; /* Number of native ints in each dset */
+ int num_iters; /* Number of times to loop doing the IO */
long buf_size; /* Buffer size */
} parameters;