summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2003-10-14 22:04:03 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2003-10-14 22:04:03 (GMT)
commita1aa262020f230c88c7b188de87119f6ff72f1a8 (patch)
tree9c08f8e3ad974fefcd2fddf2be48e6e0f2ae6afc
parente2518919c959dbf1bdb0890151cae91293e0594d (diff)
downloadhdf5-a1aa262020f230c88c7b188de87119f6ff72f1a8.zip
hdf5-a1aa262020f230c88c7b188de87119f6ff72f1a8.tar.gz
hdf5-a1aa262020f230c88c7b188de87119f6ff72f1a8.tar.bz2
[svn-r7629] Purpose: add a new performance program
Description: This program test performance of create or open datasets and create attributes for datasets. Platforms tested: h5committest Misc. update: MANIFEST
-rw-r--r--perform/Makefile.in8
-rw-r--r--perform/perf_meta.c877
2 files changed, 883 insertions, 2 deletions
diff --git a/perform/Makefile.in b/perform/Makefile.in
index 90bb22c..7228919 100644
--- a/perform/Makefile.in
+++ b/perform/Makefile.in
@@ -29,7 +29,7 @@ LIBTOOLS=../tools/lib/libh5tools.la
## These are the programs that `make all' or `make tests' will build and which
## `make check' will run. List them in the order they should be run.
TEST_PROGS_PARA=h5perf
-TEST_PROGS=iopipe chunk overhead zip_perf
+TEST_PROGS=iopipe chunk overhead zip_perf perf_meta
PUB_PROGS=h5perf
@@ -45,7 +45,7 @@ PIO_PERF_OBJ=$(PIO_PERF_SRC:.c=.lo)
TEST_SRC_PARA=$(PIO_PERF_SRC)
-TEST_SRC=iopipe.c chunk.c overhead.c zip_perf.c $(TEST_SRC_PARA)
+TEST_SRC=iopipe.c chunk.c overhead.c zip_perf.c perf_meta.c $(TEST_SRC_PARA)
TEST_OBJ=$(TEST_SRC:.c=.lo)
## How to build the programs... they all depend on the hdf5 library
@@ -76,4 +76,8 @@ zip_perf: zip_perf.lo
@$(LT_LINK_EXE) $(CFLAGS) -o $@ zip_perf.lo $(LIBH5TEST) \
$(LIBTOOLS) $(LIBHDF5) $(LDFLAGS) $(LIBS)
+perf_meta: perf_meta.lo
+ @$(LT_LINK_EXE) $(CFLAGS) -o $@ perf_meta.lo $(LIBH5TEST) $(LIBHDF5) \
+ $(LDFLAGS) $(LIBS)
+
@CONCLUDE@
diff --git a/perform/perf_meta.c b/perform/perf_meta.c
new file mode 100644
index 0000000..ad61e8f
--- /dev/null
+++ b/perform/perf_meta.c
@@ -0,0 +1,877 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Raymond Lu <slu@ncsa.uiuc.edu>
+ * Friday, Oct 3, 2004
+ *
+ * Purpose: Tests performance of metadata
+ */
+
+#include "h5test.h"
+#include <sys/time.h>
+
+#ifdef H5_HAVE_PARALLEL
+#define MAINPROCESS (!mpi_rank) /* define process 0 as main process */
+#endif /*H5_HAVE_PARALLEL*/
+
+/* File_Access_type bits */
+#define FACC_DEFAULT 0x0 /* serial as default */
+#define FACC_MPIO 0x1 /* MPIO */
+#define FACC_MPIPOSIX 0x8 /* MPIPOSIX */
+
+const char *FILENAME[] = {
+ "meta_perf_1.h5",
+ "meta_perf_2.h5",
+ "meta_perf_3.h5",
+ "meta_perf_4.h5",
+ NULL
+};
+
+/* Default values for performance. Can be changed through command line options */
+int NUM_DSETS = 16;
+int NUM_ATTRS = 8;
+int BATCH_ATTRS = 2;
+int nerrors = 0; /* errors count */
+hid_t fapl;
+
+/* Data space IDs */
+hid_t space;
+hid_t small_space;
+
+/* Performance data */
+typedef struct p_time {
+ double total;
+ double avg;
+ double max;
+ double min;
+ double start;
+ char func[32];
+} p_time;
+
+/*Test file access type for parallel. MPIO as default */
+int facc_type = FACC_DEFAULT;
+
+double retrieve_time(void);
+void perf(p_time *perf_t, double start_t, double end_t);
+void print_perf(p_time, p_time, p_time);
+
+
+/*-------------------------------------------------------------------------
+ * Function: parse_options
+ *
+ Purpose: Parse command line options
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+parse_options(int argc, char **argv)
+{
+ /* Use default values */
+ if(argc==1)
+ return(0);
+
+ while (--argc){
+ if (**(++argv) != '-'){
+ break;
+ }else{
+ switch(*(*argv+1)){
+ case 'h': /* Help page */
+ return(1);
+
+ case 'd': /* Number of datasets */
+ NUM_DSETS = atoi((*argv+1)+1);
+ if (NUM_DSETS < 0){
+ nerrors++;
+ return(1);
+ }
+ break;
+
+ case 'a': /* Number of attributes per dataset */
+ NUM_ATTRS = atoi((*argv+1)+1);
+ if (NUM_ATTRS < 0){
+ nerrors++;
+ return(1);
+ }
+ break;
+
+ case 'n': /* Number of attributes to be created in batch */
+ BATCH_ATTRS = atoi((*argv+1)+1);
+ if (BATCH_ATTRS < 0){
+ nerrors++;
+ return(1);
+ }
+ break;
+
+ case 'p': /* Use the MPI-POSIX driver access */
+ facc_type = FACC_MPIPOSIX;
+ break;
+
+ case 'm': /* Use the MPI-POSIX driver access */
+ facc_type = FACC_MPIO;
+ break;
+
+ default: nerrors++;
+ return(1);
+ }
+ }
+ } /*while*/
+
+ /* Check valid values */
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX)
+#ifdef H5_HAVE_PARALLEL
+ ;
+#else
+ {
+ nerrors++;
+ return(1);
+ }
+#endif /*H5_HAVE_PARALLEL*/
+
+
+ if(!NUM_DSETS) {
+ nerrors++;
+ return(1);
+ }
+
+ if((NUM_ATTRS && !BATCH_ATTRS) || (!NUM_ATTRS && BATCH_ATTRS)) {
+ nerrors++;
+ return(1);
+ }
+
+ if(NUM_ATTRS && BATCH_ATTRS) {
+ if(BATCH_ATTRS > NUM_ATTRS || NUM_ATTRS % BATCH_ATTRS) {
+ nerrors++;
+ return(1);
+ }
+ }
+
+ return(0);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: usage
+ *
+ Purpose: Prints help page
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+usage(void)
+{
+ printf("Usage: perf_meta [-h] [-m] [-p] [-d<num_datasets>] [-a<num_attributes>] [-n<batch_attributes>\n");
+ printf("\t-h"
+ "\t\t\thelp page.\n");
+ printf("\t-m"
+ "\t\t\tset MPIO as the file driver when parallel HDF5 is enabled."
+ " either -m or -p has be to specified when running parallel program\n");
+ printf("\t-p"
+ "\t\t\tset MPI POSIX as the file driver when parallel HDF5 is enabled."
+ " either -m or -p has be to specified when running parallel program\n");
+ printf("\t-d<num_datasets>"
+ "\tset number of datasets for meta data performance test\n");
+ printf("\t-a<num_attributes>"
+ "\tset number of attributes per dataset for meta data performance test\n");
+ printf("\t-n<batch_attributes>"
+ "\tset batch of attributes for dataset for meta data performance test\n");
+ printf("\n");
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: create_dspace
+ *
+ * Purpose: Attempts to create data space.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+create_dspace(void)
+{
+ hsize_t dims[2];
+ hsize_t small_dims[2];
+
+ /* Create the data space */
+ dims[0] = 256;
+ dims[1] = 512;
+ if((space = H5Screate_simple(2, dims, NULL)) < 0)
+ goto error;
+
+ /* Create a small data space for attributes */
+ small_dims[0] = 16;
+ small_dims[1] = 8;
+ if((small_space = H5Screate_simple(2, small_dims, NULL)) < 0)
+ goto error;
+
+ return 0;
+
+error:
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: create_dsets
+ *
+ * Purpose: Attempts to create some datasets.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+create_dsets(hid_t file)
+{
+ hid_t dataset;
+ char dset_name[32];
+ int i;
+
+ /*
+ * Create a dataset using the default dataset creation properties.
+ */
+ for(i=0; i<NUM_DSETS; i++) {
+ sprintf(dset_name, "dataset %d", i);
+ if((dataset = H5Dcreate(file, dset_name, H5T_NATIVE_DOUBLE,
+ space, H5P_DEFAULT)) < 0)
+ goto error;
+
+ if (H5Dclose(dataset) < 0) goto error;
+ }
+
+ return 0;
+
+error:
+ return -1;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: create_attrs_1
+ *
+ * Purpose: Attempts to create all attributes for each existing dataset.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+create_attrs_1(void)
+{
+ hid_t file, dataset, attr;
+ char dset_name[64];
+ char attr_name[128];
+ int i, j;
+ p_time attr_t = {0, 0, 0, 1000000, 0, ""};
+ p_time open_t = {0, 0, 0, 1000000, 0, "H5Dopen"};
+ p_time close_t = {0, 0, 0, 1000000, 0, ""};
+
+#ifdef H5_HAVE_PARALLEL
+ /* need the rank for printing data */
+ int mpi_rank;
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX)
+ MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
+#endif /*H5_HAVE_PARALLEL*/
+
+ if ((file=H5Fcreate(FILENAME[0], H5F_ACC_TRUNC, H5P_DEFAULT,
+ fapl))<0)
+ goto error;
+
+ if(create_dsets(file)<0)
+ goto error;
+
+ /*
+ * Create all(user specifies the number) attributes for each dataset
+ */
+ for(i=0; i<NUM_DSETS; i++) {
+ sprintf(dset_name, "dataset %d", i);
+ open_t.start = retrieve_time();
+ if((dataset=H5Dopen(file, dset_name))<0)
+ goto error;
+ perf(&open_t, open_t.start, retrieve_time());
+
+ for(j=0; j<NUM_ATTRS; j++) {
+ sprintf(attr_name, "all attrs for each dset %d", j);
+ attr_t.start = retrieve_time();
+ if((attr = H5Acreate(dataset, attr_name, H5T_NATIVE_DOUBLE,
+ small_space, H5P_DEFAULT)) < 0)
+ goto error;
+ if (H5Aclose(attr) < 0) goto error;
+ perf(&attr_t, attr_t.start, retrieve_time());
+ }
+
+ close_t.start = retrieve_time();
+ if(H5Dclose(dataset)<0) goto error;
+ perf(&close_t, close_t.start, retrieve_time());
+ }
+
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX) {
+#ifdef H5_HAVE_PARALLEL
+ MPI_Barrier(MPI_COMM_WORLD);
+#endif /*H5_HAVE_PARALLEL*/
+ }
+
+#ifdef H5_HAVE_PARALLEL
+ if (facc_type == FACC_DEFAULT || (facc_type != FACC_DEFAULT && MAINPROCESS)) /* only process 0 reports */
+#endif /*H5_HAVE_PARALLEL*/
+ {
+ /* Calculate the average time */
+ open_t.avg = open_t.total / NUM_DSETS;
+ close_t.avg = close_t.total / NUM_DSETS;
+ if(NUM_ATTRS)
+ attr_t.avg = attr_t.total / (NUM_ATTRS*NUM_DSETS);
+
+ /* Print out the performance result */
+ fprintf(stderr, "1. Create %d attributes for each of %d existing datasets\n",
+ NUM_ATTRS, NUM_DSETS);
+ print_perf(open_t, close_t, attr_t);
+ }
+
+ if (H5Fclose(file)<0) goto error;
+
+ return 0;
+
+error:
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: create_attrs_2
+ *
+ * Purpose: Attempts to create all attributes for each new dataset.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+create_attrs_2(void)
+{
+ hid_t file, dataset, attr;
+ char dset_name[64];
+ char attr_name[128];
+ int i, j;
+ p_time attr_t = {0, 0, 0, 1000000, 0, ""};
+ p_time create_t = {0, 0, 0, 1000000, 0, "H5Dcreate"};
+ p_time close_t = {0, 0, 0, 1000000, 0, ""};
+
+#ifdef H5_HAVE_PARALLEL
+ /* need the rank for printing data */
+ int mpi_rank;
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX)
+ MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
+#endif /*H5_HAVE_PARALLEL*/
+
+ if ((file=H5Fcreate(FILENAME[1], H5F_ACC_TRUNC, H5P_DEFAULT,
+ fapl))<0)
+ goto error;
+
+ /*
+ * Create all(user specifies the number) attributes for each new dataset
+ */
+ for(i=0; i<NUM_DSETS; i++) {
+ sprintf(dset_name, "dataset %d", i);
+ create_t.start = retrieve_time();
+ if((dataset = H5Dcreate(file, dset_name, H5T_NATIVE_DOUBLE,
+ space, H5P_DEFAULT)) < 0)
+ goto error;
+ perf(&create_t, create_t.start, retrieve_time());
+
+ for(j=0; j<NUM_ATTRS; j++) {
+ sprintf(attr_name, "all attrs for each dset %d", j);
+ attr_t.start = retrieve_time();
+ if((attr = H5Acreate(dataset, attr_name, H5T_NATIVE_DOUBLE,
+ small_space, H5P_DEFAULT)) < 0)
+ goto error;
+ if (H5Aclose(attr) < 0) goto error;
+ perf(&attr_t, attr_t.start, retrieve_time());
+ }
+
+ close_t.start = retrieve_time();
+ if(H5Dclose(dataset)<0) goto error;
+ perf(&close_t, close_t.start, retrieve_time());
+ }
+
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX) {
+#ifdef H5_HAVE_PARALLEL
+ MPI_Barrier(MPI_COMM_WORLD);
+#endif /*H5_HAVE_PARALLEL*/
+ }
+
+#ifdef H5_HAVE_PARALLEL
+ /* only process 0 reports if parallel */
+ if (facc_type == FACC_DEFAULT || (facc_type != FACC_DEFAULT && MAINPROCESS))
+#endif /*H5_HAVE_PARALLEL*/
+ {
+ /* Calculate the average time */
+ create_t.avg = create_t.total / NUM_DSETS;
+ close_t.avg = close_t.total / NUM_DSETS;
+ if(NUM_ATTRS)
+ attr_t.avg = attr_t.total / (NUM_ATTRS*NUM_DSETS);
+
+ /* Print out the performance result */
+ fprintf(stderr, "2. Create %d attributes for each of %d new datasets\n",
+ NUM_ATTRS, NUM_DSETS);
+ print_perf(create_t, close_t, attr_t);
+ }
+
+ if (H5Fclose(file)<0) goto error;
+
+ return 0;
+
+error:
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: create_attrs_3
+ *
+ * Purpose: Attempts to create one attribute for each dataset in a loop.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+create_attrs_3(void)
+{
+ hid_t file, dataset, attr;
+ char dset_name[64];
+ char attr_name[128];
+ int i, j;
+ p_time attr_t = {0, 0, 0, 1000000, 0, ""};
+ p_time open_t = {0, 0, 0, 1000000, 0, "H5Dopen"};
+ p_time close_t = {0, 0, 0, 1000000, 0, ""};
+
+#ifdef H5_HAVE_PARALLEL
+ /* need the rank for printing data */
+ int mpi_rank;
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX)
+ MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
+#endif /*H5_HAVE_PARALLEL*/
+
+ if ((file=H5Fcreate(FILENAME[2], H5F_ACC_TRUNC, H5P_DEFAULT,
+ fapl))<0)
+ goto error;
+
+ if(create_dsets(file)<0)
+ goto error;
+
+ /*
+ * Create one attribute for each existing dataset in a loop
+ */
+ for(i=0; i<NUM_ATTRS; i++) {
+ sprintf(attr_name, "one attrs for each dset %d", i);
+ for(j=0; j<NUM_DSETS; j++) {
+ sprintf(dset_name, "dataset %d", j);
+ open_t.start = retrieve_time();
+ if((dataset = H5Dopen(file, dset_name)) < 0)
+ goto error;
+ perf(&open_t, open_t.start, retrieve_time());
+
+ attr_t.start = retrieve_time();
+ if((attr = H5Acreate(dataset, attr_name, H5T_NATIVE_DOUBLE,
+ small_space, H5P_DEFAULT)) < 0)
+ goto error;
+ if (H5Aclose(attr) < 0) goto error;
+ perf(&attr_t, attr_t.start, retrieve_time());
+
+ close_t.start = retrieve_time();
+ if(H5Dclose(dataset)<0) goto error;
+ perf(&close_t, close_t.start, retrieve_time());
+ }
+ }
+
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX) {
+#ifdef H5_HAVE_PARALLEL
+ MPI_Barrier(MPI_COMM_WORLD);
+#endif /*H5_HAVE_PARALLEL*/
+ }
+
+#ifdef H5_HAVE_PARALLEL
+ /* only process 0 reports if parallel */
+ if (facc_type == FACC_DEFAULT || (facc_type != FACC_DEFAULT && MAINPROCESS))
+#endif /*H5_HAVE_PARALLEL*/
+ {
+ /* Calculate the average time */
+ open_t.avg = open_t.total / (NUM_ATTRS*NUM_DSETS);
+ close_t.avg = close_t.total / (NUM_ATTRS*NUM_DSETS);
+ attr_t.avg = attr_t.total / (NUM_ATTRS*NUM_DSETS);
+
+ /* Print out the performance result */
+ fprintf(stderr, "3. Create one attribute for each of %d existing datasets for %d times\n",
+ NUM_DSETS, NUM_ATTRS);
+ print_perf(open_t, close_t, attr_t);
+ }
+
+ if (H5Fclose(file)<0) goto error;
+
+ return 0;
+
+error:
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: create_attrs_4
+ *
+ * Purpose: Attempts to create some attributes for each dataset in a
+ * loop.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+create_attrs_4(void)
+{
+ hid_t file, dataset, attr;
+ char dset_name[64];
+ char attr_name[128];
+ int loop_num;
+ int i, j, k;
+ p_time attr_t = {0, 0, 0, 1000000, 0, ""};
+ p_time open_t = {0, 0, 0, 1000000, 0, "H5Dopen"};
+ p_time close_t = {0, 0, 0, 1000000, 0, ""};
+
+#ifdef H5_HAVE_PARALLEL
+ /* need the rank for printing data */
+ int mpi_rank;
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX)
+ MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
+#endif /*H5_HAVE_PARALLEL*/
+
+ if ((file=H5Fcreate(FILENAME[3], H5F_ACC_TRUNC, H5P_DEFAULT,
+ fapl))<0)
+ goto error;
+
+ if(create_dsets(file)<0)
+ goto error;
+
+ /*
+ * Create some(user specifies the number) attributes for each dataset
+ * in a loop
+ */
+ loop_num = NUM_ATTRS/BATCH_ATTRS;
+
+ for(i=0; i<loop_num; i++) {
+ for(j=0; j<NUM_DSETS; j++) {
+ sprintf(dset_name, "dataset %d", j);
+ open_t.start = retrieve_time();
+ if((dataset = H5Dopen(file, dset_name)) < 0)
+ goto error;
+ perf(&open_t, open_t.start, retrieve_time());
+
+ for(k=0; k<BATCH_ATTRS; k++) {
+ sprintf(attr_name, "some attrs for each dset %d %d",
+ i, k);
+ attr_t.start = retrieve_time();
+ if((attr = H5Acreate(dataset, attr_name,
+ H5T_NATIVE_DOUBLE, small_space, H5P_DEFAULT))
+ < 0) goto error;
+ if (H5Aclose(attr) < 0) goto error;
+ perf(&attr_t, attr_t.start, retrieve_time());
+
+ }
+
+ close_t.start = retrieve_time();
+ if(H5Dclose(dataset)<0) goto error;
+ perf(&close_t, close_t.start, retrieve_time());
+ }
+ }
+
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX) {
+#ifdef H5_HAVE_PARALLEL
+ MPI_Barrier(MPI_COMM_WORLD);
+#endif /*H5_HAVE_PARALLEL*/
+ }
+
+#ifdef H5_HAVE_PARALLEL
+ /* only process 0 reports if parallel */
+ if (facc_type == FACC_DEFAULT || (facc_type != FACC_DEFAULT && MAINPROCESS))
+#endif /*H5_HAVE_PARALLEL*/
+ {
+ /* Calculate the average time */
+ open_t.avg = open_t.total / (loop_num*NUM_DSETS);
+ close_t.avg = close_t.total / (loop_num*NUM_DSETS);
+ attr_t.avg = attr_t.total / (NUM_ATTRS*NUM_DSETS);
+
+ /* Print out the performance result */
+ fprintf(stderr, "4. Create %d attributes for each of %d existing datasets for %d times\n",
+ BATCH_ATTRS, NUM_DSETS, loop_num);
+ print_perf(open_t, close_t, attr_t);
+ }
+
+ if (H5Fclose(file)<0) goto error;
+
+ return 0;
+
+error:
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: retrieve_time
+ *
+ * Purpose: Returns time in seconds, in a double number.
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+double retrieve_time(void)
+{
+ if(facc_type == FACC_DEFAULT) {
+ struct timeval t;
+ gettimeofday(&t, NULL);
+ return ((double)t.tv_sec + (double)t.tv_usec / 1000000);
+ } else {
+#ifdef H5_HAVE_PARALLEL
+ return MPI_Wtime();
+#endif /*H5_HAVE_PARALLEL*/
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: perf
+ *
+ * Purpose: Calculate total time, maximal and minimal time of
+ * performance.
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void perf(p_time *perf_t, double start_t, double end_t)
+{
+ double t = end_t - start_t;
+
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX) {
+#ifdef H5_HAVE_PARALLEL
+ double reduced_t;
+ double t_max, t_min;
+ int mpi_size, mpi_rank;
+
+ MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
+ MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ MPI_Reduce(&t, &reduced_t, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0,
+ MPI_COMM_WORLD);
+ reduced_t /= mpi_size;
+
+ MPI_Reduce(&t, &t_max, 1, MPI_DOUBLE_PRECISION, MPI_MAX, 0,
+ MPI_COMM_WORLD);
+ MPI_Reduce(&t, &t_min, 1, MPI_DOUBLE_PRECISION, MPI_MIN, 0,
+ MPI_COMM_WORLD);
+
+ if (MAINPROCESS) {
+ perf_t->total += reduced_t;
+
+ if(t_max > perf_t->max)
+ perf_t->max = t_max;
+ if(t_min < perf_t->min)
+ perf_t->min = t_min;
+ }
+#endif /*H5_HAVE_PARALLEL*/
+ } else {
+ perf_t->total += t;
+
+ if(t > perf_t->max)
+ perf_t->max = t;
+ if(t < perf_t->min)
+ perf_t->min = t;
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_perf
+ *
+ * Purpose: Print out performance data.
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void print_perf(p_time open_t, p_time close_t, p_time attr_t)
+{
+ fprintf(stderr, "\t%s:\t\tavg=%.6fs;\tmax=%.6fs;\tmin=%.6fs\n",
+ open_t.func, open_t.avg, open_t.max, open_t.min);
+ fprintf(stderr, "\tH5Dclose:\t\tavg=%.6fs;\tmax=%.6fs;\tmin=%.6fs\n",
+ close_t.avg, close_t.max, close_t.min);
+ if(NUM_ATTRS)
+ fprintf(stderr, "\tH5A(create & close):\tavg=%.6fs;\tmax=%.6fs;\tmin=%.6fs\n",
+ attr_t.avg, attr_t.max, attr_t.min);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Tests
+ *
+ * Return: Success: exit(0)
+ *
+ * Failure: exit(1)
+ *
+ * Programmer: Raymond Lu
+ * Friday, Oct 3, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main(int argc, char **argv)
+{
+#ifdef H5_HAVE_PARALLEL
+ int mpi_size, mpi_rank; /* mpi variables */
+#endif /*H5_HAVE_PARALLEL*/
+
+ if(parse_options(argc, argv) != 0) {
+ usage();
+ return 0;
+ }
+
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX) {
+#ifdef H5_HAVE_PARALLEL
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
+ MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
+#endif /*H5_HAVE_PARALLEL*/
+ }
+
+#ifdef H5_HAVE_PARALLEL
+ if (facc_type == FACC_DEFAULT || (facc_type != FACC_DEFAULT && MAINPROCESS))
+#endif /*H5_HAVE_PARALLEL*/
+ fprintf(stderr, "\t\tPerformance result of metadata for datasets and attributes\n\n");
+
+ fapl = H5Pcreate (H5P_FILE_ACCESS);
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX) {
+#ifdef H5_HAVE_PARALLEL
+ if(facc_type == FACC_DEFAULT || facc_type == FACC_MPIO)
+ H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL);
+ else if(facc_type == FACC_MPIPOSIX)
+ H5Pset_fapl_mpiposix(fapl, MPI_COMM_WORLD, FALSE);
+#endif /*H5_HAVE_PARALLEL*/
+ }
+
+ nerrors += create_dspace()<0 ?1:0;
+ nerrors += create_attrs_1()<0 ?1:0;
+ nerrors += create_attrs_2()<0 ?1:0;
+ if(NUM_ATTRS)
+ nerrors += create_attrs_3()<0 ?1:0;
+ if(BATCH_ATTRS)
+ nerrors += create_attrs_4()<0 ?1:0;
+
+ if (H5Sclose(space)<0) goto error;
+ if (H5Sclose(small_space)<0) goto error;
+
+ h5_cleanup(FILENAME, fapl);
+
+ if(facc_type == FACC_MPIO || facc_type == FACC_MPIPOSIX) {
+#ifdef H5_HAVE_PARALLEL
+ /* MPI_Finalize must be called AFTER H5close which may use MPI calls */
+ MPI_Finalize();
+#endif /*H5_HAVE_PARALLEL*/
+ }
+
+ if (nerrors) goto error;
+#ifdef H5_HAVE_PARALLEL
+ if (facc_type != FACC_DEFAULT && MAINPROCESS)
+#endif /*H5_HAVE_PARALLEL*/
+ printf("All metadata performance tests passed.\n");
+
+ return 0;
+
+ error:
+ nerrors = MAX(1, nerrors);
+#ifdef H5_HAVE_PARALLEL
+ if (facc_type != FACC_DEFAULT && MAINPROCESS)
+#endif /*H5_HAVE_PARALLEL*/
+ printf("***** %d PERFORMANCE TEST%s FAILED! *****\n",
+ nerrors, 1 == nerrors ? "" : "S");
+
+ return 1;
+}