From 2763df7a3c9f3e9e7a37265acadf8a4239a58e88 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 4 Nov 2002 13:45:09 -0500 Subject: [svn-r6052] Purpose: Add benchmark Description: Add multi-D hyperslab benchmark to repo. It's not hooked up to any makefiles yet, so it's not being compiled or tested, etc. I'm just stashing it here so I don't forget about it until I have time to integrate it properly. --- perform/benchpar.c | 476 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 476 insertions(+) create mode 100644 perform/benchpar.c diff --git a/perform/benchpar.c b/perform/benchpar.c new file mode 100644 index 0000000..86f6526 --- /dev/null +++ b/perform/benchpar.c @@ -0,0 +1,476 @@ +#include +#include +#include +#include "hdf5.h" + +/* Local macros */ + +/* defines for type of VFL driver to use */ +#define FACC_DEFAULT 0 +#define FACC_MPIO 1 +#define FACC_MPIPOSIX 2 + +/* Defines for computing performance information */ +#define ONE_KB 1024 +#define ONE_MB (ONE_KB * ONE_KB) +#define ONE_GB (ONE_MB * ONE_KB) +/* report 0.0 in case t is zero too */ +#define MB_PER_SEC(bytes,t) (((t)==0.0) ? 0.0 : ((((double)bytes) / ONE_MB) / (t))) + +/* Control default behavior (with no command line arguments) */ +#define DEFAULT_RANK 3 +#define DEFAULT_DIM 1024 +#define DEFAULT_PREFIX "/tmp" +#define DEFAULT_USERNAME "koziol" +#define DEFAULT_FILENAME "benchpar.h5" +#define DEFAULT_SLICE 0 +#define DEFAULT_C_TYPE int +#define DEFAULT_HDF5_DATATYPE H5T_NATIVE_INT /* Keep this in sync with the DEFAULT_C_TYPE */ +#define DEFAULT_DATASET_NAME "Dataset" +#define DEFAULT_VFL_DRIVER FACC_MPIO +#define DEFAULT_PAR_MODE H5FD_MPIO_COLLECTIVE +#define DEFAULT_CHUNK_STORAGE 0 +#define DEFAULT_ITER 3 + +/* MPI info */ +int mpi_rank, mpi_size; +int mpi_namelen; +char mpi_name[MPI_MAX_PROCESSOR_NAME]; + +/* Usage information */ +static void usage(void) +{ + printf("usage: benchpar [-d <# of dims>] [-s ] [-f ] [-h]\n"); + printf(" [-S ] [-p] [-I] [-c] [-i <# of iterations>\n"); + printf(" -c - Use chunked storage for dataset with 1-1 exact\n"); + printf(" mapping of chunks to hyperslabs\n"); + printf(" Default: off (i.e. contiguous storage)\n"); + printf(" -d <# of dims> - Number of dimensions of the dataset\n"); + printf(" Default: 3\n"); + printf(" -f - Set the name of the test file\n"); + printf(" Default: /tmp//benchpar.h5\n"); + printf(" -h - Prints usage information\n"); + printf(" -i <# of iters> - Set the number of test iterations to perform\n"); + printf(" Default: 3\n"); + printf(" -I - Use independent parallel I/O\n"); + printf(" Default: use collective parallel I/O\n"); + printf(" -p - Use MPI-posix VFL driver\n"); + printf(" Default: use MPI-I/O VFL driver\n"); + printf(" -s - Set the size of each of the dataset's dimensions\n"); + printf(" Default: 1024\n"); + printf(" -S - Set the dimension to slice the dataset along\n"); + printf(" Default: 0\n"); +} /* end usage() */ + +/* Create & initialize file creation property list with appropriate properties */ +static hid_t create_fcpl(void) +{ + hid_t fcpl; /* File creation property list */ + + fcpl=H5Pcreate(H5P_FILE_CREATE); + assert(fcpl>0); + + return(fcpl); +} /* end create_fcpl() */ + +/* Create & initialize file access property list with appropriate properties */ +static hid_t create_fapl(MPI_Comm comm, MPI_Info info, int acc_type ) +{ + hid_t fapl; /* File access property list */ + herr_t ret; /* Generic return value */ + + fapl = H5Pcreate (H5P_FILE_ACCESS); + assert(fapl>0); + + /* set parallel access with communicator, using MPI-I/O driver */ + if (acc_type == FACC_MPIO) { + ret = H5Pset_fapl_mpio(fapl, comm, info); + assert(ret>=0); + } /* end if */ + + /* set parallel access with communicator, using MPI-posix driver */ + if (acc_type == FACC_MPIPOSIX) { + ret = H5Pset_fapl_mpiposix(fapl, comm); + assert(ret>=0); + } /* end if */ + + return (fapl); +} /* end create_fapl() */ + +/* Create & initialize dataset creation property list with appropriate properties */ +static hid_t create_dcpl(unsigned use_chunks, int rank, hsize_t *dims) +{ + hid_t dcpl; /* Dataset creation property list */ + herr_t ret; /* Generic return value */ + + dcpl=H5Pcreate(H5P_DATASET_CREATE); + assert(dcpl>0); + + /* Check if the dataset should be chunked */ + if(use_chunks) { + ret = H5Pset_chunk(dcpl, rank, dims); + assert(ret>=0); + } /* end if */ + + return(dcpl); +} /* end create_dcpl() */ + +/* Create & initialize dataset transfer property list with appropriate properties */ +static hid_t create_dxpl(H5FD_mpio_xfer_t par_mode) +{ + hid_t dxpl; /* Dataset creation property list */ + herr_t ret; /* Generic return value */ + + dxpl=H5Pcreate(H5P_DATASET_XFER); + assert(dxpl>0); + + /* Set collective I/O on this transfer */ + ret=H5Pset_dxpl_mpio(dxpl, par_mode); + assert(ret>=0); + + return(dxpl); +} /* end create_dcpl() */ + +int main(int argc, char *argv[]) +{ + int curr_arg; /* Current command line argument being processed */ + int rank; /* Number of dimensions of the dataset */ + hsize_t dim_size; /* Dimension size of each dimension */ + hsize_t *dims; /* Pointer to array of dimensions */ + hssize_t *start; /* Pointer to array of starting locations for hyperslab selection */ + hsize_t *count; /* Pointer to array of counts for hyperslab selection */ + unsigned slice_dim; /* Dimension to slice up */ + char *file_name=NULL; /* Name of file to put data into */ + hid_t fcpl; /* HDF5 File creation property list ID */ + hid_t fapl; /* HDF5 File access property list ID */ + hid_t dcpl; /* HDF5 Dataset creation property list ID */ + hid_t dxpl; /* HDF5 Dataset transfer property list ID */ + hid_t fid; /* HDF5 file ID */ + hid_t dsid; /* HDF5 dataset ID */ + hid_t file_sid; /* HDF5 dataspace ID for dataset on disk */ + hid_t mem_sid; /* HDF5 dataspace ID for dataset in memory */ + DEFAULT_C_TYPE *buf; /* Buffer to write out */ + hsize_t buf_size; /* Size of buffer to write */ + int i; /* Local index variable */ + herr_t ret; /* Generic return value */ + double start_write_time, end_write_time, elap_write_time; /* Start, end and elapsed time to write raw data */ + double tmp_max_write_time; /* Temporary holders for maximum time for all nodes to perform raw data I/O */ + double max_write_time=-DBL_MAX, min_write_time=DBL_MAX; /* Minimum & maximum time for all nodes to perform raw data I/O */ + double start_file_time, end_file_time, elap_file_time; /* Start, end and elapsed time from file open to file close */ + double tmp_max_file_time; /* Temporary holders for maximum time for all nodes from file open to file close */ + double max_file_time=-DBL_MAX, min_file_time=DBL_MAX; /* Minimum & maximum time for all nodes from file open to file close */ + int vfl_type; /* Type of VFL driver to use */ + H5FD_mpio_xfer_t par_mode; /* Type of parallel I/O to perform */ + unsigned use_chunks; /* Whether to use chunks for dataset or not */ + unsigned num_iter; /* Number of iterations to perform */ + unsigned u; /* Local index variable */ + + /* Un-buffer the stdout and stderr */ + setbuf(stderr, NULL); + setbuf(stdout, NULL); + + /* MPI initialization */ + MPI_Init(&argc,&argv); + MPI_Comm_size(MPI_COMM_WORLD,&mpi_size); + MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank); + MPI_Get_processor_name(mpi_name,&mpi_namelen); + + /* Set some defaults */ + rank=DEFAULT_RANK; + dim_size=DEFAULT_DIM; + slice_dim=DEFAULT_SLICE; + vfl_type=DEFAULT_VFL_DRIVER; + par_mode=DEFAULT_PAR_MODE; + use_chunks=DEFAULT_CHUNK_STORAGE; + num_iter=DEFAULT_ITER; + + /* Parse command line arguments */ + if(argc>1) { + curr_arg=1; + while(curr_arg=rank) { + printf("rank=%d, error, slice dim larger than rank: slice_dim=%d, rank=%d\n",mpi_rank,slice_dim,rank); + goto done; + } /* end if */ + + /* Set rest of defaults */ + if(file_name==NULL) { + char *login; /* Pointer to login name */ + + /* Get the login name for this user */ + login=getlogin(); + if(login==NULL) + login=DEFAULT_USERNAME; + + /* Allocate enough room for the prefix, the login name, two '/'s, the filename and the string terminator */ + file_name=malloc(strlen(DEFAULT_PREFIX)+1+strlen(login)+1+strlen(DEFAULT_FILENAME)+1); + strcpy(file_name,DEFAULT_PREFIX); + strcat(file_name,"/"); + strcat(file_name,login); + strcat(file_name,"/"); + strcat(file_name,DEFAULT_FILENAME); + } /* end if */ + + /* Allocate memory for this process's portion of dataset */ + buf_size=sizeof(DEFAULT_C_TYPE); + for(i=0; i0); + + /* Create file access property list */ + fapl=create_fapl(MPI_COMM_WORLD,MPI_INFO_NULL,vfl_type); + assert(fapl>0); + + /* Get file start time */ + start_file_time = MPI_Wtime(); + + /* Create file */ + fid=H5Fcreate(file_name,H5F_ACC_TRUNC,fcpl,fapl); + assert(fid>0); + + /* Close file creation property list */ + ret=H5Pclose(fcpl); + assert(ret>=0); + + /* Close file access property list */ + ret=H5Pclose(fapl); + assert(ret>=0); + + /* Create dataspace for dataset on disk */ + dims=malloc(sizeof(hsize_t)*rank); + assert(dims); + for(i=0; i0); + + /* Create dataspace for buffer in memory */ + for(i=0; i0); + + /* Create dataset creation property list */ + dcpl=create_dcpl(use_chunks,rank,dims); + assert(dcpl>0); + + /* Create dataset */ + dsid=H5Dcreate(fid,DEFAULT_DATASET_NAME,DEFAULT_HDF5_DATATYPE,file_sid,dcpl); + assert(dsid>0); + + /* Close dataset creation property list */ + ret=H5Pclose(dcpl); + assert(ret>=0); + + /* Select hyperslab for file dataspace */ + start=malloc(sizeof(hssize_t)*rank); + assert(start); + count=malloc(sizeof(hsize_t)*rank); + assert(count); + for(i=0; i=0); + + /* Create dataset transfer property list */ + dxpl=create_dxpl(par_mode); + assert(dxpl>0); + + /* Get raw data start time */ + start_write_time = MPI_Wtime(); + + /* Write hyperslab to dataset */ + ret = H5Dwrite(dsid, DEFAULT_HDF5_DATATYPE, mem_sid, + file_sid, dxpl, buf); + assert(ret>=0); + + /* Get stop time for raw data timer */ + end_write_time = MPI_Wtime(); + + /* Close dataset transfer property list */ + ret=H5Pclose(dxpl); + assert(ret>=0); + + /* Close memory dataspace */ + ret=H5Sclose(mem_sid); + assert(ret>=0); + + /* Close file dataspace */ + ret=H5Sclose(file_sid); + assert(ret>=0); + + /* Close dataset */ + ret=H5Dclose(dsid); + assert(ret>=0); + + /* Close file */ + ret=H5Fclose(fid); + assert(ret>=0); + + /* Get stop time for file timer */ + end_file_time = MPI_Wtime(); + + /* Compute timing results */ + elap_write_time=end_write_time-start_write_time; + elap_file_time=end_file_time-start_file_time; + + /* Collect the minimum and maximum times by MPI reduces */ + MPI_Allreduce(&elap_write_time, &tmp_max_write_time, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + MPI_Allreduce(&elap_file_time, &tmp_max_file_time, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + + /* Track the fastest & slowest total runs */ + if(tmp_max_write_time>max_write_time) + max_write_time=tmp_max_write_time; + if(tmp_max_write_timemax_file_time) + max_file_time=tmp_max_file_time; + if(tmp_max_file_time