diff options
Diffstat (limited to 'tools/perform')
-rw-r--r-- | tools/perform/CMakeLists.txt | 126 | ||||
-rw-r--r-- | tools/perform/CMakeTests.cmake | 54 | ||||
-rw-r--r-- | tools/perform/COPYING | 16 | ||||
-rw-r--r-- | tools/perform/Makefile.am | 79 | ||||
-rwxr-xr-x | tools/perform/build_h5perf_alone.sh | 28 | ||||
-rwxr-xr-x | tools/perform/build_h5perf_serial_alone.sh | 28 | ||||
-rw-r--r-- | tools/perform/chunk.c | 550 | ||||
-rwxr-xr-x | tools/perform/gen_report.pl | 527 | ||||
-rw-r--r-- | tools/perform/iopipe.c | 508 | ||||
-rw-r--r-- | tools/perform/overhead.c | 408 | ||||
-rw-r--r-- | tools/perform/perf.c | 494 | ||||
-rw-r--r-- | tools/perform/perf_meta.c | 850 | ||||
-rw-r--r-- | tools/perform/pio_engine.c | 2682 | ||||
-rw-r--r-- | tools/perform/pio_perf.c | 1694 | ||||
-rw-r--r-- | tools/perform/pio_perf.h | 104 | ||||
-rw-r--r-- | tools/perform/pio_standalone.c | 281 | ||||
-rw-r--r-- | tools/perform/pio_standalone.h | 530 | ||||
-rw-r--r-- | tools/perform/sio_engine.c | 1313 | ||||
-rw-r--r-- | tools/perform/sio_perf.c | 1412 | ||||
-rw-r--r-- | tools/perform/sio_perf.h | 104 | ||||
-rw-r--r-- | tools/perform/sio_standalone.c | 285 | ||||
-rw-r--r-- | tools/perform/sio_standalone.h | 546 | ||||
-rw-r--r-- | tools/perform/zip_perf.c | 644 |
23 files changed, 0 insertions, 13263 deletions
diff --git a/tools/perform/CMakeLists.txt b/tools/perform/CMakeLists.txt deleted file mode 100644 index 0a38b21..0000000 --- a/tools/perform/CMakeLists.txt +++ /dev/null @@ -1,126 +0,0 @@ -cmake_minimum_required (VERSION 3.1.0) -PROJECT (HDF5_PERFORM ) - -#----------------------------------------------------------------------------- -# Apply Definitions to compiler in this directory and below -#----------------------------------------------------------------------------- -add_definitions (${HDF_EXTRA_C_FLAGS}) - -#----------------------------------------------------------------------------- -# Setup include Directories -#----------------------------------------------------------------------------- -INCLUDE_DIRECTORIES (${HDF5_TEST_SRC_DIR}) -INCLUDE_DIRECTORIES (${HDF5_TOOLS_DIR}/lib ) - -# -------------------------------------------------------------------- -# Add the executables -# -------------------------------------------------------------------- -#-- Adding test for h5perf_serial -set (h5perf_serial_SOURCES - ${HDF5_PERFORM_SOURCE_DIR}/sio_perf.c - ${HDF5_PERFORM_SOURCE_DIR}/sio_engine.c -) -add_executable (h5perf_serial ${h5perf_serial_SOURCES}) -TARGET_NAMING (h5perf_serial STATIC) -TARGET_C_PROPERTIES (h5perf_serial STATIC " " " ") -target_link_libraries (h5perf_serial ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET}) -set_target_properties (h5perf_serial PROPERTIES FOLDER perform) - -if (HDF5_BUILD_PERFORM_STANDALONE) - #-- Adding test for h5perf_serial_alone - set (h5perf_serial_alone_SOURCES - ${HDF5_PERFORM_SOURCE_DIR}/sio_perf.c - ${HDF5_PERFORM_SOURCE_DIR}/sio_engine.c - ) - add_executable (h5perf_serial_alone ${h5perf_serial_alone_SOURCES}) - TARGET_NAMING (h5perf_serial_alone STATIC) - TARGET_C_PROPERTIES (h5perf_serial_alone STATIC " " " ") - target_link_libraries (h5perf_serial_alone ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET}) - set_target_properties (h5perf_serial_alone PROPERTIES FOLDER perform) - set_property (TARGET h5perf_serial_alone - APPEND PROPERTY COMPILE_DEFINITIONS STANDALONE - ) -endif (HDF5_BUILD_PERFORM_STANDALONE) - -#-- Adding test for chunk -set (chunk_SOURCES - ${HDF5_PERFORM_SOURCE_DIR}/chunk.c -) -ADD_EXECUTABLE(chunk ${chunk_SOURCES}) -TARGET_NAMING (chunk STATIC) -TARGET_C_PROPERTIES (chunk STATIC " " " ") -TARGET_LINK_LIBRARIES(chunk ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET}) -set_target_properties (chunk PROPERTIES FOLDER perform) - -#-- Adding test for iopipe -set (iopipe_SOURCES - ${HDF5_PERFORM_SOURCE_DIR}/iopipe.c -) -add_executable (iopipe ${iopipe_SOURCES}) -TARGET_NAMING (iopipe STATIC) -TARGET_C_PROPERTIES (iopipe STATIC " " " ") -target_link_libraries (iopipe ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET}) -set_target_properties (iopipe PROPERTIES FOLDER perform) - -#-- Adding test for overhead -set (overhead_SOURCES - ${HDF5_PERFORM_SOURCE_DIR}/overhead.c -) -add_executable (overhead ${overhead_SOURCES}) -TARGET_NAMING (overhead STATIC) -TARGET_C_PROPERTIES (overhead STATIC " " " ") -target_link_libraries (overhead ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET}) -set_target_properties (overhead PROPERTIES FOLDER perform) - -if (BUILD_TESTING) -#-- Adding test for perf_meta - set (perf_meta_SOURCES - ${HDF5_PERFORM_SOURCE_DIR}/perf_meta.c - ) - add_executable (perf_meta ${perf_meta_SOURCES}) - TARGET_NAMING (perf_meta STATIC) - TARGET_C_PROPERTIES (perf_meta STATIC " " " ") - target_link_libraries (perf_meta ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET} ${HDF5_TEST_LIB_TARGET}) - set_target_properties (perf_meta PROPERTIES FOLDER perform) -endif (BUILD_TESTING) - -#-- Adding test for zip_perf -set (zip_perf_SOURCES - ${HDF5_PERFORM_SOURCE_DIR}/zip_perf.c -) -add_executable (zip_perf ${zip_perf_SOURCES}) -TARGET_NAMING (zip_perf STATIC) -TARGET_C_PROPERTIES (zip_perf STATIC " " " ") -target_link_libraries (zip_perf ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET}) -set_target_properties (zip_perf PROPERTIES FOLDER perform) - -if (H5_HAVE_PARALLEL AND BUILD_TESTING) - #-- Adding test for h5perf - set (h5perf_SOURCES - ${HDF5_PERFORM_SOURCE_DIR}/pio_perf.c - ${HDF5_PERFORM_SOURCE_DIR}/pio_engine.c - ) - add_executable (h5perf ${h5perf_SOURCES}) - TARGET_NAMING (h5perf STATIC) - TARGET_C_PROPERTIES (h5perf STATIC " " " ") - target_link_libraries (h5perf ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET} ${HDF5_TEST_LIB_TARGET}) - set_target_properties (h5perf PROPERTIES FOLDER perform) - - if (HDF5_BUILD_PERFORM_STANDALONE) - #-- Adding test for h5perf - set (h5perf_alone_SOURCES - ${HDF5_PERFORM_SOURCE_DIR}/pio_perf.c - ${HDF5_PERFORM_SOURCE_DIR}/pio_engine.c - ) - add_executable (h5perf_alone ${h5perf_alone_SOURCES}) - TARGET_NAMING (h5perf_alone STATIC) - TARGET_C_PROPERTIES (h5perf_alone STATIC " " " ") - target_link_libraries (h5perf_alone ${HDF5_LIB_TARGET} ${HDF5_TOOLS_LIB_TARGET} ${HDF5_TEST_LIB_TARGET}) - set_target_properties (h5perf_alone PROPERTIES FOLDER perform) - set_property (TARGET h5perf_alone - APPEND PROPERTY COMPILE_DEFINITIONS STANDALONE - ) - endif (HDF5_BUILD_PERFORM_STANDALONE) -endif (H5_HAVE_PARALLEL AND BUILD_TESTING) - -include (CMakeTests.cmake) diff --git a/tools/perform/CMakeTests.cmake b/tools/perform/CMakeTests.cmake deleted file mode 100644 index 0ea40a3..0000000 --- a/tools/perform/CMakeTests.cmake +++ /dev/null @@ -1,54 +0,0 @@ - -############################################################################## -############################################################################## -### T E S T I N G ### -############################################################################## -############################################################################## - -HDFTEST_COPY_FILE("${HDF5_TOOLS_DIR}/testfiles/tfilters.h5" "${PROJECT_BINARY_DIR}/tfilters.h5" "zip_perf_files") -add_custom_target(zip_perf_files ALL COMMENT "Copying files needed by zip_perf tests" DEPENDS ${zip_perf_list}) - -#----------------------------------------------------------------------------- -# Add Tests -#----------------------------------------------------------------------------- - -# Remove any output file left over from previous test run -add_test ( - NAME PERFORM_h5perform-clear-objects - COMMAND ${CMAKE_COMMAND} - -E remove - chunk.h5 - iopipe.h5 - iopipe.raw - x-diag-rd.dat - x-diag-wr.dat - x-rowmaj-rd.dat - x-rowmaj-wr.dat - x-gnuplot -) - -add_test (NAME PERFORM_h5perf_serial COMMAND $<TARGET_FILE:h5perf_serial>) -set_tests_properties (PERFORM_h5perf_serial PROPERTIES TIMEOUT 1800) - -if (HDF5_BUILD_PERFORM_STANDALONE) - add_test (NAME PERFORM_h5perf_serial_alone COMMAND $<TARGET_FILE:h5perf_serial_alone>) -endif (HDF5_BUILD_PERFORM_STANDALONE) - -add_test (NAME PERFORM_chunk COMMAND $<TARGET_FILE:chunk>) - -add_test (NAME PERFORM_iopipe COMMAND $<TARGET_FILE:iopipe>) - -add_test (NAME PERFORM_overhead COMMAND $<TARGET_FILE:overhead>) - -add_test (NAME PERFORM_perf_meta COMMAND $<TARGET_FILE:perf_meta>) - -add_test (NAME PERFORM_zip_perf_help COMMAND $<TARGET_FILE:zip_perf> "-h") -add_test (NAME PERFORM_zip_perf COMMAND $<TARGET_FILE:zip_perf> tfilters.h5) - -if (H5_HAVE_PARALLEL) - add_test (NAME PERFORM_h5perf COMMAND ${MPIEXEC} ${MPIEXEC_PREFLAGS} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_POSTFLAGS} $<TARGET_FILE:h5perf>) - - if (HDF5_BUILD_PERFORM_STANDALONE) - add_test (NAME PERFORM_h5perf_alone COMMAND ${MPIEXEC} ${MPIEXEC_PREFLAGS} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_POSTFLAGS} $<TARGET_FILE:h5perf_alone>) - endif (HDF5_BUILD_PERFORM_STANDALONE) -endif (H5_HAVE_PARALLEL) diff --git a/tools/perform/COPYING b/tools/perform/COPYING deleted file mode 100644 index 6903daf..0000000 --- a/tools/perform/COPYING +++ /dev/null @@ -1,16 +0,0 @@ - - Copyright by The HDF Group and - The Board of Trustees of the University of Illinois. - All rights reserved. - - The files and subdirectories in this directory are 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://www.hdfgroup.org/HDF5/doc/Copyright.html. If you do not - have access to either file, you may request a copy from - help@hdfgroup.org. - diff --git a/tools/perform/Makefile.am b/tools/perform/Makefile.am deleted file mode 100644 index 1af0e7f..0000000 --- a/tools/perform/Makefile.am +++ /dev/null @@ -1,79 +0,0 @@ -# -# Copyright by The HDF Group. -# 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have -# access to either file, you may request a copy from help@hdfgroup.org. -## -## Makefile.am -## Run automake to generate a Makefile.in from this file. -## -# -# HDF5 Library Performance Makefile(.in) -# - -include $(top_srcdir)/config/commence.am - -AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/test -I$(top_srcdir)/tools/lib - -# bin_PROGRAMS will be installed. -if BUILD_PARALLEL_CONDITIONAL - bin_PROGRAMS=h5perf_serial h5perf -else - bin_PROGRAMS=h5perf_serial -endif - -# Add h5perf and h5perf_serial specific linker flags here -h5perf_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) -h5perf_serial_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) - -# Some programs are not built or run by default, but can be built by hand or by -# specifying --enable-build-all at configure time. -# Also, some of these programs should only be built in parallel. -# Currently there is no such program. -if BUILD_PARALLEL_CONDITIONAL - PARA_BUILD_ALL= -endif -if BUILD_ALL_CONDITIONAL - BUILD_ALL_PROGS=$(PARA_BUILD_ALL) -endif - -# Define programs that will be run in 'make check' -# List them in the order they should be run. -# Parallel test programs. -if BUILD_PARALLEL_CONDITIONAL - TEST_PROG_PARA=h5perf perf -endif -# Serial test programs. -TEST_PROG = iopipe chunk overhead zip_perf perf_meta h5perf_serial $(BUILD_ALL_PROGS) - -# check_PROGRAMS will be built but not installed. Do not any executable -# that is in bin_PROGRAMS already. Otherwise, it will be removed twice in -# "make clean" and some systems, e.g., AIX, do not like it. -check_PROGRAMS= iopipe chunk overhead zip_perf perf_meta $(BUILD_ALL_PROGS) perf - -h5perf_SOURCES=pio_perf.c pio_engine.c -h5perf_serial_SOURCES=sio_perf.c sio_engine.c - -# These are the files that `make clean' (and derivatives) will remove from -# this directory. -CLEANFILES=*.h5 *.raw *.dat x-gnuplot perftest.out - -# All of the programs depend on the main hdf5 library, and some of them -# depend on test or tools library. -LDADD=$(LIBHDF5) -h5perf_LDADD=$(LIBH5TOOLS) $(LIBH5TEST) $(LIBHDF5) -h5perf_serial_LDADD=$(LIBH5TOOLS) $(LIBH5TEST) $(LIBHDF5) -perf_LDADD=$(LIBH5TEST) $(LIBHDF5) -iopipe_LDADD=$(LIBH5TEST) $(LIBHDF5) -zip_perf_LDADD=$(LIBH5TOOLS) $(LIBH5TEST) $(LIBHDF5) -perf_meta_LDADD=$(LIBH5TEST) $(LIBHDF5) - -include $(top_srcdir)/config/conclude.am diff --git a/tools/perform/build_h5perf_alone.sh b/tools/perform/build_h5perf_alone.sh deleted file mode 100755 index b65e863..0000000 --- a/tools/perform/build_h5perf_alone.sh +++ /dev/null @@ -1,28 +0,0 @@ -#! /bin/sh -x -# -# Copyright by The HDF Group. -# 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have -# access to either file, you may request a copy from help@hdfgroup.org. -# -# Name: build_h5perf_alone.sh -# -# Puporse: Build the h5perf tool by standalone mode. -# -# Created: Albert Cheng, 2005/09/18 -# -# Modification: -# - -# Default to use h5pcc to build h5perf unless $H5CC is defined. -# -h5pcc=${H5CC:-h5pcc} -$h5pcc -DSTANDALONE pio_perf.c pio_engine.c pio_timer.c -o h5perf diff --git a/tools/perform/build_h5perf_serial_alone.sh b/tools/perform/build_h5perf_serial_alone.sh deleted file mode 100755 index 2566609..0000000 --- a/tools/perform/build_h5perf_serial_alone.sh +++ /dev/null @@ -1,28 +0,0 @@ -#! /bin/sh -x -# -# Copyright by The HDF Group. -# 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have -# access to either file, you may request a copy from help@hdfgroup.org. -# -# Name: build_h5perf_serial_alone.sh -# -# Puporse: Build the h5perf_serial tool by standalone mode. -# -# Created: Christian Chilan, 2008/09/02 -# -# Modification: -# - -# Default to use h5cc to build h5perf_serial unless $H5CC is defined. -# -h5cc=${H5CC:-h5cc} -$h5cc -DSTANDALONE sio_perf.c sio_engine.c sio_timer.c -o h5perf_serial diff --git a/tools/perform/chunk.c b/tools/perform/chunk.c deleted file mode 100644 index b1419ee..0000000 --- a/tools/perform/chunk.c +++ /dev/null @@ -1,550 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Programmer: Robb Matzke <robb@arborea.spizella.com> - * Thursday, May 14, 1998 - * - * Purpose: Checks the effect of various I/O request sizes and raw data - * cache sizes. Performance depends on the amount of data read - * from disk and we use a filter to get that number. - */ - -/* See H5private.h for how to include headers */ -#undef NDEBUG -#include "hdf5.h" - -#ifdef H5_STDC_HEADERS -# include <assert.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -#endif - -/* Solaris Studio defines attribute, but for the attributes we need */ -#if !defined(H5_HAVE_ATTRIBUTE) || defined __cplusplus || defined(__SUNPRO_C) -# undef __attribute__ -# define __attribute__(X) /*void*/ -# define H5_ATTR_UNUSED /*void*/ -#else -# define H5_ATTR_UNUSED __attribute__((unused)) -#endif - -#define FILE_NAME "chunk.h5" -#define LINESPOINTS "lines" -#define CH_SIZE 100 /*squared in terms of bytes */ -#define DS_SIZE 20 /*squared in terms of chunks */ -#define FILTER_COUNTER 305 -#define READ 0 -#define WRITE 1 -#define MIN(X,Y) ((X)<(Y)?(X):(Y)) -#define MAX(X,Y) ((X)>(Y)?(X):(Y)) -#define SQUARE(X) ((X)*(X)) - -/* The row-major test */ -#define RM_CACHE_STRT 25 -#define RM_CACHE_END 25 -#define RM_CACHE_DELT 5 -#define RM_START (double)0.50F -#define RM_END (double)5.00F -#define RM_DELTA (double)0.50F -#define RM_W0 0.0F -#define RM_NRDCC 521 - -/* Diagonal test */ -#define DIAG_CACHE_STRT 25 -#define DIAG_CACHE_END 25 -#define DIAG_CACHE_DELT 5 -#define DIAG_START (double)0.50F -#define DIAG_END (double)5.00F -#define DIAG_DELTA (double)0.50F -/* #define DIAG_W0 0.65F */ -/* #define DIAG_NRDCC 521 */ - -static size_t nio_g; -static hid_t fapl_g = -1; - -/* Local function prototypes */ -static size_t -counter (unsigned H5_ATTR_UNUSED flags, size_t cd_nelmts, - const unsigned *cd_values, size_t nbytes, - size_t *buf_size, void **buf); - -/* This message derives from H5Z */ -const H5Z_class2_t H5Z_COUNTER[1] = {{ - H5Z_CLASS_T_VERS, /* H5Z_class_t version */ - FILTER_COUNTER, /* Filter id number */ - 1, 1, /* Encoding and decoding enabled */ - "counter", /* Filter name for debugging */ - NULL, /* The "can apply" callback */ - NULL, /* The "set local" callback */ - counter, /* The actual filter function */ -}}; - - -/*------------------------------------------------------------------------- - * Function: counter - * - * Purpose: Count number of bytes but don't do anything. - * - * Return: Success: src_nbytes-1 - * - * Failure: never fails - * - * Programmer: Robb Matzke - * Thursday, May 14, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static size_t -counter (unsigned H5_ATTR_UNUSED flags, size_t H5_ATTR_UNUSED cd_nelmts, - const unsigned H5_ATTR_UNUSED *cd_values, size_t nbytes, - size_t H5_ATTR_UNUSED *buf_size, void H5_ATTR_UNUSED **buf) -{ - nio_g += nbytes; - return nbytes; -} - - -/*------------------------------------------------------------------------- - * Function: create_dataset - * - * Purpose: Creates a square dataset with square chunks, registers a - * stupid compress/uncompress pair for counting I/O, and - * initializes the dataset. The chunk size is in bytes, the - * dataset size is in terms of chunks. - * - * Return: void - * - * Programmer: Robb Matzke - * Thursday, May 14, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static void -create_dataset (void) -{ - hid_t file, space, dcpl, dset; - hsize_t size[2]; - signed char *buf; - - /* The file */ - file = H5Fcreate (FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_g); - - /* The data space */ - size[0] = size[1] = DS_SIZE * CH_SIZE; - space = H5Screate_simple(2, size, size); - - /* The storage layout and compression */ - dcpl = H5Pcreate(H5P_DATASET_CREATE); - size[0] = size[1] = CH_SIZE; - H5Pset_chunk(dcpl, 2, size); - H5Zregister(H5Z_COUNTER); - H5Pset_filter(dcpl, FILTER_COUNTER, 0, 0, NULL); - - /* The dataset */ - dset = H5Dcreate2(file, "dset", H5T_NATIVE_SCHAR, space, H5P_DEFAULT, dcpl, H5P_DEFAULT); - assert(dset>=0); - - /* The data */ - buf = (signed char *)calloc(1, SQUARE (DS_SIZE*CH_SIZE)); - H5Dwrite(dset, H5T_NATIVE_SCHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); - free(buf); - - /* Close */ - H5Dclose(dset); - H5Sclose(space); - H5Pclose(dcpl); - H5Fclose(file); -} - - -/*------------------------------------------------------------------------- - * Function: test_rowmaj - * - * Purpose: Reads the entire dataset using the specified size-squared - * I/O requests in row major order. - * - * Return: Efficiency: data requested divided by data actually read. - * - * Programmer: Robb Matzke - * Thursday, May 14, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static double -test_rowmaj (int op, size_t cache_size, size_t io_size) -{ - hid_t file, dset, mem_space, file_space; - signed char *buf = (signed char *)calloc (1, (size_t)(SQUARE(io_size))); - hsize_t i, j, hs_size[2]; - hsize_t hs_offset[2]; - int mdc_nelmts; - size_t rdcc_nelmts; - double w0; - - H5Pget_cache (fapl_g, &mdc_nelmts, &rdcc_nelmts, NULL, &w0); -#ifdef RM_W0 - w0 = RM_W0; -#endif -#ifdef RM_NRDCC - rdcc_nelmts = RM_NRDCC; -#endif - H5Pset_cache (fapl_g, mdc_nelmts, rdcc_nelmts, - cache_size*SQUARE (CH_SIZE), w0); - file = H5Fopen(FILE_NAME, H5F_ACC_RDWR, fapl_g); - dset = H5Dopen2(file, "dset", H5P_DEFAULT); - file_space = H5Dget_space(dset); - nio_g = 0; - - for (i=0; i<CH_SIZE*DS_SIZE; i+=io_size) { -#if 0 - fprintf (stderr, "%5d\b\b\b\b\b", (int)i); - fflush (stderr); -#endif - for (j=0; j<CH_SIZE*DS_SIZE; j+=io_size) { - hs_offset[0] = i; - hs_size[0] = MIN (io_size, CH_SIZE*DS_SIZE-i); - hs_offset[1] = j; - hs_size[1] = MIN (io_size, CH_SIZE*DS_SIZE-j); - mem_space = H5Screate_simple (2, hs_size, hs_size); - H5Sselect_hyperslab (file_space, H5S_SELECT_SET, hs_offset, - NULL, hs_size, NULL); - - if (READ==op) { - H5Dread (dset, H5T_NATIVE_SCHAR, mem_space, file_space, - H5P_DEFAULT, buf); - } else { - H5Dwrite (dset, H5T_NATIVE_SCHAR, mem_space, file_space, - H5P_DEFAULT, buf); - } - H5Sclose (mem_space); - } - } - - free (buf); - H5Sclose (file_space); - H5Dclose (dset); - H5Fclose (file); - - return (double)SQUARE(CH_SIZE*DS_SIZE)/(double)nio_g; -} - - -/*------------------------------------------------------------------------- - * Function: test_diag - * - * Purpose: Reads windows diagonally across the dataset. Each window is - * offset from the previous window by OFFSET in the x and y - * directions. The reading ends after the (k,k) value is read - * where k is the maximum index in the dataset. - * - * Return: Efficiency. - * - * Programmer: Robb Matzke - * Friday, May 15, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static double -test_diag (int op, size_t cache_size, size_t io_size, size_t offset) -{ - hid_t file, dset, mem_space, file_space; - hsize_t i, hs_size[2]; - hsize_t nio = 0; - hsize_t hs_offset[2]; - signed char *buf = (signed char *)calloc(1, (size_t)(SQUARE (io_size))); - int mdc_nelmts; - size_t rdcc_nelmts; - double w0; - - H5Pget_cache (fapl_g, &mdc_nelmts, &rdcc_nelmts, NULL, &w0); -#ifdef DIAG_W0 - w0 = DIAG_W0; -#endif -#ifdef DIAG_NRDCC - rdcc_nelmts = DIAG_NRDCC; -#endif - H5Pset_cache (fapl_g, mdc_nelmts, rdcc_nelmts, - cache_size*SQUARE (CH_SIZE), w0); - file = H5Fopen(FILE_NAME, H5F_ACC_RDWR, fapl_g); - dset = H5Dopen2(file, "dset", H5P_DEFAULT); - file_space = H5Dget_space(dset); - nio_g = 0; - - for (i=0, hs_size[0]=io_size; hs_size[0]==io_size; i+=offset) { - hs_offset[0] = hs_offset[1] = i; - hs_size[0] = hs_size[1] = MIN (io_size, CH_SIZE*DS_SIZE-i); - mem_space = H5Screate_simple (2, hs_size, hs_size); - H5Sselect_hyperslab (file_space, H5S_SELECT_SET, hs_offset, NULL, - hs_size, NULL); - if (READ==op) { - H5Dread (dset, H5T_NATIVE_SCHAR, mem_space, file_space, - H5P_DEFAULT, buf); - } else { - H5Dwrite (dset, H5T_NATIVE_SCHAR, mem_space, file_space, - H5P_DEFAULT, buf); - } - H5Sclose (mem_space); - nio += hs_size[0]*hs_size[1]; - if (i>0) nio -= SQUARE (io_size-offset); - } - - free (buf); - H5Sclose (file_space); - H5Dclose (dset); - H5Fclose (file); - - /* - * The extra cast in the following statement is a bug workaround for the - * Win32 version 5.0 compiler. - * 1998-11-06 ptl - */ - return (double)nio/(double)nio_g; -} - - -/*------------------------------------------------------------------------- - * Function: main - * - * Purpose: See file prologue. - * - * Return: Success: - * - * Failure: - * - * Programmer: Robb Matzke - * Thursday, May 14, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -int -main (void) -{ - size_t io_size; - double effic, io_percent; - FILE *f, *d; - size_t cache_size; - double w0; - - /* - * Create a global file access property list. - */ - fapl_g = H5Pcreate (H5P_FILE_ACCESS); - H5Pget_cache (fapl_g, NULL, NULL, NULL, &w0); - - /* Create the file */ - create_dataset (); - f = fopen ("x-gnuplot", "w"); - - printf("Test %8s %8s %8s\n", "CacheSz", "ChunkSz", "Effic"); - printf("--------- -------- -------- --------\n"); - -#if 1 - /* - * Test row-major reading of the dataset with various sizes of request - * windows. - */ - if (RM_CACHE_STRT==RM_CACHE_END) { - fprintf (f, "set yrange [0:1.2]\n"); - fprintf (f, "set ytics 0, 0.1, 1\n"); - fprintf (f, "set xlabel \"%s\"\n", - "Request size as a fraction of chunk size"); - fprintf (f, "set ylabel \"Efficiency\"\n"); - fprintf (f, "set title \"Cache %d chunks, w0=%g, " - "Size=(total=%d, chunk=%d)\"\n", - RM_CACHE_STRT, w0, DS_SIZE*CH_SIZE, CH_SIZE); - } else { - fprintf (f, "set autoscale\n"); - fprintf (f, "set hidden3d\n"); - } - - fprintf (f, "set terminal postscript\nset output \"x-rowmaj-rd.ps\"\n"); - fprintf (f, "%s \"x-rowmaj-rd.dat\" title \"RowMaj-Read\" with %s\n", - RM_CACHE_STRT==RM_CACHE_END?"plot":"splot", - LINESPOINTS); - fprintf (f, "set terminal x11\nreplot\n"); - d = fopen ("x-rowmaj-rd.dat", "w"); - for (cache_size=RM_CACHE_STRT; - cache_size<=RM_CACHE_END; - cache_size+=RM_CACHE_DELT) { - for (io_percent=RM_START; io_percent<=RM_END; io_percent+=RM_DELTA) { - io_size = MAX (1, (size_t)(CH_SIZE*io_percent)); - printf ("Rowmaj-rd %8d %8.2f", (int)cache_size, io_percent); - fflush (stdout); - effic = test_rowmaj (READ, cache_size, io_size); - printf (" %8.2f\n", effic); - if (RM_CACHE_STRT==RM_CACHE_END) { - fprintf (d, "%g %g\n", io_percent, effic); - } else { - fprintf (d, "%g\n", effic); - } - } - fprintf (d, "\n"); - } - fclose (d); - fprintf (f, "pause -1\n"); -#endif - -#if 1 - /* - * Test row-major writing of the dataset with various sizes of request - * windows. - */ - if (RM_CACHE_STRT==RM_CACHE_END) { - fprintf (f, "set yrange [0:1.2]\n"); - fprintf (f, "set ytics 0, 0.1, 1\n"); - fprintf (f, "set xlabel \"%s\"\n", - "Request size as a fraction of chunk size"); - fprintf (f, "set ylabel \"Efficiency\"\n"); - fprintf (f, "set title \"Cache %d chunks,w0=%g, " - "Size=(total=%d, chunk=%d)\"\n", - RM_CACHE_STRT, w0, DS_SIZE*CH_SIZE, CH_SIZE); - } else { - fprintf (f, "set autoscale\n"); - fprintf (f, "set hidden3d\n"); - } - - fprintf (f, "set terminal postscript\nset output \"x-rowmaj-wr.ps\"\n"); - fprintf (f, "%s \"x-rowmaj-wr.dat\" title \"RowMaj-Write\" with %s\n", - RM_CACHE_STRT==RM_CACHE_END?"plot":"splot", - LINESPOINTS); - fprintf (f, "set terminal x11\nreplot\n"); - d = fopen ("x-rowmaj-wr.dat", "w"); - for (cache_size=RM_CACHE_STRT; - cache_size<=RM_CACHE_END; - cache_size+=RM_CACHE_DELT) { - for (io_percent=RM_START; io_percent<=RM_END; io_percent+=RM_DELTA) { - io_size = MAX (1, (size_t)(CH_SIZE*io_percent)); - printf ("Rowmaj-wr %8d %8.2f", (int)cache_size, io_percent); - fflush (stdout); - effic = test_rowmaj (WRITE, cache_size, io_size); - printf (" %8.2f\n", effic); - if (RM_CACHE_STRT==RM_CACHE_END) { - fprintf (d, "%g %g\n", io_percent, effic); - } else { - fprintf (d, "%g\n", effic); - } - } - fprintf (d, "\n"); - } - fclose (d); - fprintf (f, "pause -1\n"); -#endif - -#if 1 - /* - * Test diagonal read - */ - if (DIAG_CACHE_STRT==DIAG_CACHE_END) { - fprintf (f, "set yrange [0:1.2]\n"); - fprintf (f, "set ytics 0, 0.1, 1\n"); - fprintf (f, "set xlabel \"%s\"\n", - "Request size as a fraction of chunk size"); - fprintf (f, "set ylabel \"Efficiency\"\n"); - fprintf (f, "set title \"Cache %d chunks,w0=%g, " - "Size=(total=%d, chunk=%d)\"\n", - DIAG_CACHE_STRT, w0, DS_SIZE*CH_SIZE, CH_SIZE); - } else { - fprintf (f, "set autoscale\n"); - fprintf (f, "set hidden3d\n"); - } - fprintf (f, "set terminal postscript\nset output \"x-diag-rd.ps\"\n"); - fprintf (f, "%s \"x-diag-rd.dat\" title \"Diag-Read\" with %s\n", - DIAG_CACHE_STRT==DIAG_CACHE_END?"plot":"splot", LINESPOINTS); - fprintf (f, "set terminal x11\nreplot\n"); - d = fopen ("x-diag-rd.dat", "w"); - for (cache_size=DIAG_CACHE_STRT; - cache_size<=DIAG_CACHE_END; - cache_size+=DIAG_CACHE_DELT) { - for (io_percent=DIAG_START; io_percent<=DIAG_END; io_percent+=DIAG_DELTA) { - io_size = MAX (1, (size_t)(CH_SIZE*io_percent)); - printf ("Diag-rd %8d %8.2f", (int)cache_size, io_percent); - fflush (stdout); - effic = test_diag (READ, cache_size, io_size, MAX (1, io_size/2)); - printf (" %8.2f\n", effic); - if (DIAG_CACHE_STRT==DIAG_CACHE_END) { - fprintf (d, "%g %g\n", io_percent, effic); - } else { - fprintf (d, "%g\n", effic); - } - } - fprintf (d, "\n"); - } - fclose (d); - fprintf (f, "pause -1\n"); -#endif - -#if 1 - /* - * Test diagonal write - */ - if (DIAG_CACHE_STRT==DIAG_CACHE_END) { - fprintf (f, "set yrange [0:1.2]\n"); - fprintf (f, "set ytics 0, 0.1, 1\n"); - fprintf (f, "set xlabel \"%s\"\n", - "Request size as a fraction of chunk size"); - fprintf (f, "set ylabel \"Efficiency\"\n"); - fprintf (f, "set title \"Cache %d chunks, w0=%g, " - "Size=(total=%d, chunk=%d)\"\n", - DIAG_CACHE_STRT, w0, DS_SIZE*CH_SIZE, CH_SIZE); - } else { - fprintf (f, "set autoscale\n"); - fprintf (f, "set hidden3d\n"); - } - fprintf (f, "set terminal postscript\nset output \"x-diag-wr.ps\"\n"); - fprintf (f, "%s \"x-diag-wr.dat\" title \"Diag-Write\" with %s\n", - DIAG_CACHE_STRT==DIAG_CACHE_END?"plot":"splot", LINESPOINTS); - fprintf (f, "set terminal x11\nreplot\n"); - d = fopen ("x-diag-wr.dat", "w"); - for (cache_size=DIAG_CACHE_STRT; - cache_size<=DIAG_CACHE_END; - cache_size+=DIAG_CACHE_DELT) { - for (io_percent=DIAG_START; - io_percent<=DIAG_END; - io_percent+=DIAG_DELTA) { - io_size = MAX (1, (size_t)(CH_SIZE*io_percent)); - printf ("Diag-wr %8d %8.2f", (int)cache_size, io_percent); - fflush (stdout); - effic = test_diag (WRITE, cache_size, io_size, MAX (1, io_size/2)); - printf (" %8.2f\n", effic); - if (DIAG_CACHE_STRT==DIAG_CACHE_END) { - fprintf (d, "%g %g\n", io_percent, effic); - } else { - fprintf (d, "%g\n", effic); - } - } - fprintf (d, "\n"); - } - fclose (d); - fprintf (f, "pause -1\n"); -#endif - - - H5Pclose (fapl_g); - fclose (f); - return 0; -} - diff --git a/tools/perform/gen_report.pl b/tools/perform/gen_report.pl deleted file mode 100755 index 285f5d7..0000000 --- a/tools/perform/gen_report.pl +++ /dev/null @@ -1,527 +0,0 @@ -#!/usr/bin/perl -# -# Copyright by The HDF Group. -# 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have -# access to either file, you may request a copy from help@hdfgroup.org. -# - -# -# Generates an ASCII and Excel-importable file of tables representing -# the output of running the "pio_perf" command. The name of the input -# file is important. The name should reflect the command-line options -# used in the performance test. It needs to be of the form: -# -# f#[GMK].i#.d#.X#[GMK].x#[GMK]..* -# -# For example: -# -# PIO_output_f1G.i2.d1.X2M.x128K.frost -# -# for a 1GB sized file ran for 2 iterations with 1 dataset from xfer -# buffer size of 128KB to 2MB on the frost machine. -# -# The output file will have the same name as the input, but will append -# ".ascii" for the ASCII file and ".excel" for the Excel-importable -# file. -# -# The data structure used in this program looks like: -# -# %results = { -# num_proc => ( -# %xfer_size => ( -# %posix = { -# 'write-only' => ##, -# 'write-close' => ##, -# 'read-only' => ##, -# 'read-close' => ## -# }, -# %mpio = { -# 'write-only' => ##, -# 'write-close' => ##, -# 'read-only' => ##, -# 'read-close' => ## -# }, -# %phdf = { -# 'write-only' => ##, -# 'write-close' => ##, -# 'read-only' => ##, -# 'read-close' => ## -# } -# ) -# ) -# } - -use IO::Handle; -use Getopt::Long; -use List::Util qw[max]; - -if ($#ARGV == -1) { - usage(); -} - -my ($ascii_output, $excel_output); - -GetOptions("data_type=s"=>\$data_type, - "buffer_size=i"=>\$transfer_buffer_size, - "procs=i"=>\$num_procs_graph, - "help!"=>\$help, - "throughput=s"=>\$throughput_type, - "io_type=i"=>\$io_type, - "3d!"=>\$plot_3d); - -usage() if $help or !@ARGV; - -$throughput_type = "average" if !$throughput_type; -$io_type = 7 if !$io_type; - -foreach my $arg (@ARGV) { - - if ($arg !~ /^-/) { - $arg =~ /f([0-9]+.)\.i([0-9]+)\.d([0-9]+)\.X([0-9]+.)\.x([0-9]+.)\.(.*)/; - - my $output = $arg . $1 . ".X" . $4 . ".x" . $5 . "." . $6; - - $ascii_output = $output . ".ascii"; - $excel_output = $output . ".excel"; - - open(INPUT, "<$arg") or die "error: cannot open file $arg: $!\n"; - open(ASCII_OUTPUT, ">$ascii_output") or - die "error: cannot open file $ascii_output: $!\n"; - open(EXCEL_OUTPUT, ">$excel_output") or - die "error: cannot open file $excel_output: $!\n"; - } - else - { - die "error: unrecognized option: $arg\n"; - } -} - -my %results; -my $num_procs = 0; -my ($xfer_size, $avg_type, $type); - -my $posix = 0, $mpio = 1, $phdf5 = 2; - -##"==== End of Parameters ====" - -while (<INPUT>) { - if (/Number of processors = ([0-9]+)/) { - $num_procs = $1; - } - - if (/Transfer Buffer Size: ([0-9]+)/) { - $xfer_size = $1; - } - - $type = $posix if /POSIX/; - $type = $mpio if /MPIO/; - $type = $phdf5 if /PHDF5/; - - if (/Write Open/) { - $avg_type = "write-close"; - } elsif (/Write/) { - $avg_type = "write-only"; - } elsif (/Read Open/) { - $avg_type = "read-close"; - } elsif (/Read/) { - $avg_type = "read-only"; - } - - if($throughput_type eq "max") - { - if (/Maximum Throughput: ( {0,2}[0-9]+\.[0-9]{2}) MB\/s/) { - $results{$num_procs}{$xfer_size}[$type]{$avg_type} = $1; - } - } - elsif($throughput_type eq "min") - { - if (/Minimum Throughput: ( {0,2}[0-9]+\.[0-9]{2}) MB\/s/) { - $results{$num_procs}{$xfer_size}[$type]{$avg_type} = $1; - } - } - elsif($throughput_type eq "average") - { - if (/Average Throughput: ( {0,2}[0-9]+\.[0-9]{2}) MB\/s/) { - $results{$num_procs}{$xfer_size}[$type]{$avg_type} = $1; - } - } -} - -sub usage { - print "Usage: gen_reporl.pl [options] FILE - options are:\n - -data_type \"data_type\" plots the results for \"write-only\",\"read-only\", \"write-close\", or \"read-close\" (default is write-only)\n - -buffer_size \"buffer_size\" plots data from this buffer size (in kilobytes, default is 128)\n - -procs \"num_procs\" plots data from the run with num_procs processors (default is the highest number of processors for which there is data).\n - -throughput \"throughput_type\" plots either the \"max\", \"min\", or \"average\" throughput (default is average)\n - -io_type \"io_type\" where \"io_type\" is the bitwise or of the io_type for which plotting is desired (1 for POSIX, 2 for MPIO, 4 for PHDF5 (default is 7 (all))\n - -3d if present, does a 3d plot in addition to the normal ones\n"; - - exit 1; -} - -sub create_excel_output_header { - my $output_header; - my $kb = 1024; - my $mb = $kb * $kb; - - foreach my $key (sort { $a <=> $b } keys(%{$results{$num_procs}})) { - if ($key < $mb) { - $key /= $kb; - $output_header .= "\t". $key . "K"; - } else { - $key /= $mb; - $output_header .= "\t". $key . "M"; - } - } - - $output_header; -} - -sub create_excel_output_string { - my ($t) = @_; - my $output_content = ""; - - foreach my $procs (sort { $b <=> $a } keys(%results)) { - $output_content .= "\n$procs Procs"; - $output_content .= "\n" . create_excel_output_header; - $output_content .= "\n POSIX"; - - foreach my $xfer (sort { $a <=> $b } keys(%{$results{$procs}})) { - $output_content .= "\t$results{$procs}{$xfer}[0]{$t}"; - } - - $output_content .= "\n MPIO"; - - foreach my $xfer (sort { $a <=> $b } keys(%{$results{$procs}})) { - $output_content .= "\t$results{$procs}{$xfer}[1]{$t}"; - } - - $output_content .= "\n PHDF5"; - - foreach my $xfer (sort { $a <=> $b } keys(%{$results{$procs}})) { - $output_content .= "\t$results{$procs}{$xfer}[2]{$t}"; - } - - $output_content .= "\n"; - } - - $output_content; -} - -sub is_defined { - my ($t) = @_; - my $def = 1; - - foreach my $procs (sort { $b <=> $a } keys(%results)) { - foreach my $xfer (sort { $a <=> $b } keys(%{$results{$procs}})) { - if (!defined($results{$procs}{$xfer}[0]{$t})) { - $def = 0; - } - } - - foreach my $xfer (sort { $a <=> $b } keys(%{$results{$procs}})) { - if (!defined($results{$procs}{$xfer}[0]{$t})) { - $def = 0; - } - } - - foreach my $xfer (sort { $a <=> $b } keys(%{$results{$procs}})) { - if (!defined($results{$procs}{$xfer}[0]{$t})) { - $def = 0; - } - } - } - - $def; -} - -sub write_excel_file { - print EXCEL_OUTPUT "\nWrite-Only\n"; - print EXCEL_OUTPUT create_excel_output_string("write-only"); - print EXCEL_OUTPUT "\nWrite-Close\n"; - print EXCEL_OUTPUT create_excel_output_string("write-close"); - - if (is_defined("read-only")) { - print EXCEL_OUTPUT "\nRead-Only\n"; - print EXCEL_OUTPUT create_excel_output_string("read-only"); - print EXCEL_OUTPUT "\nRead-Close\n"; - print EXCEL_OUTPUT create_excel_output_string("read-close"); - } -} - -sub create_ascii_output_header { - my $output_header = " " x 12 . "|"; - my $kb = 1024; - my $mb = $kb * $kb; - - foreach my $key (sort { $a <=> $b } keys(%{$results{$num_procs}})) { - if ($key < $mb) { - $key /= $kb; - $output_header = sprintf("$output_header %-4s |", $key . "K"); - } else { - $key /= $mb; - $output_header = sprintf("$output_header %-4s |", $key . "M"); - } - } - - $output_header; -} - -sub create_ascii_output_string { - my ($t) = @_; - my $output_content = ""; - my $output_header = create_ascii_output_header; - - foreach my $procs (sort { $b <=> $a } keys(%results)) { - $output_content .= "\n$procs Procs"; - $output_content .= "\n$output_header\n"; - $output_content .= "-" x length($output_header); - $output_content .= "\n POSIX |"; - - foreach my $xfer (sort { $a <=> $b } keys(%{$results{$procs}})) { - $output_content = sprintf("$output_content %-6s |", - $results{$procs}{$xfer}[0]{$t}); - } - - $output_content .= "\n "; - $output_content .= "-" x (length($output_header) - 4); - $output_content .= "\n MPI/IO |"; - - foreach my $xfer (sort { $a <=> $b } keys(%{$results{$procs}})) { - $output_content = sprintf("$output_content %-6s |", - $results{$procs}{$xfer}[1]{$t}); - } - - $output_content .= "\n "; - $output_content .= "-" x (length($output_header) - 4); - $output_content .= "\n PHDF5 |"; - - foreach my $xfer (sort { $a <=> $b } keys(%{$results{$procs}})) { - $output_content = sprintf("$output_content %-6s |", - $results{$procs}{$xfer}[2]{$t}); - } - - $output_content .= "\n"; - $output_content .= "=" x length($output_header); - $output_content .= "\n"; - } - - $output_content; -} - -sub write_ascii_file { - print ASCII_OUTPUT "\nWrite-Only"; - print ASCII_OUTPUT "\n----------\n"; - print ASCII_OUTPUT create_ascii_output_string("write-only"); - print ASCII_OUTPUT "\n\nWrite-Close"; - print ASCII_OUTPUT "\n-----------\n"; - print ASCII_OUTPUT create_ascii_output_string("write-close"); - - if (is_defined("read-only")) { - print ASCII_OUTPUT "\n\nRead-Only"; - print ASCII_OUTPUT "\n---------\n"; - print ASCII_OUTPUT create_ascii_output_string("read-only"); - print ASCII_OUTPUT "\n\nRead-Close"; - print ASCII_OUTPUT "\n----------\n"; - print ASCII_OUTPUT create_ascii_output_string("read-close"); - } -} - -sub draw_plot -{ - my($p_3d) = @_; - - if($p_3d) - { - $counter = 3; - print GNUPLOT_PIPE "splot "; - } - else - { - $counter = 2; - print GNUPLOT_PIPE "plot "; - } - - if($io_type & 1) { - print GNUPLOT_PIPE " \"gnuplot.data\" using 1:"; - - if($p_3d) { print GNUPLOT_PIPE "2:"; } - - print GNUPLOT_PIPE $counter . " title 'POSIX' with linespoints"; - $counter = $counter + 1; - } - if($io_type & 2) { - if($io_type & 1) { print GNUPLOT_PIPE ", "; } - print GNUPLOT_PIPE "\"gnuplot.data\" using 1:"; - - if($p_3d) { print GNUPLOT_PIPE "2:"; } - - print GNUPLOT_PIPE $counter . " title 'MPIO' with linespoints"; - $counter = $counter + 1; - if($io_type & 4) { print GNUPLOT_PIPE ", ";} - } - if($io_type & 4) { - print GNUPLOT_PIPE " \"gnuplot.data\" using 1:"; - - if($p_3d) { print GNUPLOT_PIPE "2:"; } - - print GNUPLOT_PIPE $counter . " title 'PHDF5' with linespoints"; - - } - print GNUPLOT_PIPE "\n"; -} - - -sub plot_default_graph1 { - open(GNUPLOT_DATA_OUTPUT, ">gnuplot.data") or - die "error: cannot open file gnuplot.data: $!\n"; - - $transfer_buffer_size = 128 if !$transfer_buffer_size; - $data_type = "write-only" if !$data_type; - - #set up the plot - print GNUPLOT_PIPE "set term x11 1\n"; - print GNUPLOT_PIPE "set xlabel \"Number of Processors\"\n"; - print GNUPLOT_PIPE "set title \"" . $data_type . " Performance (Speed vs. Num. Procs)\"\n"; - print GNUPLOT_PIPE "set ylabel \"Bandwdith (MB/s)\"\n"; - print GNUPLOT_PIPE "set label 1 \"Transfer buffer size: " . $transfer_buffer_size . "K\" at graph 0.7, graph 0.7 left \n"; - -#the next line attempts to hack gnuplot to get around it's inability to linearly scale, but logarithmically label an axis - print GNUPLOT_PIPE "set xtics (\"1\" 1, \"2\" 2, \"4\" 4, \"8\" 8, \"16\" 16, \"32\" 32, \"64\" 64, \"128\" 128, \"256\" 256, \"512\" 512, \"1024\" 1024)\n"; - - - foreach $proc (sort { $a <=> $b }( keys %results )) - { - print GNUPLOT_DATA_OUTPUT $proc . "\t"; - if($io_type & 1) { - print GNUPLOT_DATA_OUTPUT $results{$proc}{$transfer_buffer_size*1024}[0]{$data_type} . "\t"; - } - if($io_type & 2) { - print GNUPLOT_DATA_OUTPUT $results{$proc}{$transfer_buffer_size*1024}[1]{$data_type}. "\t"; - } - if($io_type & 4) { - print GNUPLOT_DATA_OUTPUT $results{$proc}{$transfer_buffer_size*1024}[2]{$data_type}; - } - print GNUPLOT_DATA_OUTPUT "\n"; - - } - - close(GNUPLOT_DATA_OUTPUT); - - draw_plot(0); - - unlink(GNUPLOT_DATA_OUTPUT); - -} - - -sub plot_default_graph2 { - open(GNUPLOT_DATA_OUTPUT, ">gnuplot.data") or - die "error: cannot open file gnuplot.data: $!\n"; - - $num_procs_graph = max(sort { $a <=> $b }( keys %results )) if !$num_procs_graph; - print "min-rpocs: " . $num_procs_graph; - $data_type = "write-only" if !$data_type; - - #set up the plot - print GNUPLOT_PIPE "set term x11 2\n"; - print GNUPLOT_PIPE "set xlabel \"Transfer Buffer Size (in bytes)\"\n"; - print GNUPLOT_PIPE "set title \"" . $data_type . " Performance (Speed vs. Transfer Buffer Size)\"\n"; - print GNUPLOT_PIPE "set ylabel \"Bandwdith (MB/s)\"\n"; - print GNUPLOT_PIPE "set label 1 \"Procs: " . $num_procs_graph . "\" at graph 0.7, graph 0.7 left \n"; - -#the next line attempts to hack gnuplot to get around it's inability to linearly scale, but logarithmically label an axis - print GNUPLOT_PIPE "set xtics (\"4K\" 4*1024, \"8K\" 8*1024, \"16K\" 16*1024, \"32K\" 32*1024, \"64K\" 64*1024, \"128K\" 128*1024, \"256K\" 256*1024, \"512K\" 512*1024, \"1M\" 1024*1024, \"2M\" 2048*1024, \"4M\" 4096*1024, \"8M\" 8192*1024, \"16M\" 16384*1024)\n"; - - foreach $xfer (sort {$a <=> $b} ( keys %{$results{$num_procs_graph}} )) - { - print GNUPLOT_DATA_OUTPUT $xfer . "\t"; - if($io_type & 1) { - print GNUPLOT_DATA_OUTPUT $results{$num_procs_graph}{$xfer}[0]{$data_type} . "\t"; - } - if($io_type & 2) { - print GNUPLOT_DATA_OUTPUT $results{$num_procs_graph}{$xfer}[1]{$data_type}. "\t"; - } - if($io_type & 4) { - print GNUPLOT_DATA_OUTPUT $results{$num_procs_graph}{$xfer}[2]{$data_type}; - } - print GNUPLOT_DATA_OUTPUT "\n"; - - } - - close(GNUPLOT_DATA_OUTPUT); - - draw_plot(0); - - unlink(GNUPLOT_DATA_OUTPUT); -} - -sub plot_3d_graph3 { - open(GNUPLOT_DATA_OUTPUT, ">gnuplot.data") or - die "error: cannot open file gnuplot.data: $!\n"; - - #set up the plot - print GNUPLOT_PIPE "set term x11 3\n"; - print GNUPLOT_PIPE "set xlabel \"Num. Processors\"\n"; - print GNUPLOT_PIPE "set title \"Write Speed v. No. Procs v. Buffer Size\"\n"; - print GNUPLOT_PIPE "set ylabel \"Buffer Size (bytes)\"\n"; - print GNUPLOT_PIPE "set zlabel \"Bandwidth (in MB/s)\"\n"; - print GNUPLOT_PIPE "set nolabel\n"; - print GNUPLOT_PIPE "set dgrid3d 30,30\n"; - print GNUPLOT_PIPE "set hidden3d\n"; - -#the next lines attempts to hack gnuplot to get around it's inability to linearly scale, but logarithmically label an axis - print GNUPLOT_PIPE "set xtics (\"1\" 1, \"2\" 2, \"4\" 4, \"8\" 8, \"16\" 16, \"32\" 32, \"64\" 64, \"128\" 128, \"256\" 256, \"512\" 512, \"1024\" 1024)\n"; - print GNUPLOT_PIPE "set ytics (\"4K\" 4*1024, \"8K\" 8*1024, \"16K\" 16*1024, \"32K\" 32*1024, \"64K\" 64*1024, \"128K\" 128*1024, \"256K\" 256*1024, \"512K\" 512*1024, \"1M\" 1024*1024, \"2M\" 2048*1024, \"4M\" 4096*1024, \"8M\" 8192*1024, \"16M\" 16384*1024)\n"; - - -#Read speed on z-axis, processors on x, buffer size on y. - - foreach $proc (sort { $a <=> $b }( keys %results )) - { - foreach $xfer (sort {$a <=> $b} ( keys %{$results{$proc}} )) - { - print GNUPLOT_DATA_OUTPUT $proc . "\t" . $xfer . "\t"; - if($io_type & 1) { - print GNUPLOT_DATA_OUTPUT $results{$proc}{$xfer}[0]{"write-only"} . "\t"; - } - if($io_type & 2) { - print GNUPLOT_DATA_OUTPUT $results{$proc}{$xfer}[1]{"write-only"}. "\t"; - } - if($io_type & 4) { - print GNUPLOT_DATA_OUTPUT $results{$proc}{$xfer}[2]{"write-only"}; - } - print GNUPLOT_DATA_OUTPUT "\n"; - - } - } - - close(GNUPLOT_DATA_OUTPUT); - - draw_plot(1); - - unlink(GNUPLOT_DATA_OUTPUT); -} - -open(GNUPLOT_PIPE, "| tee gnuplot.script | gnuplot -persist") || die "Couldn't run gnuplot: $!\n"; -GNUPLOT_PIPE->autoflush(1); - -write_excel_file; -write_ascii_file; -plot_default_graph1; -sleep 1; -plot_default_graph2; -sleep 1; - -plot_3d_graph3 if $plot_3d; -close(GNUPLOT_PIPE); diff --git a/tools/perform/iopipe.c b/tools/perform/iopipe.c deleted file mode 100644 index fd62d37..0000000 --- a/tools/perform/iopipe.c +++ /dev/null @@ -1,508 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Programmer: Robb Matzke <matzke@llnl.gov> - * Thursday, March 12, 1998 - */ - -/* See H5private.h for how to include headers */ -#include "hdf5.h" - -#include "H5private.h" - -#ifdef H5_HAVE_SYS_TIMEB -#include <sys/timeb.h> -#endif - - -#define RAW_FILE_NAME "iopipe.raw" -#define HDF5_FILE_NAME "iopipe.h5" -#define HEADING "%-16s" -#define PROGRESS '=' - -#if 0 -/* Normal testing */ -#define REQUEST_SIZE_X 4579 -#define REQUEST_SIZE_Y 4579 -#define NREAD_REQUESTS 45 -#define NWRITE_REQUESTS 45 -#else -/* Speedy testing */ -#define REQUEST_SIZE_X 1000 -#define REQUEST_SIZE_Y 1000 -#define NREAD_REQUESTS 45 -#define NWRITE_REQUESTS 45 -#endif - - -/*------------------------------------------------------------------------- - * Function: print_stats - * - * Purpose: Prints statistics - * - * Return: void - * - * Programmer: Robb Matzke - * Thursday, March 12, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -#ifdef H5_HAVE_GETRUSAGE -static void -print_stats (const char *prefix, - struct rusage *r_start, struct rusage *r_stop, - struct timeval *t_start, struct timeval *t_stop, - size_t nbytes) -#else /* H5_HAVE_GETRUSAGE */ -static void -print_stats (const char *prefix, - struct timeval *r_start, struct timeval *r_stop, - struct timeval *t_start, struct timeval *t_stop, - size_t nbytes) -#endif /* H5_HAVE_GETRUSAGE */ -{ - double e_time, bw; -#ifdef H5_HAVE_GETRUSAGE - double u_time, s_time; - - u_time = ((double)(r_stop->ru_utime.tv_sec)+ - (double)(r_stop->ru_utime.tv_usec)/(double)1000000.0F) - - ((double)(r_start->ru_utime.tv_sec)+ - (double)(r_start->ru_utime.tv_usec)/(double)1000000.0F); - - s_time = ((double)(r_stop->ru_stime.tv_sec)+ - (double)(r_stop->ru_stime.tv_usec)/(double)1000000.0F) - - ((double)(r_start->ru_stime.tv_sec)+ - (double)(r_start->ru_stime.tv_usec)/(double)1000000.0F); -#endif -#ifndef H5_HAVE_SYS_TIMEB - e_time = ((double)(t_stop->tv_sec)+ - (double)(t_stop->tv_usec)/(double)1000000.0F) - - ((double)(t_start->tv_sec)+ - (double)(t_start->tv_usec)/(double)1000000.0F); -#else - e_time = ((double)(t_stop->tv_sec)+ - (double)(t_stop->tv_usec)/(double)1000.0F) - - ((double)(t_start->tv_sec)+ - (double)(t_start->tv_usec)/(double)1000.0F); -#endif - bw = (double)nbytes / e_time; - -#ifdef H5_HAVE_GETRUSAGE - printf (HEADING "%1.2fuser %1.2fsystem %1.2felapsed %1.2fMB/s\n", - prefix, u_time, s_time, e_time, bw/(1024*1024)); -#else - printf (HEADING "%1.2felapsed %1.2fMB/s\n", - prefix, e_time, bw/(1024*1024)); -#endif - -} - - -/*------------------------------------------------------------------------- - * Function: synchronize - * - * Purpose: - * - * Return: void - * - * Programmer: Robb Matzke - * Thursday, March 12, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static void -synchronize (void) -{ -#ifdef H5_HAVE_SYSTEM -#if defined(H5_HAVE_WIN32_API) && ! defined(__CYGWIN__) - _flushall(); -#else - int status; - - status = HDsystem("sync"); - HDassert(status >= 0); - - status = HDsystem("df >/dev/null"); - HDassert(status >= 0); -#endif -#endif -} - - -/*------------------------------------------------------------------------- - * Function: main - * - * Purpose: - * - * Return: Success: - * - * Failure: - * - * Programmer: Robb Matzke - * Thursday, March 12, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -int -main (void) -{ - static hsize_t size[2] = {REQUEST_SIZE_X, REQUEST_SIZE_Y}; - static unsigned nread = NREAD_REQUESTS, nwrite = NWRITE_REQUESTS; - - unsigned char *the_data = NULL; - hid_t file, dset, file_space = -1; - herr_t status; -#ifdef H5_HAVE_GETRUSAGE - struct rusage r_start, r_stop; -#else - struct timeval r_start, r_stop; -#endif - struct timeval t_start, t_stop; - int fd; - unsigned u; - hssize_t n; - off_t offset; - hsize_t start[2]; - hsize_t count[2]; - - -#ifdef H5_HAVE_SYS_TIMEB - struct _timeb *tbstart = malloc(sizeof(struct _timeb)); - struct _timeb *tbstop = malloc(sizeof(struct _timeb)); -#endif - /* - * The extra cast in the following statement is a bug workaround for the - * Win32 version 5.0 compiler. - * 1998-11-06 ptl - */ - printf ("I/O request size is %1.1fMB\n", - (double)(hssize_t)(size[0]*size[1])/(double)1024.0F*(double)1024); - - /* Open the files */ - file = H5Fcreate (HDF5_FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - assert (file>=0); - fd = HDopen (RAW_FILE_NAME, O_RDWR|O_CREAT|O_TRUNC, 0666); - assert (fd>=0); - - /* Create the dataset */ - file_space = H5Screate_simple (2, size, size); - assert(file_space >= 0); - dset = H5Dcreate2(file, "dset", H5T_NATIVE_UCHAR, file_space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - assert(dset >= 0); - the_data = (unsigned char *)malloc((size_t)(size[0] * size[1])); - - /* initial fill for lazy malloc */ - HDmemset(the_data, 0xAA, (size_t)(size[0] * size[1])); - - /* Fill raw */ - synchronize (); -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_start); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_start, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstart); -#endif -#endif - fprintf (stderr, HEADING, "fill raw"); - for(u = 0; u < nwrite; u++) { - putc (PROGRESS, stderr); - HDfflush(stderr); - HDmemset(the_data, 0xAA, (size_t)(size[0]*size[1])); - } -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_stop); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_stop, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstop); - t_start.tv_sec = tbstart->time; - t_start.tv_usec = tbstart->millitm; - t_stop.tv_sec = tbstop->time; - t_stop.tv_usec = tbstop->millitm; -#endif -#endif - putc ('\n', stderr); - print_stats ("fill raw", - &r_start, &r_stop, &t_start, &t_stop, - (size_t)(nread*size[0]*size[1])); - - - /* Fill hdf5 */ - synchronize (); -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_start); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_start, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstart); -#endif -#endif - fprintf (stderr, HEADING, "fill hdf5"); - for(u = 0; u < nread; u++) { - putc (PROGRESS, stderr); - HDfflush(stderr); - status = H5Dread (dset, H5T_NATIVE_UCHAR, file_space, file_space, - H5P_DEFAULT, the_data); - assert (status>=0); - } -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_stop); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_stop, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstop); - t_start.tv_sec = tbstart->time; - t_start.tv_usec = tbstart->millitm; - t_stop.tv_sec = tbstop->time; - t_stop.tv_usec = tbstop->millitm; -#endif -#endif - putc ('\n', stderr); - print_stats ("fill hdf5", - &r_start, &r_stop, &t_start, &t_stop, - (size_t)(nread*size[0]*size[1])); - - /* Write the raw dataset */ - synchronize (); -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_start); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_start, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstart); -#endif -#endif - fprintf (stderr, HEADING, "out raw"); - for(u = 0; u < nwrite; u++) { - putc (PROGRESS, stderr); - HDfflush(stderr); - offset = HDlseek (fd, (off_t)0, SEEK_SET); - assert (0==offset); - n = HDwrite (fd, the_data, (size_t)(size[0]*size[1])); - assert (n>=0 && (size_t)n==size[0]*size[1]); - } -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_stop); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_stop, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstop); - t_start.tv_sec = tbstart->time; - t_start.tv_usec = tbstart->millitm; - t_stop.tv_sec = tbstop->time; - t_stop.tv_usec = tbstop->millitm; -#endif -#endif - putc ('\n', stderr); - print_stats ("out raw", - &r_start, &r_stop, &t_start, &t_stop, - (size_t)(nread*size[0]*size[1])); - - /* Write the hdf5 dataset */ - synchronize (); -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_start); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_start, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstart); -#endif -#endif - fprintf (stderr, HEADING, "out hdf5"); - for(u = 0; u < nwrite; u++) { - putc (PROGRESS, stderr); - HDfflush(stderr); - status = H5Dwrite (dset, H5T_NATIVE_UCHAR, H5S_ALL, H5S_ALL, - H5P_DEFAULT, the_data); - assert (status>=0); - } -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_stop); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_stop, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstop); - t_start.tv_sec = tbstart->time; - t_start.tv_usec = tbstart->millitm; - t_stop.tv_sec = tbstop->time; - t_stop.tv_usec = tbstop->millitm; -#endif -#endif - putc ('\n', stderr); - print_stats ("out hdf5", - &r_start, &r_stop, &t_start, &t_stop, - (size_t)(nread*size[0]*size[1])); - - /* Read the raw dataset */ - synchronize (); -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_start); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_start, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstart); -#endif -#endif - fprintf (stderr, HEADING, "in raw"); - for(u = 0; u < nread; u++) { - putc (PROGRESS, stderr); - HDfflush(stderr); - offset = HDlseek (fd, (off_t)0, SEEK_SET); - assert (0==offset); - n = HDread (fd, the_data, (size_t)(size[0]*size[1])); - assert (n>=0 && (size_t)n==size[0]*size[1]); - } -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_stop); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_stop, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstop); - t_start.tv_sec = tbstart->time; - t_start.tv_usec = tbstart->millitm; - t_stop.tv_sec = tbstop->time; - t_stop.tv_usec = tbstop->millitm; -#endif -#endif - putc ('\n', stderr); - print_stats ("in raw", - &r_start, &r_stop, &t_start, &t_stop, - (size_t)(nread*size[0]*size[1])); - - - /* Read the hdf5 dataset */ - synchronize (); -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_start); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_start, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstart); -#endif -#endif - fprintf (stderr, HEADING, "in hdf5"); - for(u = 0; u < nread; u++) { - putc (PROGRESS, stderr); - HDfflush(stderr); - status = H5Dread (dset, H5T_NATIVE_UCHAR, file_space, file_space, - H5P_DEFAULT, the_data); - assert (status>=0); - } -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_stop); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_stop, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstop); - t_start.tv_sec = tbstart->time; - t_start.tv_usec = tbstart->millitm; - t_stop.tv_sec = tbstop->time; - t_stop.tv_usec = tbstop->millitm; -#endif -#endif - putc ('\n', stderr); - print_stats ("in hdf5", - &r_start, &r_stop, &t_start, &t_stop, - (size_t)(nread*size[0]*size[1])); - - /* Read hyperslab */ - assert (size[0]>20 && size[1]>20); - start[0] = start[1] = 10; - count[0] = count[1] = size[0]-20; - status = H5Sselect_hyperslab (file_space, H5S_SELECT_SET, start, NULL, count, NULL); - assert (status>=0); - synchronize (); -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_start); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_start, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstart); -#endif -#endif - fprintf (stderr, HEADING, "in hdf5 partial"); - for(u = 0; u < nread; u++) { - putc (PROGRESS, stderr); - HDfflush(stderr); - status = H5Dread (dset, H5T_NATIVE_UCHAR, file_space, file_space, - H5P_DEFAULT, the_data); - assert (status>=0); - } -#ifdef H5_HAVE_GETRUSAGE - HDgetrusage(RUSAGE_SELF, &r_stop); -#endif -#ifdef H5_HAVE_GETTIMEOFDAY - HDgettimeofday(&t_stop, NULL); -#else -#ifdef H5_HAVE_SYS_TIMEB - _ftime(tbstop); - t_start.tv_sec = tbstart->time; - t_start.tv_usec = tbstart->millitm; - t_stop.tv_sec = tbstop->time; - t_stop.tv_usec = tbstop->millitm; -#endif -#endif - putc('\n', stderr); - print_stats("in hdf5 partial", - &r_start, &r_stop, &t_start, &t_stop, - (size_t)(nread*count[0]*count[1])); - - - - /* Close everything */ - HDclose(fd); - H5Dclose(dset); - H5Sclose(file_space); - H5Fclose(file); - free(the_data); - - return 0; -} - diff --git a/tools/perform/overhead.c b/tools/perform/overhead.c deleted file mode 100644 index 98093c7..0000000 --- a/tools/perform/overhead.c +++ /dev/null @@ -1,408 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Programmer: Robb Matzke <matzke@llnl.gov> - * Monday, September 28, 1998 - * - * Purpose: Creates a chunked dataset and measures the storage overhead. - */ - -/* See H5private.h for how to include headers */ -#undef NDEBUG -#include "hdf5.h" -#include "H5private.h" - -#ifdef H5_STDC_HEADERS -# include <ctype.h> -# include <fcntl.h> -# include <stdlib.h> -# include <sys/stat.h> -# include <string.h> -#endif - -#ifdef H5_HAVE_IO_H -# include <io.h> -#endif - -#ifdef H5_HAVE_UNISTD_H -# include <sys/types.h> -# include <unistd.h> -#endif - -/* Solaris Studio defines attribute, but for the attributes we need */ -#if !defined(H5_HAVE_ATTRIBUTE) || defined __cplusplus || defined(__SUNPRO_C) -# undef __attribute__ -# define __attribute__(X) /*void*/ -# define H5_ATTR_UNUSED /*void*/ -#else -# define H5_ATTR_UNUSED __attribute__((unused)) -#endif - -#define FILE_NAME_1 "overhead.h5" -#ifndef FALSE -#define FALSE 0 -#endif /* FALSE */ -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ - -typedef enum fill_t { - FILL_ALL, - FILL_FORWARD, - FILL_REVERSE, - FILL_INWARD, - FILL_OUTWARD, - FILL_RANDOM -} fill_t; - - -/*------------------------------------------------------------------------- - * Function: usage - * - * Purpose: Prints a usage message and exits. - * - * Return: never returns - * - * Programmer: Robb Matzke - * Wednesday, September 30, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static void -usage(const char *prog) -{ - fprintf(stderr, "usage: %s [STYLE|cache] [LEFT [MIDDLE [RIGHT]]]\n", - prog); - fprintf(stderr, "\ - STYLE is the order that the dataset is filled and should be one of:\n\ - forward -- Fill the dataset from lowest address to highest\n\ - address. This style tests the right split ratio.\n\ - reverse -- Fill the dataset from highest address to lowest\n\ - address. This is the reverse order of `forward' and\n\ - tests the left split ratio.\n\ - inward -- Fill beginning at both the lowest and highest\n\ - addresses and work in toward the center of the\n\ - dataset. This tests the middle split ratio.\n\ - outward -- Start at the center of the dataset and work outward\n\ - toward the lowest and highest addresses. This tests\n\ - both left and right split ratios.\n\ - random -- Write the chunks of the dataset in random order. This\n\ - tests all split ratios.\n\ - If no fill style is specified then all fill styles are tried and a\n\ - single value is printed for each one.\n\ -\n\ - If the word `cache' is used instead of a fill style then the raw data\n\ - cache is enabled. It is not possible to enable the raw data cache when\n\ - a specific fill style is used because H5Fflush() is called after each\n\ - chunk is written in order to calculate overhead during the test. If\n\ - the cache is enabled then chunks are written to disk in different orders\n\ - than the actual H5Dwrite() calls in the test due to collisions and the\n\ - resulting B-tree will be split differently.\n\ -\n\ - LEFT, MIDDLE, and RIGHT are the ratios to use for splitting and should\n\ - be values between zero and one, inclusive.\n"); - exit(1); -} - - -/*------------------------------------------------------------------------- - * Function: cleanup - * - * Purpose: Removes test files - * - * Return: void - * - * Programmer: Robb Matzke - * Thursday, June 4, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static void -cleanup (void) -{ - if (!getenv ("HDF5_NOCLEANUP")) { - remove (FILE_NAME_1); - } -} - - -/*------------------------------------------------------------------------- - * Function: display_error_cb - * - * Purpose: Displays the error stack after printing "*FAILED*". - * - * Return: Success: 0 - * - * Failure: -1 - * - * Programmer: Robb Matzke - * Wednesday, March 4, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -display_error_cb (hid_t estack, void H5_ATTR_UNUSED *client_data) -{ - puts ("*FAILED*"); - H5Eprint2(estack, stdout); - - return 0; -} - - -/*------------------------------------------------------------------------- - * Function: test - * - * Purpose: The guts of the test - * - * Return: Success: 0 - * - * Failure: number of errors - * - * Programmer: Robb Matzke - * Wednesday, September 30, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static int -test(fill_t fill_style, const double splits[], - hbool_t verbose, hbool_t use_rdcc) -{ - hid_t file = (-1), fapl = (-1), dcpl = (-1), xfer = (-1), mspace = (-1), fspace = (-1), dset = (-1); - hsize_t ch_size[1] = {1}; /*chunk size */ - hsize_t cur_size[1] = {1000}; /*current dataset size */ - hsize_t max_size[1] = {H5S_UNLIMITED}; /*maximum dataset size */ - hsize_t hs_start[1]; /*hyperslab start offset*/ - hsize_t hs_count[1] = {1}; /*hyperslab nelmts */ - int fd = (-1); /*h5 file direct */ - int *had = NULL; /*for random filling */ - const char *sname=NULL; /*fill style nam */ - int mdc_nelmts; /*num meta objs to cache*/ - hsize_t i, k; - int j; - h5_stat_t sb; - - if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) goto error; - if(!use_rdcc) { - if(H5Pget_cache(fapl, &mdc_nelmts, NULL, NULL, NULL) < 0) goto error; - if(H5Pset_cache(fapl, mdc_nelmts, 0, 0, 0.0F) < 0) goto error; - } - if((file = H5Fcreate(FILE_NAME_1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) goto error; - if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) goto error; - if(H5Pset_chunk(dcpl, 1, ch_size) < 0) goto error; - if((xfer = H5Pcreate(H5P_DATASET_XFER)) < 0) goto error; - if(H5Pset_btree_ratios(xfer, splits[0], splits[1], splits[2]) < 0) goto error; - if((fspace = H5Screate_simple(1, cur_size, max_size)) < 0) goto error; - if((mspace = H5Screate_simple(1, ch_size, ch_size)) < 0) goto error; - if((dset = H5Dcreate2(file, "chunked", H5T_NATIVE_INT, - fspace, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) goto error; - if ((fd=HDopen(FILE_NAME_1, O_RDONLY, 0666)) < 0) goto error; - - if(FILL_RANDOM==fill_style) - had = (int *)calloc((size_t)cur_size[0], sizeof(int)); - - for (i=1; i<=cur_size[0]; i++) { - - /* Decide which chunk to write to */ - switch (fill_style) { - case FILL_FORWARD: - hs_start[0] = i-1; - break; - case FILL_REVERSE: - hs_start[0] = cur_size[0]-i; - break; - case FILL_INWARD: - hs_start[0] = i%2 ? i/2 : cur_size[0]-i/2; - break; - case FILL_OUTWARD: - k = (cur_size[0] - i) + 1; - hs_start[0] = k % 2 ? (k / 2) : (hsize_t)((hssize_t)cur_size[0] - (hssize_t)(k / 2)); - break; - case FILL_RANDOM: - for (j=HDrand()%(int)cur_size[0]; had[j]; j=(j+1)%(int)cur_size[0]) - /*void*/; - hs_start[0] = (hsize_t)j; - had[j] = 1; - break; - case FILL_ALL: - abort(); - default: - /* unknown request */ - HDfprintf(stderr, "Unknown fill style\n"); - goto error; - break; - } - - /* Write the chunk */ - if (H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_start, NULL, - hs_count, NULL) < 0) goto error; - if (H5Dwrite(dset, H5T_NATIVE_INT, mspace, fspace, xfer, &i) < 0) { - goto error; - } - - /* Determine overhead */ - if (verbose) { - if (H5Fflush(file, H5F_SCOPE_LOCAL) < 0) goto error; - if (HDfstat(fd, &sb) < 0) goto error; - printf("%4lu %8.3f ***\n", - (unsigned long)i, - (double)(sb.st_size - (HDoff_t)(i * sizeof(int))) / (double)i); - } - } - - if(had) { - free(had); - had = NULL; - } /* end if */ - - H5Dclose(dset); - H5Sclose(mspace); - H5Sclose(fspace); - H5Pclose(dcpl); - H5Pclose(xfer); - H5Fclose(file); - - if (!verbose) { - switch (fill_style) { - case FILL_FORWARD: - sname = "forward"; - break; - case FILL_REVERSE: - sname = "reverse"; - break; - case FILL_INWARD: - sname = "inward"; - break; - case FILL_OUTWARD: - sname = "outward"; - break; - case FILL_RANDOM: - sname = "random"; - break; - case FILL_ALL: - abort(); - default: - /* unknown request */ - HDfprintf(stderr, "Unknown fill style\n"); - goto error; - break; - } - - if (HDfstat(fd, &sb) < 0) goto error; - printf("%-7s %8.3f\n", sname, - (double)(sb.st_size - (HDoff_t)(cur_size[0] * sizeof(int))) / - (double)cur_size[0]); - } - HDclose(fd); - - return 0; - - error: - H5Dclose(dset); - H5Sclose(mspace); - H5Sclose(fspace); - H5Pclose(dcpl); - H5Pclose(xfer); - H5Fclose(file); - if(had) - free(had); - HDclose(fd); - return 1; -} - - -/*------------------------------------------------------------------------- - * Function: main - * - * Purpose: - * - * Return: Success: zero - * - * Failure: non-zero - * - * Programmer: Robb Matzke - * Monday, September 28, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -int -main(int argc, char *argv[]) -{ - hid_t xfer; - fill_t fill_style = FILL_ALL; - hbool_t use_cache = FALSE; - double splits[3]; - int i, j, nerrors=0; - - /* Default split ratios */ - H5Eset_auto2(H5E_DEFAULT, display_error_cb, NULL); - - if((xfer = H5Pcreate(H5P_DATASET_XFER)) < 0) goto error; - if(H5Pget_btree_ratios(xfer, splits+0, splits+1, splits+2) < 0) goto error; - if(H5Pclose(xfer) < 0) goto error; - - /* Parse command-line options */ - for(i = 1, j = 0; i < argc; i++) { - if (!strcmp(argv[i], "forward")) { - fill_style = FILL_FORWARD; - } else if (!strcmp(argv[i], "reverse")) { - fill_style = FILL_REVERSE; - } else if (!strcmp(argv[i], "inward")) { - fill_style = FILL_INWARD; - } else if (!strcmp(argv[i], "outward")) { - fill_style = FILL_OUTWARD; - } else if (!strcmp(argv[i], "random")) { - fill_style = FILL_RANDOM; - } else if (!strcmp(argv[i], "cache")) { - use_cache = TRUE; - } else if (j<3 && (isdigit(argv[i][0]) || '.'==argv[i][0])) { - splits[j++] = strtod(argv[i], NULL); - } else { - usage(argv[0]); - } - } - - if (FILL_ALL==fill_style) { - printf("%-7s %8s\n", "Style", "Bytes/Chunk"); - printf("%-7s %8s\n", "-----", "-----------"); - nerrors += test(FILL_FORWARD, splits, FALSE, use_cache); - nerrors += test(FILL_REVERSE, splits, FALSE, use_cache); - nerrors += test(FILL_INWARD, splits, FALSE, use_cache); - nerrors += test(FILL_OUTWARD, splits, FALSE, use_cache); - nerrors += test(FILL_RANDOM, splits, FALSE, use_cache); - } - else { - if (use_cache) usage(argv[0]); - nerrors += test(fill_style, splits, TRUE, FALSE); - } - if (nerrors>0) goto error; - cleanup(); - return 0; - - error: - fprintf(stderr, "*** ERRORS DETECTED ***\n"); - return 1; -} diff --git a/tools/perform/perf.c b/tools/perform/perf.c deleted file mode 100644 index 7b9590c..0000000 --- a/tools/perform/perf.c +++ /dev/null @@ -1,494 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Author: Albert Cheng of NCSA, May 1, 2001. - * This is derived from code given to me by Robert Ross. - * - * NOTE: This code assumes that all command line arguments make it out to all - * the processes that make up the parallel job, which isn't always the case. - * So if it doesn't work on some platform, that might be why. - */ - -#include "hdf5.h" -#include "H5private.h" - -#ifdef H5_HAVE_PARALLEL - -#ifdef H5_STDC_HEADERS -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#endif - -#ifdef H5_HAVE_UNISTD_H -#include <sys/types.h> -#include <unistd.h> -#endif - -#ifdef H5_HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#if defined(H5_TIME_WITH_SYS_TIME) -# include <sys/time.h> -# include <time.h> -#elif defined(H5_HAVE_SYS_TIME_H) -# include <sys/time.h> -#else -# include <time.h> -#endif - -#include <mpi.h> -#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */ -# include <mpio.h> -#endif - -/* Macro definitions */ -/* Verify: - * if val is false (0), print mesg and if fatal is true (non-zero), die. - */ -#define H5FATAL 1 -#define VRFY(val, mesg, fatal) do { \ - if (!val) { \ - printf("Proc %d: ", mynod); \ - printf("*** Assertion failed (%s) at line %4d in %s\n", \ - mesg, (int)__LINE__, __FILE__); \ - if (fatal){ \ - fflush(stdout); \ - goto die_jar_jar_die; \ - } \ - } \ -} while(0) -#define RANK 1 -#define MAX_PATH 1024 - -hsize_t dims[RANK]; /* dataset dim sizes */ -hsize_t block[RANK], stride[RANK], count[RANK]; -hssize_t start[RANK]; -hid_t fid; /* HDF5 file ID */ -hid_t acc_tpl; /* File access templates */ -hid_t sid; /* Dataspace ID */ -hid_t file_dataspace; /* File dataspace ID */ -hid_t mem_dataspace; /* memory dataspace ID */ -hid_t dataset; /* Dataset ID */ -hsize_t opt_alignment = 1; -hsize_t opt_threshold = 1; -int opt_split_vfd = 0; -char *meta_ext, *raw_ext; /* holds the meta and raw file extension if */ - /* opt_split_vfd is set */ - - -/* DEFAULT VALUES FOR OPTIONS */ -int64_t opt_block = 1048576*16; -int opt_iter = 1; -int opt_stripe = -1; -int opt_correct = 0; -int amode = O_RDWR | O_CREAT; -char opt_file[256] = "perftest.out"; -char opt_pvfstab[256] = "notset"; -int opt_pvfstab_set = 0; - -const char *FILENAME[] = { - opt_file, - NULL -}; - -/* function prototypes */ -static int parse_args(int argc, char **argv); - -extern int errno; - -/* globals needed for getopt */ -extern char *optarg; - -int main(int argc, char **argv) -{ - char *buf, *tmp, *buf2, *tmp2, *check; - int i, j, mynod=0, nprocs=1, err, my_correct = 1, correct, myerrno; - double stim, etim; - double write_tim = 0; - double read_tim = 0; - double read_bw, write_bw; - double max_read_tim, max_write_tim; - double min_read_tim, min_write_tim; - double ave_read_tim, ave_write_tim; - int64_t iter_jump = 0; - int64_t seek_position = 0; - MPI_File fh; - MPI_Status status; - int nchars; - char filename[MAX_PATH]; - herr_t ret; /* Generic return value */ - - /* startup MPI and determine the rank of this process */ - MPI_Init(&argc,&argv); - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - MPI_Comm_rank(MPI_COMM_WORLD, &mynod); - - /* parse the command line arguments */ - parse_args(argc, argv); - - if (mynod == 0) printf("# Using hdf5-io calls.\n"); - - /* kindof a weird hack- if the location of the pvfstab file was - * specified on the command line, then spit out this location into - * the appropriate environment variable: */ - -#if H5_HAVE_SETENV -/* no setenv or unsetenv */ - if (opt_pvfstab_set) { - if((setenv("PVFSTAB_FILE", opt_pvfstab, 1)) < 0){ - perror("setenv"); - goto die_jar_jar_die; - } - } -#endif - - /* this is how much of the file data is covered on each iteration of - * the test. used to help determine the seek offset on each - * iteration */ - iter_jump = nprocs * opt_block; - - /* setup a buffer of data to write */ - if (!(tmp = (char *) malloc(opt_block + 256))) { - perror("malloc"); - goto die_jar_jar_die; - } - buf = tmp + 128 - (((long)tmp) % 128); /* align buffer */ - - if (opt_correct) { - /* do the same buffer setup for verifiable data */ - if (!(tmp2 = (char *) malloc(opt_block + 256))) { - perror("malloc2"); - goto die_jar_jar_die; - } - buf2 = tmp + 128 - (((long)tmp) % 128); - } - - /* setup file access template with parallel IO access. */ - if (opt_split_vfd){ - hid_t mpio_pl; - - mpio_pl = H5Pcreate (H5P_FILE_ACCESS); - VRFY((acc_tpl >= 0), "", H5FATAL); - ret = H5Pset_fapl_mpio(mpio_pl, MPI_COMM_WORLD, MPI_INFO_NULL); - VRFY((ret >= 0), "", H5FATAL); - - /* set optional allocation alignment */ - if (opt_alignment*opt_threshold != 1){ - ret = H5Pset_alignment(acc_tpl, opt_threshold, opt_alignment ); - VRFY((ret >= 0), "H5Pset_alignment succeeded", !H5FATAL); - } - - /* setup file access template */ - acc_tpl = H5Pcreate (H5P_FILE_ACCESS); - VRFY((acc_tpl >= 0), "", H5FATAL); - ret = H5Pset_fapl_split(acc_tpl, meta_ext, mpio_pl, raw_ext, mpio_pl); - VRFY((ret >= 0), "H5Pset_fapl_split succeeded", H5FATAL); - ret = H5Pclose(mpio_pl); - VRFY((ret >= 0), "H5Pclose mpio_pl succeeded", H5FATAL); - }else{ - /* setup file access template */ - acc_tpl = H5Pcreate (H5P_FILE_ACCESS); - VRFY((acc_tpl >= 0), "", H5FATAL); - ret = H5Pset_fapl_mpio(acc_tpl, MPI_COMM_WORLD, MPI_INFO_NULL); - VRFY((ret >= 0), "", H5FATAL); - - /* set optional allocation alignment */ - if (opt_alignment*opt_threshold != 1){ - ret = H5Pset_alignment(acc_tpl, opt_threshold, opt_alignment ); - VRFY((ret >= 0), "H5Pset_alignment succeeded", !H5FATAL); - } - } - - h5_fixname_no_suffix(FILENAME[0], acc_tpl, filename, sizeof filename); - - /* create the parallel file */ - fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl); - VRFY((fid >= 0), "H5Fcreate succeeded", H5FATAL); - - /* define a contiquous dataset of opt_iter*nprocs*opt_block chars */ - dims[0] = opt_iter * nprocs * opt_block; - sid = H5Screate_simple(RANK, dims, NULL); - VRFY((sid >= 0), "H5Screate_simple succeeded", H5FATAL); - dataset = H5Dcreate2(fid, "Dataset1", H5T_NATIVE_CHAR, sid, - H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - VRFY((dataset >= 0), "H5Dcreate2 succeeded", H5FATAL); - - /* create the memory dataspace and the file dataspace */ - dims[0] = opt_block; - mem_dataspace = H5Screate_simple(RANK, dims, NULL); - VRFY((mem_dataspace >= 0), "", H5FATAL); - file_dataspace = H5Dget_space(dataset); - VRFY((file_dataspace >= 0), "H5Dget_space succeeded", H5FATAL); - - /* now each process writes a block of opt_block chars in round robbin - * fashion until the whole dataset is covered. - */ - for(j=0; j < opt_iter; j++) { - /* setup a file dataspace selection */ - start[0] = (j*iter_jump)+(mynod*opt_block); - stride[0] = block[0] = opt_block; - count[0]= 1; - ret=H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block); - VRFY((ret >= 0), "H5Sset_hyperslab succeeded", H5FATAL); - - if (opt_correct) /* fill in buffer for iteration */ { - for (i=mynod+j, check=buf; i<opt_block; i++,check++) *check=(char)i; - } - - /* discover the starting time of the operation */ - MPI_Barrier(MPI_COMM_WORLD); - stim = MPI_Wtime(); - - /* write data */ - ret = H5Dwrite(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, - H5P_DEFAULT, buf); - VRFY((ret >= 0), "H5Dwrite dataset1 succeeded", !H5FATAL); - - /* discover the ending time of the operation */ - etim = MPI_Wtime(); - - write_tim += (etim - stim); - - /* we are done with this "write" iteration */ - } - - /* close dataset and file */ - ret=H5Dclose(dataset); - VRFY((ret >= 0), "H5Dclose succeeded", H5FATAL); - ret=H5Fclose(fid); - VRFY((ret >= 0), "H5Fclose succeeded", H5FATAL); - - - - /* wait for everyone to synchronize at this point */ - MPI_Barrier(MPI_COMM_WORLD); - - /* reopen the file for reading */ - fid=H5Fopen(filename,H5F_ACC_RDONLY,acc_tpl); - VRFY((fid >= 0), "", H5FATAL); - - /* open the dataset */ - dataset = H5Dopen2(fid, "Dataset1", H5P_DEFAULT); - VRFY((dataset >= 0), "H5Dopen succeeded", H5FATAL); - - /* we can re-use the same mem_dataspace and file_dataspace - * the H5Dwrite used since the dimension size is the same. - */ - - /* we are going to repeat the read the same pattern the write used */ - for (j=0; j < opt_iter; j++) { - /* setup a file dataspace selection */ - start[0] = (j*iter_jump)+(mynod*opt_block); - stride[0] = block[0] = opt_block; - count[0]= 1; - ret=H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block); - VRFY((ret >= 0), "H5Sset_hyperslab succeeded", H5FATAL); - /* seek to the appropriate spot give the current iteration and - * rank within the MPI processes */ - - /* discover the start time */ - MPI_Barrier(MPI_COMM_WORLD); - stim = MPI_Wtime(); - - /* read in the file data */ - if (!opt_correct){ - ret = H5Dread(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf); - } - else{ - ret = H5Dread(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf2); - } - myerrno = errno; - - /* discover the end time */ - etim = MPI_Wtime(); - read_tim += (etim - stim); - VRFY((ret >= 0), "H5Dwrite dataset1 succeeded", !H5FATAL); - - - if (ret < 0) fprintf(stderr, "node %d, read error, loc = %Ld: %s\n", - mynod, mynod*opt_block, strerror(myerrno)); - - /* if the user wanted to check correctness, compare the write - * buffer to the read buffer */ - if (opt_correct && memcmp(buf, buf2, opt_block)) { - fprintf(stderr, "node %d, correctness test failed\n", mynod); - my_correct = 0; - MPI_Allreduce(&my_correct, &correct, 1, MPI_INT, MPI_MIN, - MPI_COMM_WORLD); - } - - /* we are done with this read iteration */ - } - - /* close dataset and file */ - ret=H5Dclose(dataset); - VRFY((ret >= 0), "H5Dclose succeeded", H5FATAL); - ret=H5Fclose(fid); - VRFY((ret >= 0), "H5Fclose succeeded", H5FATAL); - ret=H5Pclose(acc_tpl); - VRFY((ret >= 0), "H5Pclose succeeded", H5FATAL); - - /* compute the read and write times */ - MPI_Allreduce(&read_tim, &max_read_tim, 1, MPI_DOUBLE, MPI_MAX, - MPI_COMM_WORLD); - MPI_Allreduce(&read_tim, &min_read_tim, 1, MPI_DOUBLE, MPI_MIN, - MPI_COMM_WORLD); - MPI_Allreduce(&read_tim, &ave_read_tim, 1, MPI_DOUBLE, MPI_SUM, - MPI_COMM_WORLD); - - /* calculate the average from the sum */ - ave_read_tim = ave_read_tim / nprocs; - - MPI_Allreduce(&write_tim, &max_write_tim, 1, MPI_DOUBLE, MPI_MAX, - MPI_COMM_WORLD); - MPI_Allreduce(&write_tim, &min_write_tim, 1, MPI_DOUBLE, MPI_MIN, - MPI_COMM_WORLD); - MPI_Allreduce(&write_tim, &ave_write_tim, 1, MPI_DOUBLE, MPI_SUM, - MPI_COMM_WORLD); - - /* calculate the average from the sum */ - ave_write_tim = ave_write_tim / nprocs; - - /* print out the results on one node */ - if (mynod == 0) { - read_bw = ((int64_t)(opt_block*nprocs*opt_iter))/(max_read_tim*1000000.0); - write_bw = ((int64_t)(opt_block*nprocs*opt_iter))/(max_write_tim*1000000.0); - - printf("nr_procs = %d, nr_iter = %d, blk_sz = %ld\n", nprocs, - opt_iter, (long)opt_block); - - printf("# total_size = %ld\n", (long)(opt_block*nprocs*opt_iter)); - - printf("# Write: min_time = %f, max_time = %f, mean_time = %f\n", - min_write_tim, max_write_tim, ave_write_tim); - printf("# Read: min_time = %f, max_time = %f, mean_time = %f\n", - min_read_tim, max_read_tim, ave_read_tim); - - printf("Write bandwidth = %f Mbytes/sec\n", write_bw); - printf("Read bandwidth = %f Mbytes/sec\n", read_bw); - - if (opt_correct) { - printf("Correctness test %s.\n", correct ? "passed" : "failed"); - } - } - - -die_jar_jar_die: - -#if H5_HAVE_SETENV -/* no setenv or unsetenv */ - /* clear the environment variable if it was set earlier */ - if (opt_pvfstab_set){ - unsetenv("PVFSTAB_FILE"); - } -#endif - - free(tmp); - if (opt_correct) free(tmp2); - - MPI_Finalize(); - - return(0); -} - -static int -parse_args(int argc, char **argv) -{ - int c; - - while ((c = getopt(argc, argv, "s:b:i:f:p:a:2:c")) != EOF) { - switch (c) { - case 's': /* stripe */ - opt_stripe = atoi(optarg); - break; - case 'b': /* block size */ - opt_block = atoi(optarg); - break; - case 'i': /* iterations */ - opt_iter = atoi(optarg); - break; - case 'f': /* filename */ - strncpy(opt_file, optarg, 255); - FILENAME[0] = opt_file; - break; - case 'p': /* pvfstab file */ - strncpy(opt_pvfstab, optarg, 255); - opt_pvfstab_set = 1; - break; - case 'a': /* aligned allocation. - * syntax: -a<alignment>/<threshold> - * e.g., -a4096/512 allocate at 4096 bytes - * boundary if request size >= 512. - */ - {char *p; - opt_alignment = atoi(optarg); - if (p=(char*)strchr(optarg, '/')) - opt_threshold = atoi(p+1); - } - HDfprintf(stdout, - "alignment/threshold=%Hu/%Hu\n", - opt_alignment, opt_threshold); - break; - case '2': /* use 2-files, i.e., split file driver */ - opt_split_vfd=1; - /* get meta and raw file extension. */ - /* syntax is <raw_ext>,<meta_ext> */ - meta_ext = raw_ext = optarg; - while (*raw_ext != '\0'){ - if (*raw_ext == ','){ - *raw_ext = '\0'; - raw_ext++; - break; - } - raw_ext++; - } - printf("split-file-vfd used: %s,%s\n", - meta_ext, raw_ext); - break; - case 'c': /* correctness */ - opt_correct = 1; - break; - case '?': /* unknown */ - default: - break; - } - } - - return(0); -} - -/* - * Local variables: - * c-indent-level: 3 - * c-basic-offset: 3 - * tab-width: 3 - * End: - */ - -#else /* H5_HAVE_PARALLEL */ -/* dummy program since H5_HAVE_PARALLEL is not configured in */ -int -main(int H5_ATTR_UNUSED argc, char H5_ATTR_UNUSED **argv) -{ - printf("No parallel performance because parallel is not configured in\n"); - return(0); -} -#endif /* H5_HAVE_PARALLEL */ - diff --git a/tools/perform/perf_meta.c b/tools/perform/perf_meta.c deleted file mode 100644 index 2c3a19c..0000000 --- a/tools/perform/perf_meta.c +++ /dev/null @@ -1,850 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Programmer: Raymond Lu <slu@ncsa.uiuc.edu> - * Friday, Oct 3, 2004 - * - * Purpose: Tests performance of metadata - */ - -#include "h5test.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 */ - -/* Which test to run */ -int RUN_TEST = 0x0; /* all tests as default */ -int TEST_1 = 0x1; /* Test 1 */ -int TEST_2 = 0x2; /* Test 2 */ -int TEST_3 = 0x4; /* Test 3 */ - - -const char *FILENAME[] = { - "meta_perf_1", - "meta_perf_2", - "meta_perf_3", - NULL -}; - -/* Default values for performance. Can be changed through command line options */ -int NUM_DSETS = 16; -int NUM_ATTRS = 8; -int BATCH_ATTRS = 2; -hbool_t flush_dset = FALSE; -hbool_t flush_attr = FALSE; -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) -{ - int t; - - /* 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 'm': /* Use the MPI-IO driver */ - facc_type = FACC_MPIO; - break; - - case 'f': /* Call H5Fflush for each dataset or attribute */ - if(!strcmp("a", (*argv+2))) - flush_attr = TRUE; - else if(!strcmp("d", (*argv+2))) - flush_dset = TRUE; - else { - nerrors++; - return(1); - } - break; - - case 't': /* Which test to run */ - t = atoi((*argv+1)+1); - if (t < 1 || t > 3){ - nerrors++; - return(1); - } - if(t == 1) - RUN_TEST |= TEST_1; - else if(t == 2) - RUN_TEST |= TEST_2; - else - RUN_TEST |= TEST_3; - - break; - - default: nerrors++; - return(1); - } - } - } /*while*/ - - /* Check valid values */ -#ifndef H5_HAVE_PARALLEL - if(facc_type == FACC_MPIO) - { - nerrors++; - return(1); - } -#endif /*H5_HAVE_PARALLEL*/ - - if(NUM_ATTRS && !BATCH_ATTRS) - NUM_ATTRS = 0; - - if(!NUM_ATTRS && BATCH_ATTRS) - BATCH_ATTRS = 0; - - if(!NUM_DSETS) { - 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] [-d<num_datasets>]" - "[-a<num_attributes>]\n" - "\t[-n<batch_attributes>] [-f<option>] [-t<test>]\n"); - printf("\t-h" - "\t\t\thelp page.\n"); - printf("\t-m" - "\t\t\tset MPIO as the file driver when parallel HDF5\n" - "\t\t\t\tis enabled. -m must be specified\n" - "\t\t\t\twhen running parallel program.\n"); - printf("\t-d<num_datasets>" - "\tset number of datasets for meta data \n" - "\t\t\t\tperformance test\n"); - printf("\t-a<num_attributes>" - "\tset number of attributes per dataset for meta \n" - "\t\t\t\tdata performance test.\n"); - printf("\t-n<batch_attributes>" - "\tset batch number of attributes for dataset \n" - "\t\t\t\tfor meta data performance test.\n"); - printf("\t-f<option>" - "\t\tflush data to disk after closing a dataset \n" - "\t\t\t\tor attribute. Valid options are \"d\" for \n" - "\t\t\t\tdataset, \"a\" for attribute. Disabled is \n" - "\t\t\t\tthe default.\n"); - printf("\t-t<tests>" - "\t\trun specific test. Give only one number each \n" - "\t\t\t\ttime. i.e. \"-t1 -t3\" will run test 1 and 3. \n" - "\t\t\t\tDefault is all three tests. The 3 tests are: \n\n" - "\t\t\t\t1. Create <num_attributes> attributes for each \n" - "\t\t\t\t of <num_datasets> existing datasets.\n" - "\t\t\t\t2. Create <num_attributes> attributes for each \n" - "\t\t\t\t of <num_datasets> new datasets.\n" - "\t\t\t\t3. Create <batch_attributes> attributes for \n" - "\t\t\t\t each of <num_dataset> new datasets for \n" - "\t\t\t\t <num_attributes>/<batch_attributes> times.\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 = H5Dcreate2(file, dset_name, H5T_NATIVE_DOUBLE, space, - H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) - goto error; - - if(H5Dclose(dataset) < 0) - goto error; - } /* end for */ - - 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 filename[128]; - 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, "H5Dopen2"}; - 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) - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); -#endif /*H5_HAVE_PARALLEL*/ - - h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - - if ((file=H5Fcreate(filename, 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 = H5Dopen2(file, dset_name, H5P_DEFAULT)) < 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 = H5Acreate2(dataset, attr_name, H5T_NATIVE_DOUBLE, - small_space, H5P_DEFAULT, H5P_DEFAULT)) < 0) - goto error; - if(H5Aclose(attr) < 0) - goto error; - perf(&attr_t, attr_t.start, retrieve_time()); - if(flush_attr && H5Fflush(file, H5F_SCOPE_LOCAL) < 0) - goto error; - } /* end for */ - - close_t.start = retrieve_time(); - if(H5Dclose(dataset) < 0) - goto error; - perf(&close_t, close_t.start, retrieve_time()); - if(flush_dset && H5Fflush(file, H5F_SCOPE_LOCAL) < 0) - goto error; - } /* end for */ - - if(facc_type == FACC_MPIO) { -#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 filename[128]; - 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, "H5Dcreate2"}; - 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) - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); -#endif /*H5_HAVE_PARALLEL*/ - - h5_fixname(FILENAME[1], fapl, filename, sizeof filename); - - if ((file=H5Fcreate(filename, 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 = H5Dcreate2(file, dset_name, H5T_NATIVE_DOUBLE, - space, H5P_DEFAULT, H5P_DEFAULT, 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 = H5Acreate2(dataset, attr_name, H5T_NATIVE_DOUBLE, - small_space, H5P_DEFAULT, H5P_DEFAULT)) < 0) - goto error; - if(H5Aclose(attr) < 0) - goto error; - perf(&attr_t, attr_t.start, retrieve_time()); - if(flush_attr && H5Fflush(file, H5F_SCOPE_LOCAL) < 0) - goto error; - } /* end for */ - - close_t.start = retrieve_time(); - if(H5Dclose(dataset) < 0) - goto error; - perf(&close_t, close_t.start, retrieve_time()); - if(flush_dset && H5Fflush(file, H5F_SCOPE_LOCAL) < 0) - goto error; - } /* end for */ - -#ifdef H5_HAVE_PARALLEL - if(facc_type == FACC_MPIO) - 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 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_3(void) -{ - hid_t file, dataset, attr; - char filename[128]; - 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, "H5Dopen2"}; - 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) - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); -#endif /*H5_HAVE_PARALLEL*/ - - h5_fixname(FILENAME[2], fapl, filename, sizeof filename); - - if ((file=H5Fcreate(filename, 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 = H5Dopen2(file, dset_name, H5P_DEFAULT)) < 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 = H5Acreate2(dataset, attr_name, H5T_NATIVE_DOUBLE, - small_space, H5P_DEFAULT, H5P_DEFAULT)) < 0) - goto error; - if(H5Aclose(attr) < 0) - goto error; - perf(&attr_t, attr_t.start, retrieve_time()); - if(flush_attr && H5Fflush(file, H5F_SCOPE_LOCAL) < 0) - goto error; - } /* end for */ - - close_t.start = retrieve_time(); - if(H5Dclose(dataset) < 0) - goto error; - perf(&close_t, close_t.start, retrieve_time()); - if(flush_dset && H5Fflush(file, H5F_SCOPE_LOCAL) < 0) - goto error; - } /* end for */ - } /* end for */ - -#ifdef H5_HAVE_PARALLEL - if(facc_type == FACC_MPIO) - 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, "3. 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) -{ -#ifdef H5_HAVE_PARALLEL - if(facc_type == FACC_DEFAULT) { -#endif /*H5_HAVE_PARALLEL*/ - struct timeval t; - HDgettimeofday(&t, NULL); - return ((double)t.tv_sec + (double)t.tv_usec / 1000000); -#ifdef H5_HAVE_PARALLEL - } else { - 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; - -#ifdef H5_HAVE_PARALLEL - if(facc_type == FACC_MPIO) { - 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, MPI_SUM, 0, - MPI_COMM_WORLD); - reduced_t /= mpi_size; - - MPI_Reduce(&t, &t_max, 1, MPI_DOUBLE, MPI_MAX, 0, - MPI_COMM_WORLD); - MPI_Reduce(&t, &t_min, 1, MPI_DOUBLE, 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; - } - } else -#endif /*H5_HAVE_PARALLEL*/ - { - 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; - } - -#ifdef H5_HAVE_PARALLEL - if(facc_type == FACC_MPIO) { - 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); -#ifdef H5_HAVE_PARALLEL - if(facc_type == FACC_MPIO) - H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL); -#endif /*H5_HAVE_PARALLEL*/ - - nerrors += create_dspace() < 0 ?1:0; - - if((RUN_TEST & TEST_1) || !RUN_TEST) - nerrors += create_attrs_1() < 0 ?1:0; - if((RUN_TEST & TEST_2) || !RUN_TEST) - nerrors += create_attrs_2() < 0 ?1:0; - if(((RUN_TEST & TEST_3) || !RUN_TEST) && BATCH_ATTRS && NUM_ATTRS) - nerrors += create_attrs_3() < 0 ?1:0; - - if (H5Sclose(space) < 0) goto error; - if (H5Sclose(small_space) < 0) goto error; - - h5_clean_files(FILENAME, fapl); - -#ifdef H5_HAVE_PARALLEL - if(facc_type == FACC_MPIO) - /* 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; -} - diff --git a/tools/perform/pio_engine.c b/tools/perform/pio_engine.c deleted file mode 100644 index ab11efd..0000000 --- a/tools/perform/pio_engine.c +++ /dev/null @@ -1,2682 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Author: Albert Cheng of NCSA, Oct 24, 2001. - */ - -#include "hdf5.h" - -#ifdef H5_STDC_HEADERS -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#endif - -#ifdef H5_HAVE_UNISTD_H -#include <sys/types.h> -#include <unistd.h> -#endif - -#ifdef H5_HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef H5_HAVE_PARALLEL - -#include <mpi.h> - -#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */ -# include <mpio.h> -#endif /* !MPI_FILE_NULL */ - -#include "pio_perf.h" - -/* Macro definitions */ - -#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 6 -# define H5DCREATE(fd, name, type, space, dcpl) H5Dcreate(fd, name, type, space, dcpl) -# define H5DOPEN(fd, name) H5Dopen(fd, name) -#else -# define H5DCREATE(fd, name, type, space, dcpl) H5Dcreate2(fd, name, type, space, H5P_DEFAULT, dcpl, H5P_DEFAULT) -# define H5DOPEN(fd, name) H5Dopen2(fd, name, H5P_DEFAULT) -#endif - -/* sizes of various items. these sizes won't change during program execution */ -/* The following three must have the same type */ -#define ELMT_SIZE (sizeof(unsigned char)) /* we're doing bytes */ -#define ELMT_MPI_TYPE MPI_BYTE -#define ELMT_H5_TYPE H5T_NATIVE_UCHAR - -#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, "*** 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, "(%s) at line %4d in %s\n", \ - mesg, (int)__LINE__, __FILE__); \ -} - -/* verify: if val is false (0), print mesg. */ -#define VRFY(val, mesg) do { \ - if (!val) { \ - ERRMSG(mesg); \ - GOTOERROR(FAIL); \ - } \ -} while(0) - - -/* POSIX I/O macros */ -#define POSIXCREATE(fn) HDopen(fn, O_CREAT|O_TRUNC|O_RDWR, 0600) -#define POSIXOPEN(fn, F) HDopen(fn, F, 0600) -#define POSIXCLOSE(F) HDclose(F) -#define POSIXSEEK(F,L) HDlseek(F, L, SEEK_SET) -#define POSIXWRITE(F,B,S) HDwrite(F,B,S) -#define POSIXREAD(F,B,S) HDread(F,B,S) - -enum { - PIO_CREATE = 1, - PIO_WRITE = 2, - PIO_READ = 4 -}; - -/* Global variables */ -static int clean_file_g = -1; /*whether to cleanup temporary test */ -/*files. -1 is not defined; */ -/*0 is no cleanup; 1 is do cleanup */ - -/* - * In a parallel machine, the filesystem suitable for compiling is - * unlikely a parallel file system that is suitable for parallel I/O. - * There is no standard pathname for the parallel file system. /tmp - * is about the best guess. - */ -#ifndef HDF5_PARAPREFIX -# define HDF5_PARAPREFIX "" -#endif /* !HDF5_PARAPREFIX */ - -#ifndef MIN -# define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif /* !MIN */ - -/* the different types of file descriptors we can expect */ -typedef union _file_descr { - int posixfd; /* POSIX file handle*/ - MPI_File mpifd; /* MPI file */ - hid_t h5fd; /* HDF5 file */ -} file_descr; - -/* local functions */ -static char *pio_create_filename(iotype iot, const char *base_name, - char *fullname, size_t size); -static herr_t do_write(results *res, file_descr *fd, parameters *parms, - long ndsets, off_t nelmts, size_t buf_size, void *buffer); -static herr_t do_read(results *res, file_descr *fd, parameters *parms, - long ndsets, off_t nelmts, size_t buf_size, void *buffer /*out*/); -static herr_t do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, - int flags); -static herr_t do_fclose(iotype iot, file_descr *fd); -static void do_cleanupfile(iotype iot, char *fname); - -/* - * Function: do_pio - * Purpose: PIO Engine where Parallel IO are executed. - * Return: results - * Programmer: Albert Cheng, Bill Wendling 2001/12/12 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ - results -do_pio(parameters param) -{ - /* return codes */ - herr_t ret_code = 0; /*return code */ - results res; - - file_descr fd; - iotype iot; - - char fname[FILENAME_MAX]; - long nf; - long ndsets; - off_t nbytes; /*number of bytes per dataset */ - off_t snbytes; /*general dataset size */ - /*for 1D, it is the actual dataset size */ - /*for 2D, it is the size of a side of the dataset square */ - char *buffer = NULL; /*data buffer pointer */ - size_t buf_size; /*general buffer size in bytes */ - /*for 1D, it is the actual buffer size */ - /*for 2D, it is the length of the buffer rectangle */ - size_t blk_size; /*data block size in bytes */ - size_t bsize; /*actual buffer size */ - - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - - /* Sanity check parameters */ - - /* IO type */ - iot = param.io_type; - - switch (iot) { - case MPIO: - fd.mpifd = MPI_FILE_NULL; - res.timers = io_time_new(MPI_CLOCK); - break; - case POSIXIO: - fd.posixfd = -1; - res.timers = io_time_new(MPI_CLOCK); - break; - case PHDF5: - fd.h5fd = -1; - res.timers = io_time_new(MPI_CLOCK); - break; - default: - /* unknown request */ - fprintf(stderr, "Unknown IO type request (%d)\n", iot); - GOTOERROR(FAIL); - } - - ndsets = param.num_dsets; /* number of datasets per file */ - nbytes = param.num_bytes; /* number of bytes per dataset */ - buf_size = param.buf_size; - blk_size = param.blk_size; - - if (!param.dim2d){ - snbytes = nbytes; /* General dataset size */ - bsize = buf_size; /* Actual buffer size */ - } - else { - snbytes = (off_t)sqrt(nbytes); /* General dataset size */ - bsize = buf_size * blk_size; /* Actual buffer size */ - } - - if (param.num_files < 0 ) { - fprintf(stderr, - "number of files must be >= 0 (%ld)\n", - param.num_files); - GOTOERROR(FAIL); - } - - if (ndsets < 0 ) { - fprintf(stderr, - "number of datasets per file must be >= 0 (%ld)\n", - ndsets); - GOTOERROR(FAIL); - } - - if (param.num_procs <= 0 ) { - fprintf(stderr, - "maximum number of process to use must be > 0 (%d)\n", - param.num_procs); - GOTOERROR(FAIL); - } - - /* Validate transfer buffer size & block size*/ - if(blk_size<=0) { - HDfprintf(stderr, - "Transfer block size (%zu) must be > 0\n", blk_size); - GOTOERROR(FAIL); - } - if(buf_size<=0) { - HDfprintf(stderr, - "Transfer buffer size (%zu) must be > 0\n", buf_size); - GOTOERROR(FAIL); - } - if ((buf_size % blk_size) != 0){ - HDfprintf(stderr, - "Transfer buffer size (%zu) must be a multiple of the " - "interleaved I/O block size (%zu)\n", - buf_size, blk_size); - GOTOERROR(FAIL); - } - if((snbytes%pio_mpi_nprocs_g)!=0) { - HDfprintf(stderr, - "Dataset size (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "number of processes (%d)\n", - (long long)snbytes, pio_mpi_nprocs_g); - GOTOERROR(FAIL); - } - - if (!param.dim2d){ - if(((snbytes/pio_mpi_nprocs_g)%buf_size)!=0) { - HDfprintf(stderr, - "Dataset size/process (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "trasfer buffer size (%zu)\n", - (long long)(snbytes/pio_mpi_nprocs_g), buf_size); - GOTOERROR(FAIL); - } - } - else { - if((snbytes%buf_size)!=0) { - HDfprintf(stderr, - "Dataset side size (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "trasfer buffer size (%zu)\n", - (long long)snbytes, buf_size); - GOTOERROR(FAIL); - } - } - - /* Allocate transfer buffer */ - if ((buffer = malloc(bsize)) == NULL){ - HDfprintf(stderr, "malloc for transfer buffer size (%zu) failed\n", - bsize); - GOTOERROR(FAIL); - } - - if (pio_debug_level >= 4) { - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - /* output all of the times for all iterations */ - if (myrank == 0) - fprintf(output, "Timer details:\n"); - } - - for (nf = 1; nf <= param.num_files; nf++) { - /* - * Write performance measurement - */ - /* Open file for write */ - char base_name[256]; - - sprintf(base_name, "#pio_tmp_%lu", nf); - pio_create_filename(iot, base_name, fname, sizeof(fname)); - if (pio_debug_level > 0) - HDfprintf(output, "rank %d: data filename=%s\n", - pio_mpi_rank_g, fname); - - /* Need barrier to make sure everyone starts at the same time */ - MPI_Barrier(pio_comm_g); - - set_time(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, PIO_CREATE | PIO_WRITE); - - VRFY((hrc == SUCCESS), "do_fopen failed"); - - set_time(res.timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTART); - hrc = do_write(&res, &fd, ¶m, ndsets, nbytes, buf_size, buffer); - hrc == SUCCESS; - set_time(res.timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTOP); - - VRFY((hrc == SUCCESS), "do_write failed"); - - /* Close file for write */ - hrc = do_fclose(iot, &fd); - - set_time(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - - if (!param.h5_write_only) { - /* - * Read performance measurement - */ - /* Need barrier to make sure everyone is done writing and has - * closed the file. Also to make sure everyone starts reading - * at the same time. - */ - MPI_Barrier(pio_comm_g); - - /* Open file for read */ - set_time(res.timers, HDF5_GROSS_READ_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, PIO_READ); - - VRFY((hrc == SUCCESS), "do_fopen failed"); - - set_time(res.timers, HDF5_FINE_READ_FIXED_DIMS, TSTART); - hrc = do_read(&res, &fd, ¶m, ndsets, nbytes, buf_size, buffer); - set_time(res.timers, HDF5_FINE_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_read failed"); - - /* Close file for read */ - hrc = do_fclose(iot, &fd); - - set_time(res.timers, HDF5_GROSS_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - } - - /* Need barrier to make sure everyone is done with the file */ - /* before it may be removed by do_cleanupfile */ - MPI_Barrier(pio_comm_g); - do_cleanupfile(iot, fname); - } - -done: - /* clean up */ - /* release HDF5 objects */ - - /* close any opened files */ - /* no remove(fname) because that should have happened normally. */ - switch (iot) { - case POSIXIO: - if (fd.posixfd != -1) - hrc = do_fclose(iot, &fd); - break; - case MPIO: - if (fd.mpifd != MPI_FILE_NULL) - hrc = do_fclose(iot, &fd); - break; - case PHDF5: - if (fd.h5fd != -1) - hrc = do_fclose(iot, &fd); - break; - } - - /* release generic resources */ - if(buffer) - free(buffer); - res.ret_code = ret_code; - return res; -} - -/* - * Function: pio_create_filename - * Purpose: Create a new filename to write to. Determine the correct - * suffix to append to the filename by the type of I/O we're - * doing. Also, place in the /tmp/{$USER,$LOGIN} directory if - * USER or LOGIN are specified in the environment. - * Return: Pointer to filename or NULL - * Programmer: Bill Wendling, 21. November 2001 - * Modifications: - */ - static char * -pio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size) -{ - const char *prefix, *suffix = ""; - char *ptr, last = '\0'; - size_t i, j; - - if (!base_name || !fullname || size < 1) - return NULL; - - HDmemset(fullname, 0, size); - - switch (iot) { - case POSIXIO: - suffix = ".posix"; - break; - case MPIO: - suffix = ".mpio"; - break; - case PHDF5: - suffix = ".h5"; - break; - } - - /* First use the environment variable and then try the constant */ - prefix = HDgetenv("HDF5_PARAPREFIX"); - -#ifdef HDF5_PARAPREFIX - if (!prefix) - prefix = HDF5_PARAPREFIX; -#endif /* HDF5_PARAPREFIX */ - - /* Prepend the prefix value to the base name */ - if (prefix && *prefix) { - /* If the prefix specifies the HDF5_PARAPREFIX directory, then - * default to using the "/tmp/$USER" or "/tmp/$LOGIN" - * directory instead. */ - register char *user, *login, *subdir; - - user = HDgetenv("USER"); - login = HDgetenv("LOGIN"); - subdir = (user ? user : login); - - if (subdir) { - for (i = 0; i < size-1 && prefix[i]; i++) - fullname[i] = prefix[i]; - - fullname[i++] = '/'; - - for (j = 0; i < size && subdir[j]; i++, j++) - fullname[i] = subdir[j]; - } - else { - /* We didn't append the prefix yet */ - HDstrncpy(fullname, prefix, size); - fullname[size - 1] = '\0'; - } - - if ((HDstrlen(fullname) + HDstrlen(base_name) + 1) < size) { - /* Append the base_name with a slash first. Multiple slashes are - * handled below. */ - h5_stat_t buf; - - if (HDstat(fullname, &buf) < 0) - /* The directory doesn't exist just yet */ - if (HDmkdir(fullname, (mode_t) 0755) < 0 && errno != EEXIST) { - /* We couldn't make the "/tmp/${USER,LOGIN}" subdirectory. - * Default to PREFIX's original prefix value. */ - HDstrcpy(fullname, prefix); - } - - HDstrcat(fullname, "/"); - HDstrcat(fullname, base_name); - } - else { - /* Buffer is too small */ - return NULL; - } - } - else if (HDstrlen(base_name) >= size) { - /* Buffer is too small */ - return NULL; - } - else { - HDstrcpy(fullname, base_name); - } - - /* Append a suffix */ - if (suffix) { - if (HDstrlen(fullname) + HDstrlen(suffix) >= size) - return NULL; - - HDstrcat(fullname, suffix); - } - - /* Remove any double slashes in the filename */ - for (ptr = fullname, i = j = 0; ptr && i < size; i++, ptr++) { - if (*ptr != '/' || last != '/') - fullname[j++] = *ptr; - - last = *ptr; - } - - return fullname; -} - -/* - * Function: do_write - * Purpose: Write the required amount of data to the file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ - static herr_t -do_write(results *res, file_descr *fd, parameters *parms, long ndsets, - off_t nbytes, size_t buf_size, void *buffer) -{ - int ret_code = SUCCESS; - int rc; /*routine return code */ - long ndset; - size_t blk_size; /* The block size to subdivide the xfer buffer into */ - off_t nbytes_xfer; /* Total number of bytes transferred so far */ - size_t nbytes_xfer_advance; /* Number of bytes transferred in a single I/O operation */ - size_t nbytes_toxfer; /* Number of bytes to transfer a particular time */ - char dname[64]; - off_t dset_offset=0; /*dataset offset in a file */ - off_t bytes_begin[2]; /*first elmt this process transfer */ - off_t bytes_count; /*number of elmts this process transfer */ - off_t snbytes=0; /*size of a side of the dataset square */ - unsigned char *buf_p; /* Current buffer pointer */ - - /* POSIX variables */ - off_t file_offset; /* File offset of the next transfer */ - off_t file_offset_advance; /* File offset advance after each I/O operation */ - off_t posix_file_offset; /* Base file offset of the next transfer */ - - /* MPI variables */ - MPI_Offset mpi_file_offset; /* Base file offset of the next transfer*/ - MPI_Offset mpi_offset; /* Offset in MPI file */ - MPI_Offset mpi_offset_advance; /* Offset advance after each I/O operation */ - MPI_Datatype mpi_file_type; /* MPI derived type for 1D file */ - MPI_Datatype mpi_blk_type; /* MPI derived type for 1D buffer */ - MPI_Datatype mpi_cont_type; /* MPI derived type for 2D contiguous file */ - MPI_Datatype mpi_partial_buffer_cont; /* MPI derived type for partial 2D contiguous buffer */ - MPI_Datatype mpi_inter_type; /* MPI derived type for 2D interleaved file */ - MPI_Datatype mpi_partial_buffer_inter; /* MPI derived type for partial 2D interleaved buffer */ - MPI_Datatype mpi_full_buffer; /* MPI derived type for 2D full buffer */ - MPI_Datatype mpi_full_chunk; /* MPI derived type for 2D full chunk */ - MPI_Datatype mpi_chunk_inter_type; /* MPI derived type for 2D chunk interleaved file */ - MPI_Datatype mpi_collective_type; /* Generic MPI derived type for 2D collective access */ - MPI_Status mpi_status; - int mrc; /* MPI return code */ - - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[2]; /*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 */ - hsize_t h5block[2]; /*dataspace selection */ - hsize_t h5stride[2]; - hsize_t h5count[2]; - hsize_t h5start[2]; - hssize_t h5offset[2]; /* Selection offset within dataspace */ - hid_t h5dcpl = -1; /* Dataset creation property list */ - hid_t h5dxpl = -1; /* Dataset transfer property list */ - - /* Get the parameters from the parameter block */ - blk_size=parms->blk_size; - - /* There are two kinds of transfer patterns, contiguous and interleaved. - * Let 0,1,2,...,n be data accessed by process 0,1,2,...,n - * where n is rank of the last process. - * In contiguous pattern, data are accessed as - * 000...111...222...nnn... - * In interleaved pattern, data are accessed as - * 012...n012...n... - * These are all in the scope of one dataset. - */ - - /* 1D dataspace */ - if (!parms->dim2d){ - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)(((double)nbytes*pio_mpi_rank_g)/pio_mpi_nprocs_g); - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = (off_t)(blk_size*pio_mpi_rank_g); - } /* end else */ - - /* Prepare buffer for verifying data */ - if (parms->verify) - memset(buffer,pio_mpi_rank_g+1,buf_size); - }/* end if */ - /* 2D dataspace */ - else { - /* nbytes is always the number of bytes per dataset (1D or 2D). If the - dataspace is 2D, snbytes is the size of a side of the dataset square. - */ - snbytes = (off_t)sqrt(nbytes); - - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)((double)snbytes*pio_mpi_rank_g / pio_mpi_nprocs_g); - bytes_begin[1] = 0; - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = 0; - - if(!parms->h5_use_chunks || parms->io_type==PHDF5) - bytes_begin[1] = (off_t)(blk_size*pio_mpi_rank_g); - else - bytes_begin[1] = (off_t)(blk_size*blk_size*pio_mpi_rank_g); - } /* end else */ - - /* Prepare buffer for verifying data */ - if (parms->verify) - memset(buffer,pio_mpi_rank_g+1,buf_size*blk_size); - } /* end else */ - - - /* Calculate the total number of bytes (bytes_count) to be - * transferred by this process. It may be different for different - * transfer pattern due to rounding to integral values. - */ - /* - * Calculate the beginning bytes of this process and the next. - * bytes_count is the difference between these two beginnings. - * This way, it eliminates any rounding errors. - * (This is tricky, don't mess with the formula, rounding errors - * can easily get introduced) */ - bytes_count = (off_t)(((double)nbytes*(pio_mpi_rank_g+1)) / pio_mpi_nprocs_g) - - (off_t)(((double)nbytes*pio_mpi_rank_g) / pio_mpi_nprocs_g); - - /* debug */ - if (pio_debug_level >= 4) { - HDprint_rank(output); - if (!parms->dim2d) { - HDfprintf(output, "Debug(do_write): " - "buf_size=%zu, bytes_begin=%" H5_PRINTF_LL_WIDTH "d, bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", - buf_size, (long long)bytes_begin[0], - (long long)bytes_count); - } else { - HDfprintf(output, "Debug(do_write): " - "linear buf_size=%zu, bytes_begin=(%" H5_PRINTF_LL_WIDTH "d,%" H5_PRINTF_LL_WIDTH "d), bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", - buf_size*blk_size, (long long)bytes_begin[0], - (long long)bytes_begin[1], (long long)bytes_count); - } - } - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - /* No extra setup */ - break; - - case MPIO: /* MPI-I/O setup */ - /* 1D dataspace */ - if (!parms->dim2d){ - /* Build block's derived type */ - mrc = MPI_Type_contiguous((int)blk_size, - MPI_BYTE, &mpi_blk_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Build file's derived type */ - mrc = MPI_Type_vector((int)(buf_size/blk_size), (int)1, - (int)pio_mpi_nprocs_g, mpi_blk_type, &mpi_file_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit file type */ - mrc = MPI_Type_commit( &mpi_file_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Commit buffer type */ - mrc = MPI_Type_commit( &mpi_blk_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - } /* end if */ - /* 2D dataspace */ - else { - /* Build partial buffer derived type for contiguous access */ - - mrc = MPI_Type_contiguous((int)buf_size, MPI_BYTE, - &mpi_partial_buffer_cont); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_cont); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build contiguous file's derived type */ - mrc = MPI_Type_vector((int)blk_size, (int)1, (int)(snbytes/buf_size), - mpi_partial_buffer_cont, &mpi_cont_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit contiguous file type */ - mrc = MPI_Type_commit(&mpi_cont_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build partial buffer derived type for interleaved access */ - mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, - &mpi_partial_buffer_inter); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_inter); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build interleaved file's derived type */ - mrc = MPI_Type_vector((int)buf_size, (int)1, (int)(snbytes/blk_size), - mpi_partial_buffer_inter, &mpi_inter_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit interleaved file type */ - mrc = MPI_Type_commit(&mpi_inter_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full buffer derived type */ - mrc = MPI_Type_contiguous((int)(blk_size*buf_size), MPI_BYTE, - &mpi_full_buffer); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full buffer derived type */ - mrc = MPI_Type_commit(&mpi_full_buffer); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full chunk derived type */ - mrc = MPI_Type_contiguous((int)(blk_size*blk_size), MPI_BYTE, - &mpi_full_chunk); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full chunk derived type */ - mrc = MPI_Type_commit(&mpi_full_chunk); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build chunk interleaved file's derived type */ - mrc = MPI_Type_vector((int)(buf_size/blk_size), (int)1, (int)(snbytes/blk_size), - mpi_full_chunk, &mpi_chunk_inter_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit chunk interleaved file type */ - mrc = MPI_Type_commit(&mpi_chunk_inter_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - } /* end else */ - break; - - case PHDF5: /* HDF5 setup */ - /* 1D dataspace */ - if (!parms->dim2d){ - if(nbytes>0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = nbytes; - h5dset_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved){ - /* Contiguous pattern */ - h5start[0] = bytes_begin[0]; - h5stride[0] = h5block[0] = blk_size; - h5count[0] = buf_size/blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = bytes_begin[0]; - h5stride[0] = blk_size*pio_mpi_nprocs_g; - h5block[0] = blk_size; - h5count[0] = buf_size/blk_size; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, - h5start, h5stride, h5count, h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if(buf_size>0) { - h5dims[0] = buf_size; - h5mem_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - if(nbytes>0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = snbytes; - h5dims[1] = snbytes; - h5dset_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved){ - /* Contiguous pattern */ - h5start[0] = bytes_begin[0]; - h5start[1] = bytes_begin[1]; - h5stride[0] = 1; - h5stride[1] = h5block[0] = h5block[1] = blk_size; - h5count[0] = 1; - h5count[1] = buf_size/blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = bytes_begin[0]; - h5start[1] = bytes_begin[1]; - h5stride[0] = blk_size; - h5stride[1] = blk_size*pio_mpi_nprocs_g; - h5block[0] = h5block[1] = blk_size; - h5count[0] = buf_size/blk_size; - h5count[1] = 1; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, - h5start, h5stride, h5count, h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if(buf_size>0) { - if (!parms->interleaved){ - h5dims[0] = blk_size; - h5dims[1] = buf_size; - }else{ - h5dims[0] = buf_size; - h5dims[1] = blk_size; - } - h5mem_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end else */ - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - fprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - /* Change to collective I/O, if asked */ - if(parms->collective) { - hrc = H5Pset_dxpl_mpio(h5dxpl, H5FD_MPIO_COLLECTIVE); - if (hrc < 0) { - fprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - break; - } /* end switch */ - - for (ndset = 1; ndset <= ndsets; ++ndset) { - - /* Calculate dataset offset within a file */ - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - case MPIO: - /* both posix and mpi io just need dataset offset in file*/ - dset_offset = (ndset - 1) * nbytes; - break; - - case PHDF5: - h5dcpl = H5Pcreate(H5P_DATASET_CREATE); - if (h5dcpl < 0) { - fprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - /* 1D dataspace */ - if (!parms->dim2d){ - /* Make the dataset chunked if asked */ - if(parms->h5_use_chunks) { - /* Set the chunk size to be the same as the buffer size */ - h5dims[0] = blk_size; - hrc = H5Pset_chunk(h5dcpl, 1, h5dims); - if (hrc < 0) { - fprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - }/* end if */ - else{ - /* 2D dataspace */ - if(parms->h5_use_chunks) { - /* Set the chunk size to be the same as the block size */ - h5dims[0] = blk_size; - h5dims[1] = blk_size; - hrc = H5Pset_chunk(h5dcpl, 2, h5dims); - if (hrc < 0) { - fprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - }/* end else */ - - sprintf(dname, "Dataset_%ld", ndset); - h5ds_id = H5DCREATE(fd->h5fd, dname, ELMT_H5_TYPE, - h5dset_space_id, h5dcpl); - - if (h5ds_id < 0) { - fprintf(stderr, "HDF5 Dataset Create failed\n"); - GOTOERROR(FAIL); - } - - hrc = H5Pclose(h5dcpl); - /* verifying the close of the dcpl */ - if (hrc < 0) { - fprintf(stderr, "HDF5 Property List Close failed\n"); - GOTOERROR(FAIL); - } - break; - } - - /* The task is to transfer bytes_count bytes, starting at - * bytes_begin position, using transfer buffer of buf_size bytes. - * If interleaved, select buf_size at a time, in round robin - * fashion, according to number of process. Otherwise, select - * all bytes_count in contiguous. - */ - nbytes_xfer = 0 ; - - /* 1D dataspace */ - if (!parms->dim2d){ - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset = dset_offset + bytes_begin[0]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0]); - } /* end if */ - else { - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset=dset_offset + bytes_begin[0]*snbytes+ - bytes_begin[1]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset=(MPI_Offset)(dset_offset + bytes_begin[0]*snbytes+ - bytes_begin[1]); - } /* end else */ - - /* Start "raw data" write timer */ - set_time(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTART); - - while (nbytes_xfer < bytes_count){ - /* Write */ - /* Calculate offset of write within a dataset/file */ - switch (parms->io_type) { - case POSIXIO: - /* 1D dataspace */ - if (!parms->dim2d){ - /* Contiguous pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + (off_t)nbytes_xfer; - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc==0), "POSIXSEEK"); - - /* check if all bytes are written */ - rc = ((ssize_t)buf_size == - POSIXWRITE(fd->posixfd, buffer, buf_size)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer+=buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p=(unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to write */ - while(nbytes_toxfer>0) { - /* Skip offset over blocks of other processes */ - file_offset = posix_file_offset + - (off_t)(nbytes_xfer*pio_mpi_nprocs_g); - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc==0), "POSIXSEEK"); - - /* check if all bytes are written */ - rc = ((ssize_t)blk_size == - POSIXWRITE(fd->posixfd, buf_p, blk_size)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance location in buffer */ - buf_p+=blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer+=blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer-=blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset=posix_file_offset+(off_t)(((nbytes_xfer/blk_size) - /snbytes)*(blk_size*snbytes)+((nbytes_xfer/blk_size)%snbytes)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute file offset */ - file_offset=posix_file_offset+(off_t)((((nbytes_xfer/buf_size) - *pio_mpi_nprocs_g)/snbytes)*(buf_size*snbytes) - +((nbytes_xfer/buf_size)*pio_mpi_nprocs_g)%snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset=posix_file_offset+(off_t)nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = 0; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute file offset */ - /* Before simplification */ - /* file_offset=posix_file_offset+(off_t)((nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))*(buf_size/blk_size - *snbytes/blk_size*(blk_size*blk_size))+((nbytes_xfer/(buf_size/blk_size)) - *pio_mpi_nprocs_g)%(snbytes/blk_size*(blk_size*blk_size))); */ - - file_offset=posix_file_offset+(off_t)(((nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes*blk_size))*(buf_size*snbytes)+((nbytes_xfer/(buf_size/blk_size)) - *pio_mpi_nprocs_g)%(snbytes*blk_size)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* file_offset_advance = (off_t)(snbytes/blk_size*(blk_size*blk_size)); */ - file_offset_advance = (off_t)(snbytes*blk_size); - } /* end else */ - } /* end else */ - - /* Common code for file access */ - - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size*blk_size; - - /* Loop over portions of the buffer to write */ - while(nbytes_toxfer>0){ - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc==0), "POSIXSEEK"); - - /* check if all bytes are written */ - rc = ((ssize_t)nbytes_xfer_advance == - POSIXWRITE(fd->posixfd, buf_p, nbytes_xfer_advance)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance location in buffer */ - buf_p+=nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer+=nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer-=nbytes_xfer_advance; - - /* Partially advance file offset */ - file_offset+=file_offset_advance; - } /* end while */ - - } /* end else */ - - break; - - case MPIO: - /* 1D dataspace */ - if (!parms->dim2d){ - /* Independent file access */ - if(!parms->collective) { - /* Contiguous pattern */ - if (!parms->interleaved){ - /* Compute offset in file */ - mpi_offset = mpi_file_offset + - nbytes_xfer; - - /* Perform independent write */ - mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buffer, - (int)(buf_size/blk_size), mpi_blk_type, - &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer+=buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p=(unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to write */ - while(nbytes_toxfer>0) { - /* Skip offset over blocks of other processes */ - mpi_offset = mpi_file_offset + - (nbytes_xfer*pio_mpi_nprocs_g); - - /* Perform independent write */ - mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buf_p, - (int)1, mpi_blk_type, &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance location in buffer */ - buf_p+=blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer+=blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer-=blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* Collective file access */ - else { - /* Contiguous access pattern */ - if (!parms->interleaved){ - /* Compute offset in file */ - mpi_offset = mpi_file_offset + - nbytes_xfer; - - /* Perform independent write */ - mrc = MPI_File_write_at_all(fd->mpifd, mpi_offset, buffer, - (int)(buf_size/blk_size), mpi_blk_type, &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer+=buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + - (nbytes_xfer*pio_mpi_nprocs_g); - - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, mpi_blk_type, - mpi_file_type, (char*)"native", h5_io_info_g); - VRFY((mrc==MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform write */ - mrc = MPI_File_write_at_all(fd->mpifd, 0, buffer, - (int)(buf_size/blk_size), mpi_blk_type, &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer+=buf_size; - } /* end else */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset=mpi_file_offset+((nbytes_xfer/blk_size)/snbytes)* - (blk_size*snbytes)+((nbytes_xfer/blk_size)%snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_cont_type; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset=mpi_file_offset+(((nbytes_xfer/buf_size)*pio_mpi_nprocs_g)/snbytes)* - (buf_size*snbytes)+((nbytes_xfer/buf_size)*pio_mpi_nprocs_g)%snbytes; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_inter_type; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset=mpi_file_offset+nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = 0; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_full_buffer; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute offset in file */ - /* Before simplification */ - /* mpi_offset=mpi_file_offset+(nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))* - (buf_size/blk_size*snbytes/blk_size*(blk_size*blk_size))+ - ((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes - /blk_size*(blk_size*blk_size)); */ - mpi_offset=mpi_file_offset+((nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes*blk_size))*(buf_size*snbytes) - +((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes*blk_size); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* mpi_offset_advance = (MPI_Offset)(snbytes/blk_size*(blk_size*blk_size)); */ - mpi_offset_advance = (MPI_Offset)(snbytes*blk_size); - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_chunk_inter_type; - } /* end else */ - } /* end else */ - - /* Common code for independent file access */ - if (!parms->collective) { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size * blk_size; - - /* Loop over portions of the buffer to write */ - while(nbytes_toxfer>0){ - /* Perform independent write */ - mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buf_p, - (int)nbytes_xfer_advance, MPI_BYTE, &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance location in buffer */ - buf_p+=nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer+=nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer-=nbytes_xfer_advance; - - /* Partially advance global offset in dataset */ - mpi_offset+=mpi_offset_advance; - } /* end while */ - } /* end if */ - - /* Common code for collective file access */ - else { - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, MPI_BYTE, - mpi_collective_type, (char *)"native", h5_io_info_g); - VRFY((mrc==MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform write */ - MPI_File_write_at_all(fd->mpifd, 0, buffer,(int)(buf_size*blk_size), - MPI_BYTE, &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer+=buf_size*blk_size; - } /* end else */ - - } /* end else */ - - break; - - case PHDF5: - /* 1D dataspace */ - if (!parms->dim2d){ - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved){ - /* Contiguous pattern */ - h5offset[0] = nbytes_xfer; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = (nbytes_xfer*pio_mpi_nprocs_g); - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc = H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, - h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dwrite"); - - /* Increment number of bytes transferred */ - nbytes_xfer += buf_size; - } /* end if */ - /* 2D dataspace */ - else { - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved){ - /* Contiguous pattern */ - h5offset[0] = (nbytes_xfer/(snbytes*blk_size))*blk_size; - h5offset[1] = (nbytes_xfer%(snbytes*blk_size))/blk_size; - - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = ((nbytes_xfer*pio_mpi_nprocs_g)/(snbytes*buf_size))*buf_size; - h5offset[1] = ((nbytes_xfer*pio_mpi_nprocs_g)%(snbytes*buf_size))/buf_size; - - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc = H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, - h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dwrite"); - - /* Increment number of bytes transferred */ - nbytes_xfer += buf_size*blk_size; - - } /* end else */ - - break; - } /* switch (parms->io_type) */ - } /* end while */ - - /* Stop "raw data" write timer */ - set_time(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTOP); - - /* Calculate write time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == PHDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - fprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = -1; - } /* end if */ - } /* end for */ - -done: - /* release MPI-I/O objects */ - if (parms->io_type == MPIO) { - /* 1D dataspace */ - if (!parms->dim2d){ - /* Free file type */ - mrc = MPI_Type_free( &mpi_file_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free buffer type */ - mrc = MPI_Type_free( &mpi_blk_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end if */ - /* 2D dataspace */ - else { - /* Free partial buffer type for contiguous access */ - mrc = MPI_Type_free( &mpi_partial_buffer_cont ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free contiguous file type */ - mrc = MPI_Type_free( &mpi_cont_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free partial buffer type for interleaved access */ - mrc = MPI_Type_free( &mpi_partial_buffer_inter ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free interleaved file type */ - mrc = MPI_Type_free( &mpi_inter_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full buffer type */ - mrc = MPI_Type_free(&mpi_full_buffer); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full chunk type */ - mrc = MPI_Type_free(&mpi_full_chunk); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free chunk interleaved file type */ - mrc = MPI_Type_free(&mpi_chunk_inter_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end else */ - } /* end if */ - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0){ - fprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } else { - h5dset_space_id = -1; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - fprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } else { - h5mem_space_id = -1; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - fprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } else { - h5dxpl = -1; - } - } - - return ret_code; -} - -/* - * Function: do_read - * Purpose: read the required amount of data from the file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng 2001/12/13 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ - static herr_t -do_read(results *res, file_descr *fd, parameters *parms, long ndsets, - off_t nbytes, size_t buf_size, void *buffer /*out*/) -{ - int ret_code = SUCCESS; - int rc; /*routine return code */ - long ndset; - size_t blk_size; /* The block size to subdivide the xfer buffer into */ - size_t bsize; /* Size of the actual buffer */ - off_t nbytes_xfer; /* Total number of bytes transferred so far */ - size_t nbytes_xfer_advance; /* Number of bytes transferred in a single I/O operation */ - size_t nbytes_toxfer; /* Number of bytes to transfer a particular time */ - char dname[64]; - off_t dset_offset=0; /*dataset offset in a file */ - off_t bytes_begin[2]; /*first elmt this process transfer */ - off_t bytes_count; /*number of elmts this process transfer */ - off_t snbytes=0; /*size of a side of the dataset square */ - unsigned char *buf_p; /* Current buffer pointer */ - - /* POSIX variables */ - off_t file_offset; /* File offset of the next transfer */ - off_t file_offset_advance; /* File offset advance after each I/O operation */ - off_t posix_file_offset; /* Base file offset of the next transfer */ - - /* MPI variables */ - MPI_Offset mpi_file_offset;/* Base file offset of the next transfer*/ - MPI_Offset mpi_offset; /* Offset in MPI file */ - MPI_Offset mpi_offset_advance; /* Offset advance after each I/O operation */ - MPI_Datatype mpi_file_type; /* MPI derived type for 1D file */ - MPI_Datatype mpi_blk_type; /* MPI derived type for 1D buffer */ - MPI_Datatype mpi_cont_type; /* MPI derived type for 2D contiguous file */ - MPI_Datatype mpi_partial_buffer_cont; /* MPI derived type for partial 2D contiguous buffer */ - MPI_Datatype mpi_inter_type; /* MPI derived type for 2D interleaved file */ - MPI_Datatype mpi_partial_buffer_inter; /* MPI derived type for partial 2D interleaved buffer */ - MPI_Datatype mpi_full_buffer; /* MPI derived type for 2D full buffer */ - MPI_Datatype mpi_full_chunk; /* MPI derived type for 2D full chunk */ - MPI_Datatype mpi_chunk_inter_type; /* MPI derived type for 2D chunk interleaved file */ - MPI_Datatype mpi_collective_type; /* Generic MPI derived type for 2D collective access */ - MPI_Status mpi_status; - int mrc; /* MPI return code */ - - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[2]; /*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 */ - hsize_t h5block[2]; /*dataspace selection */ - hsize_t h5stride[2]; - hsize_t h5count[2]; - hsize_t h5start[2]; - hssize_t h5offset[2]; /* Selection offset within dataspace */ - hid_t h5dxpl = -1; /* Dataset transfer property list */ - - /* Get the parameters from the parameter block */ - blk_size=parms->blk_size; - - /* There are two kinds of transfer patterns, contiguous and interleaved. - * Let 0,1,2,...,n be data accessed by process 0,1,2,...,n - * where n is rank of the last process. - * In contiguous pattern, data are accessed as - * 000...111...222...nnn... - * In interleaved pattern, data are accessed as - * 012...n012...n... - * These are all in the scope of one dataset. - */ - - /* 1D dataspace */ - if (!parms->dim2d){ - bsize = buf_size; - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)(((double)nbytes*pio_mpi_rank_g)/pio_mpi_nprocs_g); - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = (off_t)(blk_size*pio_mpi_rank_g); - } /* end else */ - }/* end if */ - /* 2D dataspace */ - else { - /* nbytes is always the number of bytes per dataset (1D or 2D). If the - dataspace is 2D, snbytes is the size of a side of the 'dataset square'. - */ - snbytes = (off_t)sqrt(nbytes); - - bsize = buf_size * blk_size; - - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)((double)snbytes*pio_mpi_rank_g / pio_mpi_nprocs_g); - bytes_begin[1] = 0; - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = 0; - - if (!parms->h5_use_chunks || parms->io_type==PHDF5) - bytes_begin[1] = (off_t)(blk_size*pio_mpi_rank_g); - else - bytes_begin[1] = (off_t)(blk_size*blk_size*pio_mpi_rank_g); - } /* end else */ - } /* end else */ - - /* Calculate the total number of bytes (bytes_count) to be - * transferred by this process. It may be different for different - * transfer pattern due to rounding to integral values. - */ - /* - * Calculate the beginning bytes of this process and the next. - * bytes_count is the difference between these two beginnings. - * This way, it eliminates any rounding errors. - * (This is tricky, don't mess with the formula, rounding errors - * can easily get introduced) */ - bytes_count = (off_t)(((double)nbytes*(pio_mpi_rank_g+1)) / pio_mpi_nprocs_g) - - (off_t)(((double)nbytes*pio_mpi_rank_g) / pio_mpi_nprocs_g); - - /* debug */ - if (pio_debug_level >= 4) { - HDprint_rank(output); - if (!parms->dim2d) { - HDfprintf(output, "Debug(do_write): " - "buf_size=%zu, bytes_begin=%" H5_PRINTF_LL_WIDTH "d, bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", - buf_size, (long long)bytes_begin[0], - (long long)bytes_count); - } else { - HDfprintf(output, "Debug(do_write): " - "linear buf_size=%zu, bytes_begin=(%" H5_PRINTF_LL_WIDTH "d,%" H5_PRINTF_LL_WIDTH "d), bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", - buf_size*blk_size, (long long)bytes_begin[0], - (long long)bytes_begin[1], (long long)bytes_count); - } - } - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - /* No extra setup */ - break; - - case MPIO: /* MPI-I/O setup */ - /* 1D dataspace */ - if (!parms->dim2d){ - /* Build block's derived type */ - mrc = MPI_Type_contiguous((int)blk_size, - MPI_BYTE, &mpi_blk_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Build file's derived type */ - mrc = MPI_Type_vector((int)(buf_size/blk_size), (int)1, - (int)pio_mpi_nprocs_g, mpi_blk_type, &mpi_file_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit file type */ - mrc = MPI_Type_commit( &mpi_file_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Commit buffer type */ - mrc = MPI_Type_commit( &mpi_blk_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - } /* end if */ - /* 2D dataspace */ - else { - /* Build partial buffer derived type for contiguous access */ - mrc = MPI_Type_contiguous((int)buf_size, MPI_BYTE, - &mpi_partial_buffer_cont); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_cont); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build contiguous file's derived type */ - mrc = MPI_Type_vector((int)blk_size, (int)1, (int)(snbytes/buf_size), - mpi_partial_buffer_cont, &mpi_cont_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit contiguous file type */ - mrc = MPI_Type_commit(&mpi_cont_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build partial buffer derived type for interleaved access */ - mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, - &mpi_partial_buffer_inter); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_inter); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build interleaved file's derived type */ - mrc = MPI_Type_vector((int)buf_size, (int)1, (int)(snbytes/blk_size), - mpi_partial_buffer_inter, &mpi_inter_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit interleaved file type */ - mrc = MPI_Type_commit(&mpi_inter_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full buffer derived type */ - mrc = MPI_Type_contiguous((int)(blk_size*buf_size), MPI_BYTE, - &mpi_full_buffer); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full buffer derived type */ - mrc = MPI_Type_commit(&mpi_full_buffer); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full chunk derived type */ - mrc = MPI_Type_contiguous((int)(blk_size*blk_size), MPI_BYTE, - &mpi_full_chunk); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full chunk derived type */ - mrc = MPI_Type_commit(&mpi_full_chunk); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build chunk interleaved file's derived type */ - mrc = MPI_Type_vector((int)(buf_size/blk_size), (int)1, (int)(snbytes/blk_size), - mpi_full_chunk, &mpi_chunk_inter_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit chunk interleaved file type */ - mrc = MPI_Type_commit(&mpi_chunk_inter_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - } /* end else */ - break; - - case PHDF5: /* HDF5 setup */ - /* 1D dataspace */ - if (!parms->dim2d){ - if(nbytes>0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = nbytes; - h5dset_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved){ - /* Contiguous pattern */ - h5start[0] = bytes_begin[0]; - h5stride[0] = h5block[0] = blk_size; - h5count[0] = buf_size/blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = bytes_begin[0]; - h5stride[0] = blk_size*pio_mpi_nprocs_g; - h5block[0] = blk_size; - h5count[0] = buf_size/blk_size; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, - h5start, h5stride, h5count, h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if(buf_size>0) { - h5dims[0] = buf_size; - h5mem_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - if(nbytes>0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = snbytes; - h5dims[1] = snbytes; - h5dset_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved){ - /* Contiguous pattern */ - h5start[0] = bytes_begin[0]; - h5start[1] = bytes_begin[1]; - h5stride[0] = 1; - h5stride[1] = h5block[0] = h5block[1] = blk_size; - h5count[0] = 1; - h5count[1] = buf_size/blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = bytes_begin[0]; - h5start[1] = bytes_begin[1]; - h5stride[0] = blk_size; - h5stride[1] = blk_size*pio_mpi_nprocs_g; - h5block[0] = h5block[1] = blk_size; - h5count[0] = buf_size/blk_size; - h5count[1] = 1; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, - h5start, h5stride, h5count, h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if(buf_size>0) { - if (!parms->interleaved){ - h5dims[0] = blk_size; - h5dims[1] = buf_size; - }else{ - h5dims[0] = buf_size; - h5dims[1] = blk_size; - } - h5mem_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end else */ - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - fprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - /* Change to collective I/O, if asked */ - if(parms->collective) { - hrc = H5Pset_dxpl_mpio(h5dxpl, H5FD_MPIO_COLLECTIVE); - if (hrc < 0) { - fprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - break; - } /* end switch */ - - for (ndset = 1; ndset <= ndsets; ++ndset) { - - /* Calculate dataset offset within a file */ - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - case MPIO: - /* both posix and mpi io just need dataset offset in file*/ - dset_offset = (ndset - 1) * nbytes; - break; - - case PHDF5: - sprintf(dname, "Dataset_%ld", ndset); - h5ds_id = H5DOPEN(fd->h5fd, dname); - if (h5ds_id < 0) { - fprintf(stderr, "HDF5 Dataset open failed\n"); - GOTOERROR(FAIL); - } - - break; - } - - /* The task is to transfer bytes_count bytes, starting at - * bytes_begin position, using transfer buffer of buf_size bytes. - * If interleaved, select buf_size at a time, in round robin - * fashion, according to number of process. Otherwise, select - * all bytes_count in contiguous. - */ - nbytes_xfer = 0 ; - - /* 1D dataspace */ - if (!parms->dim2d){ - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset = dset_offset + bytes_begin[0]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0]); - } /* end if */ - else { - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset=dset_offset + bytes_begin[0]*snbytes+ - bytes_begin[1]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset=(MPI_Offset)(dset_offset + bytes_begin[0]*snbytes+ - bytes_begin[1]); - } /* end else */ - - /* Start "raw data" read timer */ - set_time(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTART); - - while (nbytes_xfer < bytes_count){ - /* Read */ - /* Calculate offset of read within a dataset/file */ - switch (parms->io_type) { - case POSIXIO: - /* 1D dataspace */ - if (!parms->dim2d){ - /* Contiguous pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + (off_t)nbytes_xfer; - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc==0), "POSIXSEEK"); - - /* check if all bytes are read */ - rc = ((ssize_t)buf_size == - POSIXREAD(fd->posixfd, buffer, buf_size)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance global offset in dataset */ - nbytes_xfer+=buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p=(unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to read */ - while(nbytes_toxfer>0) { - /* Skip offset over blocks of other processes */ - file_offset = posix_file_offset + - (off_t)(nbytes_xfer*pio_mpi_nprocs_g); - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc==0), "POSIXSEEK"); - - /* check if all bytes are read */ - rc = ((ssize_t)blk_size == - POSIXREAD(fd->posixfd, buf_p, blk_size)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance location in buffer */ - buf_p+=blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer+=blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer-=blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset=posix_file_offset+(off_t)(((nbytes_xfer/blk_size) - /snbytes)*(blk_size*snbytes)+((nbytes_xfer/blk_size)%snbytes)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute file offset */ - file_offset=posix_file_offset+(off_t)((((nbytes_xfer/buf_size) - *pio_mpi_nprocs_g)/snbytes)*(buf_size*snbytes) - +((nbytes_xfer/buf_size)*pio_mpi_nprocs_g)%snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset=posix_file_offset+(off_t)nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = 0; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute file offset */ - /* Before simplification */ - /* file_offset=posix_file_offset+(off_t)((nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))*(buf_size/blk_size - *snbytes/blk_size*(blk_size*blk_size))+((nbytes_xfer/(buf_size/blk_size)) - *pio_mpi_nprocs_g)%(snbytes/blk_size*(blk_size*blk_size))); */ - - file_offset=posix_file_offset+(off_t)(((nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes*blk_size))*(buf_size*snbytes)+((nbytes_xfer/(buf_size/blk_size)) - *pio_mpi_nprocs_g)%(snbytes*blk_size)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* file_offset_advance = (off_t)(snbytes/blk_size*(blk_size*blk_size)); */ - file_offset_advance = (off_t)(snbytes*blk_size); - } /* end else */ - } /* end else */ - - /* Common code for file access */ - - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size*blk_size; - - /* Loop over portions of the buffer to read */ - while(nbytes_toxfer>0){ - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc==0), "POSIXSEEK"); - - /* check if all bytes are read */ - rc = ((ssize_t)nbytes_xfer_advance == - POSIXREAD(fd->posixfd, buf_p, nbytes_xfer_advance)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance location in buffer */ - buf_p+=nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer+=nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer-=nbytes_xfer_advance; - - /* Partially advance file offset */ - file_offset+=file_offset_advance; - } /* end while */ - - } /* end else */ - break; - - case MPIO: - /* 1D dataspace */ - if (!parms->dim2d){ - /* Independent file access */ - if(!parms->collective) { - /* Contiguous pattern */ - if (!parms->interleaved){ - /* Compute offset in file */ - mpi_offset = mpi_file_offset + - nbytes_xfer; - - /* Perform independent read */ - mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buffer, - (int)(buf_size/blk_size), mpi_blk_type, - &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer+=buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p=(unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to read */ - while(nbytes_toxfer>0) { - /* Skip offset over blocks of other processes */ - mpi_offset = mpi_file_offset + - (nbytes_xfer*pio_mpi_nprocs_g); - - /* Perform independent read */ - mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buf_p, - (int)1, mpi_blk_type, &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_READ"); - - /* Advance location in buffer */ - buf_p+=blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer+=blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer-=blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* Collective file access */ - else { - /* Contiguous access pattern */ - if (!parms->interleaved){ - /* Compute offset in file */ - mpi_offset = mpi_file_offset + - nbytes_xfer; - - /* Perform collective read */ - mrc = MPI_File_read_at_all(fd->mpifd, mpi_offset, buffer, - (int)(buf_size/blk_size), mpi_blk_type, &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer+=buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + - (nbytes_xfer*pio_mpi_nprocs_g); - - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, mpi_blk_type, - mpi_file_type, (char*)"native", h5_io_info_g); - VRFY((mrc==MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform collective read */ - mrc = MPI_File_read_at_all(fd->mpifd, 0, buffer, - (int)(buf_size/blk_size), mpi_blk_type, &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer+=buf_size; - } /* end else */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset=mpi_file_offset+((nbytes_xfer/blk_size)/snbytes)* - (blk_size*snbytes)+((nbytes_xfer/blk_size)%snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_cont_type; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset=mpi_file_offset+(((nbytes_xfer/buf_size)*pio_mpi_nprocs_g)/snbytes)* - (buf_size*snbytes)+((nbytes_xfer/buf_size)*pio_mpi_nprocs_g)%snbytes; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_inter_type; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset=mpi_file_offset+nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = 0; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_full_buffer; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute offset in file */ - /* Before simplification */ - /* mpi_offset=mpi_file_offset+(nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))* - (buf_size/blk_size*snbytes/blk_size*(blk_size*blk_size))+ - ((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes - /blk_size*(blk_size*blk_size)); */ - mpi_offset=mpi_file_offset+((nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes*blk_size))*(buf_size*snbytes) - +((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes*blk_size); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* mpi_offset_advance = (MPI_Offset)(snbytes/blk_size*(blk_size*blk_size)); */ - mpi_offset_advance = (MPI_Offset)(snbytes*blk_size); - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_chunk_inter_type; - } /* end else */ - } /* end else */ - - /* Common code for independent file access */ - if (!parms->collective) { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size * blk_size; - - /* Loop over portions of the buffer to read */ - while(nbytes_toxfer>0){ - /* Perform independent read */ - mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buf_p, - (int)nbytes_xfer_advance, MPI_BYTE, &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_READ"); - - /* Advance location in buffer */ - buf_p+=nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer+=nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer-=nbytes_xfer_advance; - - /* Partially advance global offset in dataset */ - mpi_offset+=mpi_offset_advance; - } /* end while */ - } /* end if */ - - /* Common code for collective file access */ - else { - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, MPI_BYTE, - mpi_collective_type, (char *)"native", h5_io_info_g); - VRFY((mrc==MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform read */ - MPI_File_read_at_all(fd->mpifd, 0, buffer,(int)(buf_size*blk_size), - MPI_BYTE, &mpi_status); - VRFY((mrc==MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer+=buf_size*blk_size; - } /* end else */ - - } /* end else */ - break; - - case PHDF5: - /* 1D dataspace */ - if (!parms->dim2d){ - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved){ - /* Contiguous pattern */ - h5offset[0] = nbytes_xfer; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = (nbytes_xfer*pio_mpi_nprocs_g); - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Read the buffer in */ - hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, - h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dread"); - - /* Increment number of bytes transferred */ - nbytes_xfer += buf_size; - } /* end if */ - /* 2D dataspace */ - else { - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved){ - /* Contiguous pattern */ - h5offset[0] = (nbytes_xfer/(snbytes*blk_size))*blk_size; - h5offset[1] = (nbytes_xfer%(snbytes*blk_size))/blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = ((nbytes_xfer*pio_mpi_nprocs_g)/(snbytes*buf_size))*buf_size; - h5offset[1] = ((nbytes_xfer*pio_mpi_nprocs_g)%(snbytes*buf_size))/buf_size; - - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, - h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dread"); - - /* Increment number of bytes transferred */ - nbytes_xfer += buf_size*blk_size; - - } /* end else */ - break; - } /* switch (parms->io_type) */ - - /* Verify raw data, if asked */ - if (parms->verify) { - /* Verify data read */ - unsigned char *ucharptr = (unsigned char *)buffer; - size_t i; - int nerror=0; - - for (i = 0; i < bsize; ++i){ - if (*ucharptr++ != pio_mpi_rank_g+1) { - if (++nerror < 20){ - /* report at most 20 errors */ - HDprint_rank(output); - HDfprintf(output, "read data error, expected (%d), " - "got (%d)\n", - pio_mpi_rank_g+1, - (int)*(ucharptr-1)); - } /* end if */ - } /* end if */ - } /* end for */ - if (nerror >= 20) { - HDprint_rank(output); - HDfprintf(output, "..."); - HDfprintf(output, "total read data errors=%d\n", - nerror); - } /* end if */ - } /* if (parms->verify) */ - - } /* end while */ - - /* Stop "raw data" read timer */ - set_time(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTOP); - - /* Calculate read time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == PHDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - fprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = -1; - } /* end if */ - } /* end for */ - -done: - /* release MPI-I/O objects */ - if (parms->io_type == MPIO) { - /* 1D dataspace */ - if (!parms->dim2d){ - /* Free file type */ - mrc = MPI_Type_free( &mpi_file_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free buffer type */ - mrc = MPI_Type_free( &mpi_blk_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end if */ - /* 2D dataspace */ - else { - /* Free partial buffer type for contiguous access */ - mrc = MPI_Type_free( &mpi_partial_buffer_cont ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free contiguous file type */ - mrc = MPI_Type_free( &mpi_cont_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free partial buffer type for interleaved access */ - mrc = MPI_Type_free( &mpi_partial_buffer_inter ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free interleaved file type */ - mrc = MPI_Type_free( &mpi_inter_type ); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full buffer type */ - mrc = MPI_Type_free(&mpi_full_buffer); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full chunk type */ - mrc = MPI_Type_free(&mpi_full_chunk); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free chunk interleaved file type */ - mrc = MPI_Type_free(&mpi_chunk_inter_type); - VRFY((mrc==MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end else */ - } /* end if */ - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0){ - fprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } else { - h5dset_space_id = -1; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - fprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } else { - h5mem_space_id = -1; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - fprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } else { - h5dxpl = -1; - } - } - - return ret_code; -} - -/* - * Function: do_fopen - * Purpose: Open the specified file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - */ - static herr_t -do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags) -{ - int ret_code = SUCCESS, mrc; - hid_t acc_tpl = -1; /* file access templates */ - - switch (param->io_type) { - case POSIXIO: - if (flags & (PIO_CREATE | PIO_WRITE)) - fd->posixfd = POSIXCREATE(fname); - else - fd->posixfd = POSIXOPEN(fname, O_RDONLY); - - if (fd->posixfd < 0 ) { - fprintf(stderr, "POSIX File Open failed(%s)\n", fname); - GOTOERROR(FAIL); - } - - - /* The perils of POSIX I/O in a parallel environment. The problem is: - * - * - Process n opens a file with truncation and then starts - * writing to the file. - * - Process m also opens the file with truncation, but after - * process n has already started to write to the file. Thus, - * all of the stuff process n wrote is now lost. - */ - MPI_Barrier(pio_comm_g); - - break; - - case MPIO: - if (flags & (PIO_CREATE | PIO_WRITE)) { - MPI_File_delete(fname, h5_io_info_g); - mrc = MPI_File_open(pio_comm_g, fname, MPI_MODE_CREATE | MPI_MODE_RDWR, - h5_io_info_g, &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, (MPI_Offset)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, h5_io_info_g, &fd->mpifd); - if (mrc != MPI_SUCCESS) { - fprintf(stderr, "MPI File Open failed(%s)\n", fname); - GOTOERROR(FAIL); - } - } - - break; - - case PHDF5: - if ((acc_tpl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { - fprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - /* Set the file driver to the MPI-IO driver */ - if (H5Pset_fapl_mpio(acc_tpl, pio_comm_g, h5_io_info_g) < 0) { - fprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } - - /* Set the alignment of objects in HDF5 file */ - if (H5Pset_alignment(acc_tpl, param->h5_thresh, param->h5_align) < 0) { - fprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } - - /* create the parallel file */ - if (flags & (PIO_CREATE | PIO_WRITE)) - fd->h5fd = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl); - else - fd->h5fd = H5Fopen(fname, H5F_ACC_RDONLY, acc_tpl); - if (fd->h5fd < 0) { - fprintf(stderr, "HDF5 File Create failed(%s)\n", fname); - GOTOERROR(FAIL); - } - - /* verifying the close of the acc_tpl */ - if (H5Pclose(acc_tpl) < 0) { - fprintf(stderr, "HDF5 Property List Close failed\n"); - GOTOERROR(FAIL); - } - - break; - } - -done: - return ret_code; -} - -/* - * Function: do_fclose - * Purpose: Close the specified file descriptor. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - */ - static herr_t -do_fclose(iotype iot, file_descr *fd /*out*/) -{ - herr_t ret_code = SUCCESS, hrc; - int mrc = 0, rc = 0; - - switch (iot) { - case POSIXIO: - rc = POSIXCLOSE(fd->posixfd); - - if (rc != 0){ - fprintf(stderr, "POSIX File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->posixfd = -1; - break; - - case MPIO: - mrc = MPI_File_close(&fd->mpifd); - - if (mrc != MPI_SUCCESS){ - fprintf(stderr, "MPI File close failed\n"); - GOTOERROR(FAIL); - } - - fd->mpifd = MPI_FILE_NULL; - break; - - case PHDF5: - hrc = H5Fclose(fd->h5fd); - - if (hrc < 0) { - fprintf(stderr, "HDF5 File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->h5fd = -1; - break; - } - -done: - return ret_code; -} - - -/* - * Function: do_fclose - * Purpose: Cleanup temporary file unless HDF5_NOCLEANUP is set. - * Only Proc 0 of the PIO communicator will do the cleanup. - * Other processes just return. - * Return: void - * Programmer: Albert Cheng 2001/12/12 - * Modifications: - */ - static void -do_cleanupfile(iotype iot, char *fname) -{ - if (pio_mpi_rank_g != 0) - return; - - if (clean_file_g == -1) - clean_file_g = (getenv("HDF5_NOCLEANUP")==NULL) ? 1 : 0; - - if (clean_file_g){ - switch (iot){ - case POSIXIO: - remove(fname); - break; - case MPIO: - case PHDF5: - MPI_File_delete(fname, h5_io_info_g); - break; - } - } -} - -#ifdef TIME_MPI -/* instrument the MPI_File_wrirte_xxx and read_xxx calls to measure - * pure time spent in MPI_File code. - */ -int MPI_File_read_at(MPI_File fh, MPI_Offset offset, void *buf, - int count, MPI_Datatype datatype, MPI_Status *status) -{ - int err; - set_time(timer_g, HDF5_MPI_READ, TSTART); - err=PMPI_File_read_at(fh, offset, buf, count, datatype, status); - set_time(timer_g, HDF5_MPI_READ, TSTOP); - return err; -} - - -int MPI_File_read_at_all(MPI_File fh, MPI_Offset offset, void *buf, - int count, MPI_Datatype datatype, MPI_Status *status) -{ - int err; - set_time(timer_g, HDF5_MPI_READ, TSTART); - err=PMPI_File_read_at_all(fh, offset, buf, count, datatype, status); - set_time(timer_g, HDF5_MPI_READ, TSTOP); - return err; -} - -int MPI_File_write_at(MPI_File fh, MPI_Offset offset, void *buf, - int count, MPI_Datatype datatype, MPI_Status *status) -{ - int err; - set_time(timer_g, HDF5_MPI_WRITE, TSTART); - err=PMPI_File_write_at(fh, offset, buf, count, datatype, status); - set_time(timer_g, HDF5_MPI_WRITE, TSTOP); - return err; -} - -int MPI_File_write_at_all(MPI_File fh, MPI_Offset offset, void *buf, - int count, MPI_Datatype datatype, MPI_Status *status) -{ - int err; - set_time(timer_g, HDF5_MPI_WRITE, TSTART); - err=PMPI_File_write_at_all(fh, offset, buf, count, datatype, status); - set_time(timer_g, HDF5_MPI_WRITE, TSTOP); - return err; -} - -#endif /* TIME_MPI */ -#endif /* H5_HAVE_PARALLEL */ - - - - - diff --git a/tools/perform/pio_perf.c b/tools/perform/pio_perf.c deleted file mode 100644 index c1bfadb..0000000 --- a/tools/perform/pio_perf.c +++ /dev/null @@ -1,1694 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Parallel HDF5 Performance Testing Code - * -------------------------------------- - * - * Portable code to test performance on the different platforms we support. - * This is what the report should look like: - * - * nprocs = Max#Procs - * IO API = POSIXIO - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * IO API = MPIO - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * IO API = PHDF5 - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * nprocs = Max#Procs / 2 - * - * . . . - * - */ - -/* system header files */ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> - -#include "hdf5.h" - -#ifdef H5_HAVE_PARALLEL - -/* library header files */ -#include <mpi.h> - -/* our header files */ -#include "pio_perf.h" - -/* useful macros */ -#define TAB_SPACE 4 - -#define ONE_KB 1024 -#define ONE_MB (ONE_KB * ONE_KB) -#define ONE_GB (ONE_MB * ONE_KB) - -#define PIO_POSIX 0x1 -#define PIO_MPI 0x2 -#define PIO_HDF5 0x4 - -/* 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))) - -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE (!TRUE) -#endif /* FALSE */ - -/* global variables */ -FILE *output; /* output file */ -int comm_world_rank_g; /* my rank in MPI_COMM_RANK */ -int comm_world_nprocs_g;/* num. of processes of MPI_COMM_WORLD */ -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 */ -int pio_debug_level = 0;/* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Maximal & then some - */ - -/* local variables */ -static const char *progname = "h5perf"; - -/* - * Command-line options: The user can specify short or long-named - * parameters. The long-named ones can be partially spelled. When - * adding more, make sure that they don't clash with each other. - */ -#if 1 -static const char *s_opts = "a:A:B:cCd:D:e:F:ghi:Imno:p:P:stT:wx:X:"; -#else -static const char *s_opts = "a:A:bB:cCd:D:e:F:ghi:Imno:p:P:stT:wx:X:"; -#endif /* 1 */ -static struct long_options l_opts[] = { - { "align", require_arg, 'a' }, - { "alig", require_arg, 'a' }, - { "ali", require_arg, 'a' }, - { "al", require_arg, 'a' }, - { "api", require_arg, 'A' }, - { "ap", require_arg, 'A' }, -#if 0 - /* a sighting of the elusive binary option */ - { "binary", no_arg, 'b' }, - { "binar", no_arg, 'b' }, - { "bina", no_arg, 'b' }, - { "bin", no_arg, 'b' }, - { "bi", no_arg, 'b' }, -#endif /* 0 */ - { "block-size", require_arg, 'B' }, - { "block-siz", require_arg, 'B' }, - { "block-si", require_arg, 'B' }, - { "block-s", require_arg, 'B' }, - { "block-", require_arg, 'B' }, - { "block", require_arg, 'B' }, - { "bloc", require_arg, 'B' }, - { "blo", require_arg, 'B' }, - { "bl", require_arg, 'B' }, - { "chunk", no_arg, 'c' }, - { "chun", no_arg, 'c' }, - { "chu", no_arg, 'c' }, - { "ch", no_arg, 'c' }, - { "collective", no_arg, 'C' }, - { "collectiv", no_arg, 'C' }, - { "collecti", no_arg, 'C' }, - { "collect", no_arg, 'C' }, - { "collec", no_arg, 'C' }, - { "colle", no_arg, 'C' }, - { "coll", no_arg, 'C' }, - { "col", no_arg, 'C' }, - { "co", no_arg, 'C' }, - { "debug", require_arg, 'D' }, - { "debu", require_arg, 'D' }, - { "deb", require_arg, 'D' }, - { "de", require_arg, 'D' }, - { "geometry", no_arg, 'g' }, - { "geometr", no_arg, 'g' }, - { "geomet", no_arg, 'g' }, - { "geome", no_arg, 'g' }, - { "geom", no_arg, 'g' }, - { "geo", no_arg, 'g' }, - { "ge", no_arg, 'g' }, - { "help", no_arg, 'h' }, - { "hel", no_arg, 'h' }, - { "he", no_arg, 'h' }, - { "interleaved", require_arg, 'I' }, - { "interleave", require_arg, 'I' }, - { "interleav", require_arg, 'I' }, - { "interlea", require_arg, 'I' }, - { "interle", require_arg, 'I' }, - { "interl", require_arg, 'I' }, - { "inter", require_arg, 'I' }, - { "inte", require_arg, 'I' }, - { "int", require_arg, 'I' }, - { "in", require_arg, 'I' }, - { "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' }, - { "num-bytes", require_arg, 'e' }, - { "num-byte", require_arg, 'e' }, - { "num-byt", require_arg, 'e' }, - { "num-by", require_arg, 'e' }, - { "num-b", require_arg, 'e' }, - { "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' }, - { "threshold", require_arg, 'T' }, - { "threshol", require_arg, 'T' }, - { "thresho", require_arg, 'T' }, - { "thresh", require_arg, 'T' }, - { "thres", require_arg, 'T' }, - { "thre", require_arg, 'T' }, - { "thr", require_arg, 'T' }, - { "th", require_arg, 'T' }, - { "write-only", require_arg, 'w' }, - { "write-onl", require_arg, 'w' }, - { "write-on", require_arg, 'w' }, - { "write-o", require_arg, 'w' }, - { "write", require_arg, 'w' }, - { "writ", require_arg, 'w' }, - { "wri", require_arg, 'w' }, - { "wr", require_arg, 'w' }, - { 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 num_dsets; /* number of datasets */ - long num_files; /* number of files */ - off_t num_bpp; /* number of bytes per proc per dset */ - int num_iters; /* number of iterations */ - int max_num_procs; /* maximum number of processes to use */ - int min_num_procs; /* minimum number of processes to use */ - size_t max_xfer_size; /* maximum transfer buffer size */ - size_t min_xfer_size; /* minimum transfer buffer size */ - size_t blk_size; /* Block size */ - unsigned interleaved; /* Interleaved vs. contiguous blocks */ - unsigned collective; /* Collective vs. independent I/O */ - unsigned dim2d; /* 1D vs. 2D geometry */ - int print_times; /* print times as well as throughputs */ - int print_raw; /* print raw data throughput info */ - off_t h5_alignment; /* alignment in HDF5 file */ - off_t h5_threshold; /* threshold for alignment in HDF5 file */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int verify; /* Verify data correctness */ -}; - -typedef struct _minmax { - double min; - double max; - double sum; - int num; -} minmax; - -/* local functions */ -static off_t parse_size_directive(const char *size); -static struct options *parse_command_line(int argc, char *argv[]); -static void run_test_loop(struct options *options); -static int run_test(iotype iot, parameters parms, struct options *opts); -static void output_all_info(minmax *mm, int count, int indent_level); -static void get_minmax(minmax *mm, double val); -static minmax accumulate_minmax_stuff(minmax *mm, int count); -static int create_comm_world(int num_procs, int *doing_pio); -static int destroy_comm_world(void); -static void output_results(const struct options *options, const char *name, - minmax *table, int table_size, off_t data_size); -static void output_times(const struct options *options, const char *name, - minmax *table, int table_size); -static void output_report(const char *fmt, ...); -static void print_indent(register int indent); -static void usage(const char *prog); -static void report_parameters(struct options *opts); - -/* - * Function: main - * Purpose: Start things up. Initialize MPI and then call the test looping - * function. - * Return: EXIT_SUCCESS or EXIT_FAILURE - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - */ -int -main(int argc, char **argv) -{ - int ret; - int exit_value = EXIT_SUCCESS; - struct options *opts = NULL; - -#ifndef STANDALONE - /* Initialize h5tools lib */ - h5tools_init(); -#endif - - output = stdout; - - /* initialize MPI and get the maximum num of processors we started with */ - MPI_Init(&argc, &argv); - ret = MPI_Comm_size(MPI_COMM_WORLD, &comm_world_nprocs_g); - - if (ret != MPI_SUCCESS) { - fprintf(stderr, "%s: MPI_Comm_size call failed\n", progname); - - if (ret == MPI_ERR_COMM) - fprintf(stderr, "invalid MPI communicator\n"); - else - fprintf(stderr, "invalid argument\n"); - - exit_value = EXIT_FAILURE; - goto finish; - } - - ret = MPI_Comm_rank(MPI_COMM_WORLD, &comm_world_rank_g); - - if (ret != MPI_SUCCESS) { - fprintf(stderr, "%s: MPI_Comm_rank call failed\n", progname); - - if (ret == MPI_ERR_COMM) - fprintf(stderr, "invalid MPI communicator\n"); - else - fprintf(stderr, "invalid argument\n"); - - exit_value = EXIT_FAILURE; - goto finish; - } - - pio_comm_g = MPI_COMM_WORLD; - - h5_set_info_object(); - opts = parse_command_line(argc, argv); - - if (!opts) { - exit_value = EXIT_FAILURE; - goto finish; - } - - if (opts->output_file) { - if ((output = HDfopen(opts->output_file, "w")) == NULL) { - fprintf(stderr, "%s: cannot open output file\n", progname); - perror(opts->output_file); - goto finish; - } - } - - if ((pio_debug_level == 0 && comm_world_rank_g == 0) || pio_debug_level > 0) - report_parameters(opts); - - run_test_loop(opts); - -finish: - MPI_Finalize(); - free(opts); - return exit_value; -} - -/* - * Function: run_test_loop - * Purpose: Run the I/O tests. Write the results to OUTPUT. - * - * - The slowest changing part of the test is the number of - * processors to use. For each loop iteration, we divide that - * number by 2 and rerun the test. - * - * - The second slowest is what type of IO API to perform. We have - * three choices: POSIXIO, MPI-IO, and PHDF5. - * - * - Then we change the size of the buffer. This information is - * inferred from the number of datasets to create and the number - * of integers to put into each dataset. The backend code figures - * this out. - * - * Return: Nothing - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static void -run_test_loop(struct options *opts) -{ - parameters parms; - int num_procs; - int doing_pio; /* if this process is doing PIO */ - - parms.num_files = opts->num_files; - parms.num_dsets = opts->num_dsets; - parms.num_iters = opts->num_iters; - parms.blk_size = opts->blk_size; - parms.interleaved = opts->interleaved; - parms.collective = opts->collective; - parms.dim2d = opts->dim2d; - parms.h5_align = opts->h5_alignment; - parms.h5_thresh = opts->h5_threshold; - parms.h5_use_chunks = opts->h5_use_chunks; - parms.h5_write_only = opts->h5_write_only; - parms.verify = opts->verify; - - /* start with max_num_procs and decrement it by half for each loop. */ - /* if performance needs restart, fewer processes may be needed. */ - for (num_procs = opts->max_num_procs; - num_procs >= opts->min_num_procs; num_procs >>= 1) { - register size_t buf_size; - - parms.num_procs = num_procs; - - if (create_comm_world(parms.num_procs, &doing_pio) != SUCCESS) { - /* do something harsh */ - } - - /* only processes doing PIO will run the tests */ - if (doing_pio){ - output_report("Number of processors = %ld\n", parms.num_procs); - - /* multiply the xfer buffer size by 2 for each loop iteration */ - for (buf_size = opts->min_xfer_size; - buf_size <= opts->max_xfer_size; buf_size <<= 1) { - parms.buf_size = buf_size; - - if (parms.dim2d){ - parms.num_bytes = (off_t)pow((double)(opts->num_bpp*parms.num_procs),2); - if (parms.interleaved) - output_report("Transfer Buffer Size: %ldx%ld bytes, File size: %.2f MB\n", - buf_size, opts->blk_size, - ((double)parms.num_dsets * (double)parms.num_bytes) - / ONE_MB); - else - output_report("Transfer Buffer Size: %ldx%ld bytes, File size: %.2f MB\n", - opts->blk_size, buf_size, - ((double)parms.num_dsets * (double)parms.num_bytes) - / ONE_MB); - - print_indent(1); - output_report(" # of files: %ld, # of datasets: %ld, dataset size: %.2fx%.2f KB\n", - parms.num_files, parms.num_dsets, (double)(opts->num_bpp*parms.num_procs)/ONE_KB, - (double)(opts->num_bpp*parms.num_procs)/ONE_KB); - } - else{ - parms.num_bytes = (off_t)opts->num_bpp*parms.num_procs; - output_report("Transfer Buffer Size: %ld bytes, File size: %.2f MB\n", - buf_size,((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); - - print_indent(1); - output_report(" # of files: %ld, # of datasets: %ld, dataset size: %.2f MB\n", - parms.num_files, parms.num_dsets, (double)(opts->num_bpp*parms.num_procs)/ONE_MB); - } - - if (opts->io_types & PIO_POSIX) - run_test(POSIXIO, parms, opts); - - if (opts->io_types & PIO_MPI) - run_test(MPIO, parms, opts); - - if (opts->io_types & PIO_HDF5) - run_test(PHDF5, parms, opts); - - /* Run the tests once if buf_size==0, but then break out */ - if(buf_size==0) - break; - } - - if (destroy_comm_world() != SUCCESS) { - /* do something harsh */ - } - } - } -} - -/* - * Function: run_test - * Purpose: Inner loop call to actually run the I/O test. - * Return: Nothing - * Programmer: Bill Wendling, 18. December 2001 - * Modifications: - */ -static int -run_test(iotype iot, parameters parms, struct options *opts) -{ - results res; - register int i, ret_value = SUCCESS; - int comm_size; - off_t raw_size; - minmax *write_mpi_mm_table=NULL; - minmax *write_mm_table=NULL; - minmax *write_gross_mm_table=NULL; - minmax *write_raw_mm_table=NULL; - minmax *read_mpi_mm_table=NULL; - minmax *read_mm_table=NULL; - minmax *read_gross_mm_table=NULL; - minmax *read_raw_mm_table=NULL; - minmax *read_open_mm_table=NULL; - minmax *read_close_mm_table=NULL; - minmax *write_open_mm_table=NULL; - minmax *write_close_mm_table=NULL; - minmax write_mpi_mm = {0.0, 0.0, 0.0, 0}; - minmax write_mm = {0.0, 0.0, 0.0, 0}; - minmax write_gross_mm = {0.0, 0.0, 0.0, 0}; - minmax write_raw_mm = {0.0, 0.0, 0.0, 0}; - minmax read_mpi_mm = {0.0, 0.0, 0.0, 0}; - minmax read_mm = {0.0, 0.0, 0.0, 0}; - minmax read_gross_mm = {0.0, 0.0, 0.0, 0}; - minmax read_raw_mm = {0.0, 0.0, 0.0, 0}; - minmax read_open_mm = {0.0, 0.0, 0.0, 0}; - minmax read_close_mm = {0.0, 0.0, 0.0, 0}; - minmax write_open_mm = {0.0, 0.0, 0.0, 0}; - minmax write_close_mm = {0.0, 0.0, 0.0, 0}; - - raw_size = parms.num_files * (off_t)parms.num_dsets * (off_t)parms.num_bytes; - parms.io_type = iot; - print_indent(2); - output_report("IO API = "); - - switch (iot) { - case POSIXIO: - output_report("POSIX\n"); - break; - case MPIO: - output_report("MPIO\n"); - break; - case PHDF5: - output_report("PHDF5 (w/MPI-IO driver)\n"); - break; - } - - MPI_Comm_size(pio_comm_g, &comm_size); - - /* allocate space for tables minmax and that it is sufficient */ - /* to initialize all elements to zeros by calloc. */ - write_mpi_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - write_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - write_gross_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - write_raw_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - write_open_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - write_close_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - if (!parms.h5_write_only) { - read_mpi_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - read_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - read_gross_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - read_raw_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - read_open_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - read_close_mm_table = calloc((size_t)parms.num_iters , sizeof(minmax)); - } - - /* Do IO iteration times, collecting statistics each time */ - for (i = 0; i < parms.num_iters; ++i) { - double t; - - MPI_Barrier(pio_comm_g); - res = do_pio(parms); - - /* gather all of the "mpi write" times */ - t = get_time(res.timers, HDF5_MPI_WRITE); - get_minmax(&write_mpi_mm, t); - - write_mpi_mm_table[i] = write_mpi_mm; - - /* gather all of the "write" times */ - t = get_time(res.timers, HDF5_FINE_WRITE_FIXED_DIMS); - get_minmax(&write_mm, t); - - write_mm_table[i] = write_mm; - - /* gather all of the "write" times from open to close */ - t = get_time(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS); - get_minmax(&write_gross_mm, t); - - write_gross_mm_table[i] = write_gross_mm; - - /* gather all of the raw "write" times */ - t = get_time(res.timers, HDF5_RAW_WRITE_FIXED_DIMS); - get_minmax(&write_raw_mm, t); - - write_raw_mm_table[i] = write_raw_mm; - - /* gather all of the file open times (time from open to first write) */ - t = get_time(res.timers, HDF5_FILE_WRITE_OPEN); - get_minmax(&write_open_mm, t); - - write_open_mm_table[i] = write_open_mm; - - /* gather all of the file close times (time from last write to close) */ - t = get_time(res.timers, HDF5_FILE_WRITE_CLOSE); - get_minmax(&write_close_mm, t); - - write_close_mm_table[i] = write_close_mm; - - if (!parms.h5_write_only) { - /* gather all of the "mpi read" times */ - t = get_time(res.timers, HDF5_MPI_READ); - get_minmax(&read_mpi_mm, t); - - read_mpi_mm_table[i] = read_mpi_mm; - - /* gather all of the "read" times */ - t = get_time(res.timers, HDF5_FINE_READ_FIXED_DIMS); - get_minmax(&read_mm, t); - - read_mm_table[i] = read_mm; - - /* gather all of the "read" times from open to close */ - t = get_time(res.timers, HDF5_GROSS_READ_FIXED_DIMS); - get_minmax(&read_gross_mm, t); - - read_gross_mm_table[i] = read_gross_mm; - - /* gather all of the raw "read" times */ - t = get_time(res.timers, HDF5_RAW_READ_FIXED_DIMS); - get_minmax(&read_raw_mm, t); - - read_raw_mm_table[i] = read_raw_mm; - - /* gather all of the file open times (time from open to first read) */ - t = get_time(res.timers, HDF5_FILE_READ_OPEN); - get_minmax(&read_open_mm, t); - - read_open_mm_table[i] = read_open_mm; - - /* gather all of the file close times (time from last read to close) */ - t = get_time(res.timers, HDF5_FILE_READ_CLOSE); - get_minmax(&read_close_mm, t); - - read_close_mm_table[i] = read_close_mm; - - } - - io_time_destroy(res.timers); - } - - /* - * Show various statistics - */ - /* Write statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw write" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Write details:\n"); - output_all_info(write_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts,"Raw Data Write",write_raw_mm_table,parms.num_iters,raw_size); - } /* end if */ - - /* show mpi write statics */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Write details:\n"); - output_all_info(write_mpi_mm_table, parms.num_iters, 4); - } - - /* We don't currently output the MPI write results */ - - /* accumulate and output the max, min, and average "write" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write details:\n"); - output_all_info(write_mm_table, parms.num_iters, 4); - } - - output_results(opts,"Write",write_mm_table,parms.num_iters,raw_size); - - /* accumulate and output the max, min, and average "gross write" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write Open-Close details:\n"); - output_all_info(write_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts,"Write Open-Close",write_gross_mm_table,parms.num_iters,raw_size); - - if (opts->print_times) { - output_times(opts,"Write File Open",write_open_mm_table,parms.num_iters); - output_times(opts,"Write File Close",write_close_mm_table,parms.num_iters); - } - - /* Print out time from open to first write */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write file open details:\n"); - output_all_info(write_open_mm_table, parms.num_iters, 4); - } - - /* Print out time from last write to close */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write file close details:\n"); - output_all_info(write_close_mm_table, parms.num_iters, 4); - } - - if (!parms.h5_write_only) { - /* Read statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw read" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Read details:\n"); - output_all_info(read_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Raw Data Read", read_raw_mm_table, - parms.num_iters, raw_size); - } /* end if */ - - /* show mpi read statics */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Read details:\n"); - output_all_info(read_mpi_mm_table, parms.num_iters, 4); - } - - /* We don't currently output the MPI read results */ - - /* accumulate and output the max, min, and average "read" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read details:\n"); - output_all_info(read_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read", read_mm_table, parms.num_iters, raw_size); - - /* accumulate and output the max, min, and average "gross read" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read Open-Close details:\n"); - output_all_info(read_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read Open-Close", read_gross_mm_table,parms.num_iters, raw_size); - - if (opts->print_times) { - output_times(opts,"Read File Open",read_open_mm_table,parms.num_iters); - output_times(opts,"Read File Close",read_close_mm_table,parms.num_iters); - } - - /* Print out time from open to first read */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read file open details:\n"); - output_all_info(read_open_mm_table, parms.num_iters, 4); - } - - /* Print out time from last read to close */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read file close details:\n"); - output_all_info(read_close_mm_table, parms.num_iters, 4); - } - - } - - /* clean up our mess */ - free(write_mpi_mm_table); - free(write_mm_table); - free(write_gross_mm_table); - free(write_raw_mm_table); - free(write_open_mm_table); - free(write_close_mm_table); - - if (!parms.h5_write_only) { - free(read_mpi_mm_table); - free(read_mm_table); - free(read_gross_mm_table); - free(read_raw_mm_table); - free(read_open_mm_table); - free(read_close_mm_table); - } - - return ret_value; -} - -/* - * Function: output_all_info - * Purpose: - * Return: Nothing - * Programmer: Bill Wendling, 29. January 2002 - * Modifications: - */ -static void -output_all_info(minmax *mm, int count, int indent_level) -{ - int i; - - for (i = 0; i < count; ++i) { - print_indent(indent_level); - output_report("Iteration %d:\n", i + 1); - print_indent(indent_level + 1); - output_report("Minimum Time: %.2fs\n", mm[i].min); - print_indent(indent_level + 1); - output_report("Maximum Time: %.2fs\n", mm[i].max); - } -} - -/* - * Function: get_minmax - * Purpose: Gather all the min, max and total of val. - * Return: Nothing - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Use MPI_Allreduce to do it. -akc, 2002/01/11 - */ -static void -get_minmax(minmax *mm, double val) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - MPI_Comm_size(pio_comm_g, &mm->num); - - MPI_Allreduce(&val, &mm->max, 1, MPI_DOUBLE, MPI_MAX, pio_comm_g); - MPI_Allreduce(&val, &mm->min, 1, MPI_DOUBLE, MPI_MIN, pio_comm_g); - MPI_Allreduce(&val, &mm->sum, 1, MPI_DOUBLE, MPI_SUM, pio_comm_g); -} - -/* - * Function: accumulate_minmax_stuff - * Purpose: Accumulate the minimum, maximum, and average of the times - * across all processes. - * Return: TOTAL_MM - the total of all of these. - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Changed to use seconds instead of MB/s - QAK, 5/9/02 - */ -static minmax -accumulate_minmax_stuff(minmax *mm, int count) -{ - int i; - minmax total_mm; - - total_mm.sum = 0.0; - total_mm.max = -DBL_MAX; - total_mm.min = DBL_MAX; - total_mm.num = count; - - for (i = 0; i < count; ++i) { - double m = mm[i].max; - - total_mm.sum += m; - - if (m < total_mm.min) - total_mm.min = m; - - if (m > total_mm.max) - total_mm.max = m; - } - - return total_mm; -} - -/* - * Function: create_comm_world - * Purpose: Create an MPI Comm world and store it in pio_comm_g, which - * is a global variable. - * Return: SUCCESS on success. - * FAIL otherwise. - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static int -create_comm_world(int num_procs, int *doing_pio) -{ - /* MPI variables */ - int mrc; /* return values */ - int color; /* for communicator creation */ - int myrank, nprocs; - - pio_comm_g = MPI_COMM_NULL; - - /* - * Create a sub communicator for this PIO run. Easier to use the first N - * processes. - */ - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - - if (num_procs > nprocs) { - fprintf(stderr, - "number of process(%d) must be <= number of processes in MPI_COMM_WORLD(%d)\n", - num_procs, nprocs); - goto error_done; - } - - MPI_Comm_rank(MPI_COMM_WORLD, &myrank); - color = (myrank < num_procs); - mrc = MPI_Comm_split(MPI_COMM_WORLD, color, myrank, &pio_comm_g); - - if (mrc != MPI_SUCCESS) { - fprintf(stderr, "MPI_Comm_split failed\n"); - goto error_done; - } - - if (!color) { - /* not involved in this run */ - mrc = destroy_comm_world(); - goto done; - } - - /* determine the MPI rank in the PIO communicator */ - MPI_Comm_size(pio_comm_g, &pio_mpi_nprocs_g); - MPI_Comm_rank(pio_comm_g, &pio_mpi_rank_g); - -done: - *doing_pio = color; - return SUCCESS; - -error_done: - destroy_comm_world(); - return FAIL; -} - -/* - * Function: destroy_comm_world - * Purpose: Destroy the created MPI Comm world which is stored in the - * pio_comm_g global variable. - * Return: SUCCESS on success. - * FAIL otherwise. - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static int -destroy_comm_world(void) -{ - int mrc = SUCCESS; /* return code */ - - /* release MPI resources */ - if (pio_comm_g != MPI_COMM_NULL) - mrc = (MPI_Comm_free(&pio_comm_g) == MPI_SUCCESS ? SUCCESS : FAIL); - - return mrc; -} - -/* - * Function: output_results - * Purpose: Print information about the time & bandwidth for a given - * minmax & # of iterations. - * Return: Nothing - * Programmer: Quincey Koziol, 9. May 2002 - * Modifications: - */ -static void -output_results(const struct options *opts, const char *name, minmax *table, - int table_size,off_t data_size) -{ - minmax total_mm; - - total_mm = accumulate_minmax_stuff(table, table_size); - - print_indent(3); - output_report("%s (%d iteration(s)):\n", name,table_size); - - /* Note: The maximum throughput uses the minimum amount of time & vice versa */ - - print_indent(4); - output_report("Maximum Throughput: %6.2f MB/s", MB_PER_SEC(data_size,total_mm.min)); - if(opts->print_times) - output_report(" (%7.3f s)\n", total_mm.min); - else - output_report("\n"); - - print_indent(4); - output_report("Average Throughput: %6.2f MB/s", - MB_PER_SEC(data_size,total_mm.sum / total_mm.num)); - if(opts->print_times) - output_report(" (%7.3f s)\n", (total_mm.sum / total_mm.num)); - else - output_report("\n"); - - print_indent(4); - output_report("Minimum Throughput: %6.2f MB/s", MB_PER_SEC(data_size,total_mm.max)); - if(opts->print_times) - output_report(" (%7.3f s)\n", total_mm.max); - else - output_report("\n"); - -} - -static void -output_times(const struct options *opts, const char *name, minmax *table, - int table_size) -{ - minmax total_mm; - - total_mm = accumulate_minmax_stuff(table, table_size); - - print_indent(3); - output_report("%s (%d iteration(s)):\n", name,table_size); - - /* Note: The maximum throughput uses the minimum amount of time & vice versa */ - - print_indent(4); - output_report("Minimum Accumulated Time using %d file(s): %7.5f s\n", opts->num_files,(total_mm.min)); - - print_indent(4); - output_report("Average Accumulated Time using %d file(s): %7.5f s\n", opts->num_files,(total_mm.sum / total_mm.num)); - - print_indent(4); - output_report("Maximum Accumulated Time using %d file(s): %7.5f s\n", opts->num_files,(total_mm.max)); -} - -/* - * Function: output_report - * Purpose: Print a line of the report. Only do so if I'm the 0 process. - * Return: Nothing - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static void -output_report(const char *fmt, ...) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - if (myrank == 0) { - va_list ap; - - va_start(ap, fmt); - vfprintf(output, fmt, ap); - va_end(ap); - } -} - -/* - * Function: print_indent - * Purpose: Print spaces to indent a new line of text for pretty printing - * things. - * Return: Nothing - * Programmer: Bill Wendling, 29. October 2001 - * Modifications: - */ -static void -print_indent(register int indent) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - if (myrank == 0) { - indent *= TAB_SPACE; - - for (; indent > 0; --indent) - fputc(' ', output); - } -} - -static void -recover_size_and_print(long long val, const char *end) -{ - if (val >= ONE_KB && (val % ONE_KB) == 0) { - if (val >= ONE_MB && (val % ONE_MB) == 0) { - if (val >= ONE_GB && (val % ONE_GB) == 0) - HDfprintf(output, "%" H5_PRINTF_LL_WIDTH "d""GB%s", val / ONE_GB, end); - else - HDfprintf(output, "%" H5_PRINTF_LL_WIDTH "d""MB%s", val / ONE_MB, end); - } else { - HDfprintf(output, "%" H5_PRINTF_LL_WIDTH "d""KB%s", val / ONE_KB, end); - } - } else { - HDfprintf(output, "%" H5_PRINTF_LL_WIDTH "d""%s", val, end); - } -} - -static void -print_io_api(long io_types) -{ - if (io_types & PIO_POSIX) - HDfprintf(output, "posix "); - if (io_types & PIO_MPI) - HDfprintf(output, "mpiio "); - if (io_types & PIO_HDF5) - HDfprintf(output, "phdf5 "); - HDfprintf(output, "\n"); -} - -static void -report_parameters(struct options *opts) -{ - int rank = comm_world_rank_g; - - print_version("HDF5 Library"); /* print library version */ - HDfprintf(output, "rank %d: ==== Parameters ====\n", rank); - - HDfprintf(output, "rank %d: IO API=", rank); - print_io_api(opts->io_types); - - HDfprintf(output, "rank %d: Number of files=%ld\n", rank, - opts->num_files); - HDfprintf(output, "rank %d: Number of datasets=%ld\n", rank, - opts->num_dsets); - HDfprintf(output, "rank %d: Number of iterations=%d\n", rank, - opts->num_iters); - HDfprintf(output, "rank %d: Number of processes=%d:%d\n", rank, - opts->min_num_procs, opts->max_num_procs); - - if (opts->dim2d){ - HDfprintf(output, "rank %d: Number of bytes per process per dataset=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->num_bpp * opts->min_num_procs), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->num_bpp * opts->max_num_procs), "\n"); - - HDfprintf(output, "rank %d: Size of dataset(s)=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), "x"); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "x"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "\n"); - - HDfprintf(output, "rank %d: File size=", rank); - recover_size_and_print((long long)(pow(opts->num_bpp * opts->min_num_procs,2) - * opts->num_dsets), ":"); - recover_size_and_print((long long)(pow(opts->num_bpp * opts->max_num_procs,2) - * opts->num_dsets), "\n"); - - HDfprintf(output, "rank %d: Transfer buffer size=", rank); - if(opts->interleaved){ - recover_size_and_print((long long)opts->min_xfer_size, "x"); - recover_size_and_print((long long)opts->blk_size, ":"); - recover_size_and_print((long long)opts->max_xfer_size, "x"); - recover_size_and_print((long long)opts->blk_size, "\n"); - } - else{ - recover_size_and_print((long long)opts->blk_size, "x"); - recover_size_and_print((long long)opts->min_xfer_size, ":"); - recover_size_and_print((long long)opts->blk_size, "x"); - recover_size_and_print((long long)opts->max_xfer_size, "\n"); - } - HDfprintf(output, "rank %d: Block size=", rank); - recover_size_and_print((long long)opts->blk_size, "x"); - recover_size_and_print((long long)opts->blk_size, "\n"); - } - else{ - HDfprintf(output, "rank %d: Number of bytes per process per dataset=", rank); - recover_size_and_print((long long)opts->num_bpp, "\n"); - - HDfprintf(output, "rank %d: Size of dataset(s)=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "\n"); - - HDfprintf(output, "rank %d: File size=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs - * opts->num_dsets), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs - * opts->num_dsets), "\n"); - - HDfprintf(output, "rank %d: Transfer buffer size=", rank); - recover_size_and_print((long long)opts->min_xfer_size, ":"); - recover_size_and_print((long long)opts->max_xfer_size, "\n"); - HDfprintf(output, "rank %d: Block size=", rank); - recover_size_and_print((long long)opts->blk_size, "\n"); - } - - HDfprintf(output, "rank %d: Block Pattern in Dataset=", rank); - if(opts->interleaved) - HDfprintf(output, "Interleaved\n"); - else - HDfprintf(output, "Contiguous\n"); - - HDfprintf(output, "rank %d: I/O Method for MPI and HDF5=", rank); - if(opts->collective) - HDfprintf(output, "Collective\n"); - else - HDfprintf(output, "Independent\n"); - - HDfprintf(output, "rank %d: Geometry=", rank); - if(opts->dim2d) - HDfprintf(output, "2D\n"); - else - HDfprintf(output, "1D\n"); - - HDfprintf(output, "rank %d: VFL used for HDF5 I/O=%s\n", rank, "MPI-IO driver"); - - HDfprintf(output, "rank %d: Data storage method in HDF5=", rank); - if(opts->h5_use_chunks) - HDfprintf(output, "Chunked\n"); - else - HDfprintf(output, "Contiguous\n"); - - { - char *prefix = HDgetenv("HDF5_PARAPREFIX"); - - HDfprintf(output, "rank %d: Env HDF5_PARAPREFIX=%s\n", rank, - (prefix ? prefix : "not set")); - } - - HDfprintf(output, "rank %d: ", rank); - h5_dump_info_object(h5_io_info_g); - - HDfprintf(output, "rank %d: ==== End of Parameters ====\n", rank); - HDfprintf(output, "\n"); -} - -/* - * Function: parse_command_line - * Purpose: Parse the command line options and return a STRUCT OPTIONS - * structure which will need to be freed by the calling function. - * Return: Pointer to an OPTIONS structure - * Programmer: Bill Wendling, 31. October 2001 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static struct options * -parse_command_line(int argc, char *argv[]) -{ - register int opt; - struct options *cl_opts; - - cl_opts = (struct options *)malloc(sizeof(struct options)); - - cl_opts->output_file = NULL; - cl_opts->io_types = 0; /* will set default after parsing options */ - cl_opts->num_dsets = 1; - cl_opts->num_files = 1; - cl_opts->num_bpp = 0; - cl_opts->num_iters = 1; - cl_opts->max_num_procs = comm_world_nprocs_g; - cl_opts->min_num_procs = 1; - cl_opts->max_xfer_size = 0; - cl_opts->min_xfer_size = 0; - cl_opts->blk_size = 0; - cl_opts->interleaved = 0; /* Default to contiguous blocks in dataset */ - cl_opts->collective = 0; /* Default to independent I/O access */ - cl_opts->dim2d = 0; /* Default to 1D */ - cl_opts->print_times = FALSE; /* Printing times is off by default */ - cl_opts->print_raw = FALSE; /* Printing raw data throughput is off by default */ - cl_opts->h5_alignment = 1; /* No alignment for HDF5 objects by default */ - cl_opts->h5_threshold = 1; /* No threshold for aligning HDF5 objects by default */ - cl_opts->h5_use_chunks = FALSE; /* Don't chunk the HDF5 dataset by default */ - cl_opts->h5_write_only = FALSE; /* Do both read and write by default */ - cl_opts->verify = FALSE; /* No Verify data correctness by default */ - - while ((opt = get_option(argc, (const char **)argv, s_opts, l_opts)) != EOF) { - switch ((char)opt) { - case 'a': - cl_opts->h5_alignment = parse_size_directive(opt_arg); - break; - case 'A': - { - const char *end = opt_arg; - - while (end && *end != '\0') { - char buf[10]; - int i; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (isalnum(*end) && i < 10) - buf[i++] = *end; - - if (!HDstrcasecmp(buf, "phdf5")) { - cl_opts->io_types |= PIO_HDF5; - } else if (!HDstrcasecmp(buf, "mpiio")) { - cl_opts->io_types |= PIO_MPI; - } else if (!HDstrcasecmp(buf, "posix")) { - cl_opts->io_types |= PIO_POSIX; - } else { - fprintf(stderr, "pio_perf: invalid --api option %s\n", - buf); - exit(EXIT_FAILURE); - } - - if (*end == '\0') - break; - - end++; - } - } - - break; -#if 0 - case 'b': - /* the future "binary" option */ - break; -#endif /* 0 */ - case 'B': - cl_opts->blk_size = parse_size_directive(opt_arg); - break; - case 'c': - /* Turn on chunked HDF5 dataset creation */ - cl_opts->h5_use_chunks = TRUE; - break; - case 'C': - cl_opts->collective = 1; - break; - case 'd': - cl_opts->num_dsets = atoi(opt_arg); - break; - case 'D': - { - const char *end = opt_arg; - - while (end && *end != '\0') { - char buf[10]; - int i; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (isalnum(*end) && i < 10) - buf[i++] = *end; - - if (strlen(buf) > 1 || isdigit(buf[0])) { - size_t j; - - for (j = 0; j < 10 && buf[j] != '\0'; ++j) - if (!isdigit(buf[j])) { - fprintf(stderr, "pio_perf: invalid --debug option %s\n", - buf); - exit(EXIT_FAILURE); - } - - pio_debug_level = atoi(buf); - - if (pio_debug_level > 4) - pio_debug_level = 4; - else if (pio_debug_level < 0) - pio_debug_level = 0; - } else { - switch (*buf) { - case 'r': - /* Turn on raw data throughput info */ - cl_opts->print_raw = TRUE; - break; - case 't': - /* Turn on time printing */ - cl_opts->print_times = TRUE; - break; - case 'v': - /* Turn on verify data correctness*/ - cl_opts->verify = TRUE; - break; - default: - fprintf(stderr, "pio_perf: invalid --debug option %s\n", buf); - exit(EXIT_FAILURE); - } - } - - if (*end == '\0') - break; - - end++; - } - } - - break; - case 'e': - cl_opts->num_bpp = parse_size_directive(opt_arg); - break; - case 'F': - cl_opts->num_files = atoi(opt_arg); - break; - case 'g': - cl_opts->dim2d = 1; - break; - case 'i': - cl_opts->num_iters = atoi(opt_arg); - break; - case 'I': - cl_opts->interleaved = 1; - break; - case 'o': - cl_opts->output_file = opt_arg; - break; - case 'p': - cl_opts->min_num_procs = atoi(opt_arg); - break; - case 'P': - cl_opts->max_num_procs = atoi(opt_arg); - break; - case 'T': - cl_opts->h5_threshold = parse_size_directive(opt_arg); - break; - case 'w': - cl_opts->h5_write_only = TRUE; - 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': - case '?': - default: - usage(progname); - free(cl_opts); - return NULL; - } - } - - - if (cl_opts->num_bpp == 0){ - if (cl_opts->dim2d == 0) - cl_opts->num_bpp = 256 * ONE_KB; - else - cl_opts->num_bpp = 8 * ONE_KB; - } - - if (cl_opts->max_xfer_size == 0) - cl_opts->max_xfer_size = cl_opts->num_bpp; - - if (cl_opts->min_xfer_size == 0) - cl_opts->min_xfer_size = (cl_opts->num_bpp)/2; - - if (cl_opts->blk_size == 0) - cl_opts->blk_size = (cl_opts->num_bpp)/2; - - - /* set default if none specified yet */ - if (!cl_opts->io_types) - cl_opts->io_types = PIO_HDF5 | PIO_MPI | PIO_POSIX; /* run all API */ - - /* verify parameters sanity. Adjust if needed. */ - /* cap xfer_size with bytes per process */ - if (!cl_opts->dim2d) { - if (cl_opts->min_xfer_size > cl_opts->num_bpp) - cl_opts->min_xfer_size = cl_opts->num_bpp; - if (cl_opts->max_xfer_size > cl_opts->num_bpp) - cl_opts->max_xfer_size = cl_opts->num_bpp; - } - if (cl_opts->min_xfer_size > cl_opts->max_xfer_size) - cl_opts->min_xfer_size = cl_opts->max_xfer_size; - if (cl_opts->blk_size > cl_opts->num_bpp ) - cl_opts->blk_size = cl_opts->num_bpp; - /* check range of number of processes */ - if (cl_opts->min_num_procs <= 0) - cl_opts->min_num_procs = 1; - if (cl_opts->max_num_procs <= 0) - cl_opts->max_num_procs = 1; - if (cl_opts->min_num_procs > cl_opts->max_num_procs) - cl_opts->min_num_procs = cl_opts->max_num_procs; - /* check iteration */ - if (cl_opts->num_iters <= 0) - cl_opts->num_iters = 1; - - 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 off_t because this is related to file size. - * 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 off_t -parse_size_directive(const char *size) -{ - off_t s; - char *endptr; - - s = HDstrtol(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: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static void -usage(const char *prog) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - if (myrank == 0) { - print_version(prog); - printf("usage: %s [OPTIONS]\n", prog); - printf(" OPTIONS\n"); - printf(" -h, --help Print a usage message and exit\n"); - printf(" -a S, --align=S Alignment of objects in HDF5 file [default: 1]\n"); - printf(" -A AL, --api=AL Which APIs to test [default: all of them]\n"); -#if 0 - printf(" -b, --binary The elusive binary option\n"); -#endif /* 0 */ - printf(" -B S, --block-size=S Block size within transfer buffer\n"); - printf(" (see below for description)\n"); - printf(" [default: half the number of bytes per process\n"); - printf(" per dataset]\n"); - printf(" -c, --chunk Create HDF5 datasets using chunked storage\n"); - printf(" [default: contiguous storage]\n"); - printf(" -C, --collective Use collective I/O for MPI and HDF5 APIs\n"); - printf(" [default: independent I/O)\n"); - printf(" -d N, --num-dsets=N Number of datasets per file [default: 1]\n"); - printf(" -D DL, --debug=DL Indicate the debugging level\n"); - printf(" [default: no debugging]\n"); - printf(" -e S, --num-bytes=S Number of bytes per process per dataset\n"); - printf(" (see below for description)\n"); - printf(" [default: 256K for 1D, 8K for 2D]\n"); - printf(" -F N, --num-files=N Number of files [default: 1]\n"); - printf(" -g, --geometry Use 2D geometry [default: 1D geometry]\n"); - printf(" -i N, --num-iterations=N Number of iterations to perform [default: 1]\n"); - printf(" -I, --interleaved Interleaved access pattern\n"); - printf(" (see below for example)\n"); - printf(" [default: Contiguous access pattern]\n"); - printf(" -o F, --output=F Output raw data into file F [default: none]\n"); - printf(" -p N, --min-num-processes=N Minimum number of processes to use [default: 1]\n"); - printf(" -P N, --max-num-processes=N Maximum number of processes to use\n"); - printf(" [default: all MPI_COMM_WORLD processes ]\n"); - printf(" -T S, --threshold=S Threshold for alignment of objects in HDF5 file\n"); - printf(" [default: 1]\n"); - printf(" -w, --write-only Perform write tests not the read tests\n"); - printf(" -x S, --min-xfer-size=S Minimum transfer buffer size\n"); - printf(" (see below for description)\n"); - printf(" [default: half the number of bytes per process\n"); - printf(" per dataset]\n"); - printf(" -X S, --max-xfer-size=S Maximum transfer buffer size\n"); - printf(" [default: the number of bytes per process per\n"); - printf(" dataset]\n"); - printf("\n"); - printf(" F - is a filename.\n"); - printf(" N - is an integer >=0.\n"); - printf(" S - is a size specifier, an integer >=0 followed by a size indicator:\n"); - printf(" K - Kilobyte (%d)\n", ONE_KB); - printf(" M - Megabyte (%d)\n", ONE_MB); - printf(" G - Gigabyte (%d)\n", ONE_GB); - printf("\n"); - printf(" Example: '37M' is 37 megabytes or %d bytes\n", 37*ONE_MB); - printf("\n"); - printf(" AL - is an API list. Valid values are:\n"); - printf(" phdf5 - Parallel HDF5\n"); - printf(" mpiio - MPI-I/O\n"); - printf(" posix - POSIX\n"); - printf("\n"); - printf(" Example: --api=mpiio,phdf5\n"); - printf("\n"); - printf(" Dataset size:\n"); - printf(" Depending on the selected geometry, each test dataset is either a linear\n"); - printf(" array of size bytes-per-process * num-processes, or a square array of size\n"); - printf(" (bytes-per-process * num-processes) x (bytes-per-process * num-processes).\n"); - printf("\n"); - printf(" Block size vs. Transfer buffer size:\n"); - printf(" buffer-size controls the size of the memory buffer, which is broken into\n"); - printf(" blocks and written to the file. Depending on the selected geometry, each\n"); - printf(" block can be a linear array of size block-size or a square array of size\n"); - printf(" block-size x block-size. The arrangement in which blocks are written is\n"); - printf(" determined by the access pattern.\n"); - printf("\n"); - printf(" In 1D geometry, the transfer buffer is a linear array of size buffer-size.\n"); - printf(" In 2D geometry, it is a rectangular array of size block-size x buffer-size\n"); - printf(" or buffer-size x block-size if interleaved pattern is selected.\n"); - printf("\n"); - printf(" Interleaved and Contiguous patterns in 1D geometry:\n"); - printf(" When contiguous access pattern is chosen, the dataset is evenly divided\n"); - printf(" into num-processes regions and each process writes data to its own region.\n"); - printf(" When interleaved blocks are written to a dataset, space for the first\n"); - printf(" block of the first process is allocated in the dataset, then space is\n"); - printf(" allocated for the first block of the second process, etc. until space is\n"); - printf(" allocated for the first block of each process, then space is allocated for\n"); - printf(" the second block of the first process, the second block of the second\n"); - printf(" process, etc.\n"); - printf("\n"); - printf(" For example, with a 3 process run, 512KB bytes-per-process, 256KB transfer\n"); - printf(" buffer size, and 64KB block size, each process must issue 2 transfer\n"); - printf(" requests to complete access to the dataset.\n"); - printf(" Contiguous blocks of the first transfer request are written like so:\n"); - printf(" 1111----2222----3333----\n"); - printf(" Interleaved blocks of the first transfer request are written like so:\n"); - printf(" 123123123123------------\n"); - printf(" The actual number of I/O operations involved in a transfer request\n"); - printf(" depends on the access pattern and communication mode.\n"); - printf(" When using independent I/O with interleaved pattern, each process\n"); - printf(" performs 4 small non-contiguous I/O operations per transfer request.\n"); - printf(" If collective I/O is turned on, the combined content of the buffers of\n"); - printf(" the 3 processes will be written using one collective I/O operation\n"); - printf(" per transfer request.\n"); - printf("\n"); - printf(" For information about access patterns in 2D geometry, please refer to the\n"); - printf(" HDF5 Reference Manual.\n"); - printf("\n"); - printf(" DL - is a list of debugging flags. Valid values are:\n"); - printf(" 1 - Minimal\n"); - printf(" 2 - Not quite everything\n"); - printf(" 3 - Everything\n"); - printf(" 4 - The kitchen sink\n"); - printf(" r - Raw data I/O throughput information\n"); - printf(" t - Times as well as throughputs\n"); - printf(" v - Verify data correctness\n"); - printf("\n"); - printf(" Example: --debug=2,r,t\n"); - printf("\n"); - printf(" Environment variables:\n"); - printf(" HDF5_NOCLEANUP Do not remove data files if set [default remove]\n"); - printf(" HDF5_MPI_INFO MPI INFO object key=value separated by ;\n"); - printf(" HDF5_PARAPREFIX Paralllel data files prefix\n"); - fflush(stdout); - } /* end if */ -} /* end usage() */ - -#else /* H5_HAVE_PARALLEL */ - -/* - * Function: main - * Purpose: Dummy main() function for if HDF5 was configured without - * parallel stuff. - * Return: EXIT_SUCCESS - * Programmer: Bill Wendling, 14. November 2001 - */ -int -main(void) -{ - printf("No parallel IO performance because parallel is not configured\n"); - return EXIT_SUCCESS; -} /* end main */ - -#endif /* !H5_HAVE_PARALLEL */ diff --git a/tools/perform/pio_perf.h b/tools/perform/pio_perf.h deleted file mode 100644 index 89cf3a8..0000000 --- a/tools/perform/pio_perf.h +++ /dev/null @@ -1,104 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef PIO_PERF_H__ -#define PIO_PERF_H__ - -#include "io_timer.h" -#ifndef STANDALONE -#include "H5private.h" -#include "h5test.h" -#include "h5tools.h" -#include "h5tools_utils.h" -#else -#include "pio_standalone.h" -#endif - -/* setup the dataset no fill option if this is v1.5 or more */ -#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR > 4 -#define H5_HAVE_NOFILL 1 -#endif - -typedef enum iotype_ { - POSIXIO, - MPIO, - PHDF5 - /*NUM_TYPES*/ -} iotype; - -typedef struct parameters_ { - iotype io_type; /* The type of IO test to perform */ - int num_procs; /* Maximum number of processes to use */ - long num_files; /* Number of files to create */ - long num_dsets; /* Number of datasets to create */ - off_t num_bytes; /* Number of bytes in each dset */ - int num_iters; /* Number of times to loop doing the IO */ - size_t buf_size; /* Buffer size */ - size_t blk_size; /* Block size */ - unsigned interleaved; /* Interleaved vs. contiguous blocks */ - unsigned collective; /* Collective vs. independent I/O */ - unsigned dim2d; /* 1D vs. 2D */ - hsize_t h5_align; /* HDF5 object alignment */ - hsize_t h5_thresh; /* HDF5 object alignment threshold */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int verify; /* Verify data correctness */ -} parameters; - -typedef struct results_ { - herr_t ret_code; - io_time_t *timers; -} results; - -#ifndef SUCCESS -#define SUCCESS 0 -#endif /* !SUCCESS */ - -#ifndef FAIL -#define FAIL -1 -#endif /* !FAIL */ - -extern FILE *output; /* output file */ -extern io_time_t *timer_g; /* timer: global for stub functions */ -extern int comm_world_rank_g; /* my rank in MPI_COMM_RANK */ -extern int comm_world_nprocs_g;/* num. of processes of MPI_COMM_WORLD */ -extern MPI_Comm pio_comm_g; /* Communicator to run the PIO */ -extern int pio_mpi_rank_g; /* MPI rank of pio_comm_g */ -extern int pio_mpi_nprocs_g; /* number of processes of pio_comm_g */ -extern int pio_debug_level; /* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Even More Debugging (timer stuff) - */ - -#define HDprint_rank(f) /* print rank in MPI_COMM_WORLD */ \ - HDfprintf(f, "%d: ", comm_world_rank_g); -#define HDprint_size(f) /* print size of MPI_COMM_WORLD */ \ - HDfprintf(f, "%d", comm_world_nprocs_g); -#define HDprint_rank_size(f) /* print rank/size of MPI_COMM_WORLD */ \ - HDfprintf(f, "%d/%d: ", comm_world_rank_g, comm_world_nprocs_g); - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern results do_pio(parameters param); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* PIO_PERF_H__ */ diff --git a/tools/perform/pio_standalone.c b/tools/perform/pio_standalone.c deleted file mode 100644 index 475c678..0000000 --- a/tools/perform/pio_standalone.c +++ /dev/null @@ -1,281 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -/* This file contains the definition of functions required to build h5perf in - * STANDALONE mode. - * Created: Christian Chilan, 2005/5/18. - */ - -#include "pio_perf.h" - - -/** From h5tools_utils.c **/ - -/* global variables */ -int nCols = 80; - -/* ``get_option'' variables */ -int opt_err = 1; /*get_option prints errors if this is on */ -int opt_ind = 1; /*token pointer */ -const char *opt_arg; /*flag argument (or value) */ - - -int -get_option(int argc, const char **argv, const char *opts, const struct long_options *l_opts) -{ - static int sp = 1; /* character index in current token */ - int opt_opt = '?'; /* option character passed back to user */ - - if (sp == 1) { - /* check for more flag-like tokens */ - if (opt_ind >= argc || argv[opt_ind][0] != '-' || argv[opt_ind][1] == '\0') { - return EOF; - } else if (HDstrcmp(argv[opt_ind], "--") == 0) { - opt_ind++; - return EOF; - } - } - - if (sp == 1 && argv[opt_ind][0] == '-' && argv[opt_ind][1] == '-') { - /* long command line option */ - const char *arg = &argv[opt_ind][2]; - int i; - - for (i = 0; l_opts && l_opts[i].name; i++) { - size_t len = HDstrlen(l_opts[i].name); - - if (HDstrncmp(arg, l_opts[i].name, len) == 0) { - /* we've found a matching long command line flag */ - opt_opt = l_opts[i].shortval; - - if (l_opts[i].has_arg != no_arg) { - if (arg[len] == '=') { - opt_arg = &arg[len + 1]; - } else if (opt_ind < (argc - 1) && argv[opt_ind + 1][0] != '-') { - opt_arg = argv[++opt_ind]; - } else if (l_opts[i].has_arg == require_arg) { - if (opt_err) - HDfprintf(stderr, - "%s: option required for \"--%s\" flag\n", - argv[0], arg); - - opt_opt = '?'; - } - } else { - if (arg[len] == '=') { - if (opt_err) - HDfprintf(stderr, - "%s: no option required for \"%s\" flag\n", - argv[0], arg); - - opt_opt = '?'; - } - - opt_arg = NULL; - } - - break; - } - } - - if (l_opts[i].name == NULL) { - /* exhausted all of the l_opts we have and still didn't match */ - if (opt_err) - HDfprintf(stderr, "%s: unknown option \"%s\"\n", argv[0], arg); - - opt_opt = '?'; - } - - opt_ind++; - sp = 1; - } else { - register char *cp; /* pointer into current token */ - - /* short command line option */ - opt_opt = argv[opt_ind][sp]; - - if (opt_opt == ':' || (cp = strchr(opts, opt_opt)) == 0) { - - if (opt_err) - HDfprintf(stderr, "%s: unknown option \"%c\"\n", - argv[0], opt_opt); - - /* if no chars left in this token, move to next token */ - if (argv[opt_ind][++sp] == '\0') { - opt_ind++; - sp = 1; - } - - return '?'; - } - - if (*++cp == ':') { - /* if a value is expected, get it */ - if (argv[opt_ind][sp + 1] != '\0') { - /* flag value is rest of current token */ - opt_arg = &argv[opt_ind++][sp + 1]; - } else if (++opt_ind >= argc) { - if (opt_err) - HDfprintf(stderr, - "%s: value expected for option \"%c\"\n", - argv[0], opt_opt); - - opt_opt = '?'; - } else { - /* flag value is next token */ - opt_arg = argv[opt_ind++]; - } - - sp = 1; - } else { - /* set up to look at next char in token, next time */ - if (argv[opt_ind][++sp] == '\0') { - /* no more in current token, so setup next token */ - opt_ind++; - sp = 1; - } - - opt_arg = NULL; - } - } - - /* return the current flag character found */ - return opt_opt; -} - - -void -print_version(const char *progname) -{ - printf("%s: Version %u.%u.%u%s%s\n", - progname, H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE, - H5_VERS_SUBRELEASE[0] ? "-" : "", H5_VERS_SUBRELEASE); -} - - - -/** From h5test.c **/ - -#ifdef H5_HAVE_PARALLEL -MPI_Info h5_io_info_g=MPI_INFO_NULL;/* MPI INFO object for IO */ -#endif - -int -h5_set_info_object(void) -{ - char *envp; /* environment pointer */ - int ret_value=0; - - /* handle any MPI INFO hints via $HDF5_MPI_INFO */ - if ((envp = getenv("HDF5_MPI_INFO")) != NULL){ - char *next, *valp; - - - valp = envp = next = HDstrdup(envp); - - /* create an INFO object if not created yet */ - if (h5_io_info_g == MPI_INFO_NULL) - MPI_Info_create(&h5_io_info_g); - - do { - size_t len; - char *key_val, *endp, *namep; - - if (*valp == ';') - valp++; - - /* copy key/value pair into temporary buffer */ - len = strcspn(valp, ";"); - next = &valp[len]; - key_val = calloc(1, len + 1); - - /* increment the next pointer past the terminating semicolon */ - if (*next == ';') - ++next; - - namep = HDstrncpy(key_val, valp, len); - - /* pass up any beginning whitespaces */ - while (*namep && (*namep == ' ' || *namep == '\t')) - namep++; - - /* eat up any ending white spaces */ - endp = &namep[strlen(namep) - 1]; - - while (endp && (*endp == ' ' || *endp == '\t')) - *endp-- = '\0'; - - /* find the '=' */ - - valp = HDstrchr(namep, '='); - - if (valp != NULL) { /* it's a valid key/value pairing */ - char *tmp_val = valp + 1; - - /* change '=' to \0, move valp down one */ - *valp-- = '\0'; - - /* eat up ending whitespace on the "key" part */ - while (*valp == ' ' || *valp == '\t') - *valp-- = '\0'; - - valp = tmp_val; - - /* eat up beginning whitespace on the "value" part */ - while (*valp == ' ' || *valp == '\t') - *valp++ = '\0'; - - /* actually set the darned thing */ - if (MPI_SUCCESS != MPI_Info_set(h5_io_info_g, namep, valp)) { - printf("MPI_Info_set failed\n"); - ret_value = -1; - } - } - - valp = next; - HDfree(key_val); - } while (next && *next); - - HDfree(envp); - } - - return ret_value; -} - - -void -h5_dump_info_object(MPI_Info info) -{ - char key[MPI_MAX_INFO_KEY+1]; - char value[MPI_MAX_INFO_VAL+1]; - int flag; - int i, nkeys; - - printf("Dumping MPI Info Object(%d) (up to %d bytes per item):\n", (int)info, - MPI_MAX_INFO_VAL); - if (info==MPI_INFO_NULL){ - printf("object is MPI_INFO_NULL\n"); - } - else { - MPI_Info_get_nkeys(info, &nkeys); - printf("object has %d items\n", nkeys); - for (i=0; i<nkeys; i++){ - MPI_Info_get_nthkey(info, i, key); - MPI_Info_get(info, key, MPI_MAX_INFO_VAL, value, &flag); - printf("%s=%s\n", key, value); - } - - } -} diff --git a/tools/perform/pio_standalone.h b/tools/perform/pio_standalone.h deleted file mode 100644 index f088c93..0000000 --- a/tools/perform/pio_standalone.h +++ /dev/null @@ -1,530 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef PIO_STANDALONE_H__ -#define PIO_PERF_H__ - -/* Header file for building h5perf by standalone mode. - * Created: Christian Chilan, 2005/5/18. - */ - -/** From H5private.h **/ - -#include "H5public.h" /* Include Public Definitions */ - - -/* - * Include ANSI-C header files. - */ -#ifdef H5_STDC_HEADERS -# include <assert.h> -# include <ctype.h> -# include <errno.h> -# include <fcntl.h> -# include <float.h> -# include <limits.h> -# include <math.h> -# include <signal.h> -# include <stdarg.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -#endif - -/* - * Redefine all the POSIX functions. We should never see a POSIX - * function (or any other non-HDF5 function) in the source! - */ -#define HDabort() abort() -#define HDabs(X) abs(X) -#ifdef H5_HAVE_WIN32_API -#define HDaccess(F,M) _access(F, M) -#define R_OK 4 /* Test for read permission. */ -#define W_OK 2 /* Test for write permission. */ -#define X_OK 1 /* Test for execute permission. */ -#define F_OK 0 /* Test for existence. */ -#else /* H5_HAVE_WIN32_API */ -#define HDaccess(F,M) access(F, M) -#ifndef F_OK -#define F_OK 00 -#define W_OK 02 -#define R_OK 04 -#endif -#endif /* H5_HAVE_WIN32_API */ -#define HDacos(X) acos(X) -#ifdef H5_HAVE_ALARM -#define HDalarm(N) alarm(N) -#else /* H5_HAVE_ALARM */ -#define HDalarm(N) (0) -#endif /* H5_HAVE_ALARM */ -#define HDasctime(T) asctime(T) -#define HDasin(X) asin(X) -#define HDasprintf asprintf /*varargs*/ -#define HDassert(X) assert(X) -#define HDatan(X) atan(X) -#define HDatan2(X,Y) atan2(X,Y) -#define HDatexit(F) atexit(F) -#define HDatof(S) atof(S) -#define HDatoi(S) atoi(S) -#define HDatol(S) atol(S) -#define HDbsearch(K,B,N,Z,F) bsearch(K,B,N,Z,F) -#define HDcalloc(N,Z) calloc(N,Z) -#define HDceil(X) ceil(X) -#define HDcfgetispeed(T) cfgetispeed(T) -#define HDcfgetospeed(T) cfgetospeed(T) -#define HDcfsetispeed(T,S) cfsetispeed(T,S) -#define HDcfsetospeed(T,S) cfsetospeed(T,S) -#define HDchdir(S) chdir(S) -#define HDchmod(S,M) chmod(S,M) -#define HDchown(S,O,G) chown(S,O,G) -#define HDclearerr(F) clearerr(F) -#define HDclock() clock() -#define HDclose(F) close(F) -#define HDclosedir(D) closedir(D) -#define HDcos(X) cos(X) -#define HDcosh(X) cosh(X) -#define HDcreat(S,M) creat(S,M) -#define HDctermid(S) ctermid(S) -#define HDctime(T) ctime(T) -#define HDcuserid(S) cuserid(S) -#ifdef H5_HAVE_DIFFTIME -#define HDdifftime(X,Y) difftime(X,Y) -#else -#define HDdifftime(X,Y) ((double)(X)-(double)(Y)) -#endif -#define HDdiv(X,Y) div(X,Y) -#define HDdup(F) dup(F) -#define HDdup2(F,I) dup2(F,I) -/* execl() variable arguments */ -/* execle() variable arguments */ -/* execlp() variable arguments */ -#define HDexecv(S,AV) execv(S,AV) -#define HDexecve(S,AV,E) execve(S,AV,E) -#define HDexecvp(S,AV) execvp(S,AV) -#define HDexit(N) exit(N) -#define HD_exit(N) _exit(N) -#define HDexp(X) exp(X) -#define HDfabs(X) fabs(X) -/* use ABS() because fabsf() fabsl() are not common yet. */ -#define HDfabsf(X) ABS(X) -#define HDfabsl(X) ABS(X) -#define HDfclose(F) fclose(F) -/* fcntl() variable arguments */ -#define HDfdopen(N,S) fdopen(N,S) -#define HDfeof(F) feof(F) -#define HDferror(F) ferror(F) -#define HDfflush(F) fflush(F) -#define HDfgetc(F) fgetc(F) -#define HDfgetpos(F,P) fgetpos(F,P) -#define HDfgets(S,N,F) fgets(S,N,F) -#ifdef H5_HAVE_WIN32_API -#define HDfileno(F) _fileno(F) -#else /* H5_HAVE_WIN32_API */ -#define HDfileno(F) fileno(F) -#endif /* H5_HAVE_WIN32_API */ -#define HDfloor(X) floor(X) -#define HDfmod(X,Y) fmod(X,Y) -#define HDfopen(S,M) fopen(S,M) -#define HDfork() fork() -#define HDfpathconf(F,N) fpathconf(F,N) -H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...); -#define HDfputc(C,F) fputc(C,F) -#define HDfputs(S,F) fputs(S,F) -#define HDfread(M,Z,N,F) fread(M,Z,N,F) -#define HDfree(M) free(M) -#define HDfreopen(S,M,F) freopen(S,M,F) -#define HDfrexp(X,N) frexp(X,N) -/* Check for Cray-specific 'frexpf()' and 'frexpl()' routines */ -#ifdef H5_HAVE_FREXPF -#define HDfrexpf(X,N) frexpf(X,N) -#else /* H5_HAVE_FREXPF */ -#define HDfrexpf(X,N) frexp(X,N) -#endif /* H5_HAVE_FREXPF */ -#ifdef H5_HAVE_FREXPL -#define HDfrexpl(X,N) frexpl(X,N) -#else /* H5_HAVE_FREXPL */ -#define HDfrexpl(X,N) frexp(X,N) -#endif /* H5_HAVE_FREXPL */ -/* fscanf() variable arguments */ -#ifdef H5_HAVE_FSEEKO - #define HDfseek(F,O,W) fseeko(F,O,W) -#else - #define HDfseek(F,O,W) fseek(F,O,W) -#endif -#define HDfsetpos(F,P) fsetpos(F,P) -/* definitions related to the file stat utilities. - * Windows have its own function names. - * For Unix, if off_t is not 64bit big, try use the pseudo-standard - * xxx64 versions if available. - */ -#ifdef H5_HAVE_WIN32_API - #define HDfstat(F,B) _fstati64(F,B) - #define HDlstat(S,B) _lstati64(S,B) - #define HDstat(S,B) _stati64(S,B) - typedef struct _stati64 h5_stat_t; - typedef __int64 h5_stat_size_t; - #define HDoff_t __int64 -#elif H5_SIZEOF_OFF_T!=8 && H5_SIZEOF_OFF64_T==8 && defined(H5_HAVE_STAT64) - #define HDfstat(F,B) fstat64(F,B) - #define HDlstat(S,B) lstat64(S,B) - #define HDstat(S,B) stat64(S,B) - typedef struct stat64 h5_stat_t; - typedef off64_t h5_stat_size_t; - #define HDoff_t off64_t -#else - #define HDfstat(F,B) fstat(F,B) - #define HDlstat(S,B) lstat(S,B) - #define HDstat(S,B) stat(S,B) - typedef struct stat h5_stat_t; - typedef off_t h5_stat_size_t; - #define HDoff_t off_t -#endif - -#ifndef H5_HAVE_WIN32_API -/* These definitions differ in Windows and are defined in - * H5win32defs for that platform. - */ -typedef struct stat h5_stat_t; -typedef off_t h5_stat_size_t; -#define HDoff_t off_t -#endif /* H5_HAVE_WIN32_API */ - -#define HDftell(F) ftell(F) -#define HDftruncate(F,L) ftruncate(F,L) -#define HDfwrite(M,Z,N,F) fwrite(M,Z,N,F) -#define HDgetc(F) getc(F) -#define HDgetchar() getchar() -#define HDgetcwd(S,Z) getcwd(S,Z) -#define HDgetegid() getegid() -#define HDgetenv(S) getenv(S) -#define HDgeteuid() geteuid() -#define HDgetgid() getgid() -#define HDgetgrgid(G) getgrgid(G) -#define HDgetgrnam(S) getgrnam(S) -#define HDgetgroups(Z,G) getgroups(Z,G) -#ifdef H5_HAVE_WIN32_API -#define HDgetlogin() Wgetlogin() -#else /* H5_HAVE_WIN32_API */ -#define HDgetlogin() getlogin() -#endif /* H5_HAVE_WIN32_API */ -#define HDgetpgrp() getpgrp() -#define HDgetpid() getpid() -#define HDgetppid() getppid() -#define HDgetpwnam(S) getpwnam(S) -#define HDgetpwuid(U) getpwuid(U) -#define HDgetrusage(X,S) getrusage(X,S) -#define HDgets(S) gets(S) -#ifdef H5_HAVE_WIN32_API - H5_DLL int Wgettimeofday(struct timeval *tv, struct timezone *tz); -#define HDgettimeofday(V,Z) Wgettimeofday(V,Z) -#else /* H5_HAVE_WIN32_API */ -#define HDgettimeofday(S,P) gettimeofday(S,P) -#endif /* H5_HAVE_WIN32_API */ -#define HDgetuid() getuid() -#define HDgmtime(T) gmtime(T) -#define HDisalnum(C) isalnum((int)(C)) /*cast for solaris warning*/ -#define HDisalpha(C) isalpha((int)(C)) /*cast for solaris warning*/ -#define HDisatty(F) isatty(F) -#define HDiscntrl(C) iscntrl((int)(C)) /*cast for solaris warning*/ -#define HDisdigit(C) isdigit((int)(C)) /*cast for solaris warning*/ -#define HDisgraph(C) isgraph((int)(C)) /*cast for solaris warning*/ -#define HDislower(C) islower((int)(C)) /*cast for solaris warning*/ -#define HDisprint(C) isprint((int)(C)) /*cast for solaris warning*/ -#define HDispunct(C) ispunct((int)(C)) /*cast for solaris warning*/ -#define HDisspace(C) isspace((int)(C)) /*cast for solaris warning*/ -#define HDisupper(C) isupper((int)(C)) /*cast for solaris warning*/ -#define HDisxdigit(C) isxdigit((int)(C)) /*cast for solaris warning*/ -#define HDkill(P,S) kill(P,S) -#define HDlabs(X) labs(X) -#define HDldexp(X,N) ldexp(X,N) -#define HDldiv(X,Y) ldiv(X,Y) -#define HDlink(OLD,NEW) link(OLD,NEW) -#define HDlocaleconv() localeconv() -#define HDlocaltime(T) localtime(T) -#define HDlog(X) log(X) -#define HDlog10(X) log10(X) -#define HDlongjmp(J,N) longjmp(J,N) -#ifdef H5_HAVE_WIN32_API - #define HDlseek(F,O,W) _lseeki64(F,O,W) -#else - #ifdef H5_HAVE_LSEEK64 - #define HDlseek(F,O,W) lseek64(F,O,W) - #else - #define HDlseek(F,O,W) lseek(F,O,W) - #endif -#endif -#define HDmalloc(Z) malloc(Z) -#define HDposix_memalign(P,A,Z) posix_memalign(P,A,Z) -#define HDmblen(S,N) mblen(S,N) -#define HDmbstowcs(P,S,Z) mbstowcs(P,S,Z) -#define HDmbtowc(P,S,Z) mbtowc(P,S,Z) -#define HDmemchr(S,C,Z) memchr(S,C,Z) -#define HDmemcmp(X,Y,Z) memcmp(X,Y,Z) -/* - * The (char*) casts are required for the DEC when optimizations are turned - * on and the source and/or destination are not aligned. - */ -#define HDmemcpy(X,Y,Z) memcpy((char*)(X),(const char*)(Y),Z) -#define HDmemmove(X,Y,Z) memmove((char*)(X),(const char*)(Y),Z) -/* - * The (void*) cast just avoids a compiler warning in H5_HAVE_VISUAL_STUDIO - */ -#ifdef H5_HAVE_VISUAL_STUDIO -#define HDmemset(X,C,Z) memset((void*)(X),C,Z) -#else /* H5_HAVE_VISUAL_STUDIO */ -#define HDmemset(X,C,Z) memset(X,C,Z) -#endif /* H5_HAVE_VISUAL_STUDIO */ -#ifdef H5_HAVE_WIN32_API -#define HDmkdir(S,M) _mkdir(S) -#else /* H5_HAVE_WIN32_API */ -#define HDmkdir(S,M) mkdir(S,M) -#endif /* H5_HAVE_WIN32_API */ -#define HDmkfifo(S,M) mkfifo(S,M) -#define HDmktime(T) mktime(T) -#define HDmodf(X,Y) modf(X,Y) -#ifdef _O_BINARY -#define HDopen(S,F,M) open(S,F|_O_BINARY,M) -#else -#define HDopen(S,F,M) open(S,F,M) -#endif -#define HDopendir(S) opendir(S) -#define HDpathconf(S,N) pathconf(S,N) -#define HDpause() pause() -#define HDperror(S) perror(S) -#define HDpipe(F) pipe(F) -#define HDpow(X,Y) pow(X,Y) -/* printf() variable arguments */ -#define HDputc(C,F) putc(C,F) -#define HDputchar(C) putchar(C) -#define HDputs(S) puts(S) -#define HDqsort(M,N,Z,F) qsort(M,N,Z,F) -#define HDraise(N) raise(N) - -#ifdef H5_HAVE_RAND_R -#define HDrandom() HDrand() -H5_DLL int HDrand(void); -#elif H5_HAVE_RANDOM -#define HDrand() random() -#define HDrandom() random() -#else -#define HDrand() rand() -#define HDrandom() rand() -#endif - -#define HDread(F,M,Z) read(F,M,Z) -#define HDreaddir(D) readdir(D) -#define HDrealloc(M,Z) realloc(M,Z) -#define HDremove(S) remove(S) -#define HDrename(OLD,NEW) rename(OLD,NEW) -#define HDrewind(F) rewind(F) -#define HDrewinddir(D) rewinddir(D) -#define HDrmdir(S) rmdir(S) -/* scanf() variable arguments */ -#define HDsetbuf(F,S) setbuf(F,S) -#define HDsetgid(G) setgid(G) -#define HDsetjmp(J) setjmp(J) -#define HDsetlocale(N,S) setlocale(N,S) -#define HDsetpgid(P,PG) setpgid(P,PG) -#define HDsetsid() setsid() -#define HDsetuid(U) setuid(U) -/* Windows does not permit setting the buffer size to values - less than 2. */ -#ifndef H5_HAVE_WIN32_API -#define HDsetvbuf(F,S,M,Z) setvbuf(F,S,M,Z) -#else -#define HDsetvbuf(F,S,M,Z) setvbuf(F,S,M,(Z>1?Z:2)) -#endif -#define HDsigaddset(S,N) sigaddset(S,N) -#define HDsigdelset(S,N) sigdelset(S,N) -#define HDsigemptyset(S) sigemptyset(S) -#define HDsigfillset(S) sigfillset(S) -#define HDsigismember(S,N) sigismember(S,N) -#define HDsiglongjmp(J,N) siglongjmp(J,N) -#define HDsignal(N,F) signal(N,F) -#define HDsigpending(S) sigpending(S) -#define HDsigprocmask(H,S,O) sigprocmask(H,S,O) -#define HDsigsetjmp(J,N) sigsetjmp(J,N) -#define HDsigsuspend(S) sigsuspend(S) -#define HDsin(X) sin(X) -#define HDsinh(X) sinh(X) -#define HDsleep(N) sleep(N) -#ifdef H5_HAVE_WIN32_API -H5_DLL int c99_snprintf(char* str, size_t size, const char* format, ...); -#define HDsnprintf c99_snprintf /*varargs*/ -#else -#define HDsnprintf snprintf /*varargs*/ -#endif -/* sprintf() variable arguments */ -#define HDsqrt(X) sqrt(X) -#ifdef H5_HAVE_RAND_R -H5_DLL void HDsrand(unsigned int seed); -#define HDsrandom(S) HDsrand(S) -#elif H5_HAVE_RANDOM -#define HDsrand(S) srandom(S) -#define HDsrandom(S) srandom(S) -#else -#define HDsrand(S) srand(S) -#define HDsrandom(S) srand(S) -#endif -/* sscanf() variable arguments */ - -#ifdef H5_HAVE_WIN32_API -#define HDstrcasecmp(A,B) _stricmp(A,B) -#else -#define HDstrcasecmp(X,Y) strcasecmp(X,Y) -#endif -#define HDstrcat(X,Y) strcat(X,Y) -#define HDstrchr(S,C) strchr(S,C) -#define HDstrcmp(X,Y) strcmp(X,Y) -#define HDstrcoll(X,Y) strcoll(X,Y) -#define HDstrcpy(X,Y) strcpy(X,Y) -#define HDstrcspn(X,Y) strcspn(X,Y) -#define HDstrerror(N) strerror(N) -#define HDstrftime(S,Z,F,T) strftime(S,Z,F,T) -#define HDstrlen(S) strlen(S) -#define HDstrncat(X,Y,Z) strncat(X,Y,Z) -#define HDstrncmp(X,Y,Z) strncmp(X,Y,Z) -#define HDstrncpy(X,Y,Z) strncpy(X,Y,Z) -#define HDstrpbrk(X,Y) strpbrk(X,Y) -#define HDstrrchr(S,C) strrchr(S,C) -#define HDstrspn(X,Y) strspn(X,Y) -#define HDstrstr(X,Y) strstr(X,Y) -#define HDstrtod(S,R) strtod(S,R) -#define HDstrtok(X,Y) strtok(X,Y) -#define HDstrtol(S,R,N) strtol(S,R,N) -H5_DLL int64_t HDstrtoll (const char *s, const char **rest, int base); -#define HDstrtoul(S,R,N) strtoul(S,R,N) -#ifdef H5_HAVE_WIN32_API -#define HDstrtoull(S,R,N) _strtoui64(S,R,N) -#else -#define HDstrtoull(S,R,N) strtoull(S,R,N) -#endif -#define HDstrxfrm(X,Y,Z) strxfrm(X,Y,Z) -#define HDsysconf(N) sysconf(N) -#define HDsystem(S) system(S) -#define HDtan(X) tan(X) -#define HDtanh(X) tanh(X) -#define HDtcdrain(F) tcdrain(F) -#define HDtcflow(F,A) tcflow(F,A) -#define HDtcflush(F,N) tcflush(F,N) -#define HDtcgetattr(F,T) tcgetattr(F,T) -#define HDtcgetpgrp(F) tcgetpgrp(F) -#define HDtcsendbreak(F,N) tcsendbreak(F,N) -#define HDtcsetattr(F,O,T) tcsetattr(F,O,T) -#define HDtcsetpgrp(F,N) tcsetpgrp(F,N) -#define HDtime(T) time(T) -#define HDtimes(T) times(T) -#define HDtmpfile() tmpfile() -#define HDtmpnam(S) tmpnam(S) -#define HDtolower(C) tolower(C) -#define HDtoupper(C) toupper(C) -#define HDttyname(F) ttyname(F) -#define HDtzset() tzset() -#define HDumask(N) umask(N) -#define HDuname(S) uname(S) -#define HDungetc(C,F) ungetc(C,F) -#ifdef H5_HAVE_WIN32_API -#define HDunlink(S) _unlink(S) -#else -#define HDunlink(S) unlink(S) -#endif -#define HDutime(S,T) utime(S,T) -#define HDva_arg(A,T) va_arg(A,T) -#define HDva_end(A) va_end(A) -#define HDva_start(A,P) va_start(A,P) -#define HDvasprintf(RET,FMT,A) vasprintf(RET,FMT,A) -#define HDvfprintf(F,FMT,A) vfprintf(F,FMT,A) -#define HDvprintf(FMT,A) vprintf(FMT,A) -#define HDvsprintf(S,FMT,A) vsprintf(S,FMT,A) -#ifdef H5_HAVE_WIN32_API -H5_DLL int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap); -#define HDvsnprintf c99_vsnprintf -#else -# define HDvsnprintf(S,N,FMT,A) vsnprintf(S,N,FMT,A) -#endif -#define HDwait(W) wait(W) -#define HDwaitpid(P,W,O) waitpid(P,W,O) -#define HDwcstombs(S,P,Z) wcstombs(S,P,Z) -#define HDwctomb(S,C) wctomb(S,C) -#define HDwrite(F,M,Z) write(F,M,Z) - -/* - * And now for a couple non-Posix functions... Watch out for systems that - * define these in terms of macros. - */ -#ifdef H5_HAVE_WIN32_API -#define HDstrdup(S) _strdup(S) -#else /* H5_HAVE_WIN32_API */ - -#if !defined strdup && !defined H5_HAVE_STRDUP -extern char *strdup(const char *s); -#endif - -#define HDstrdup(S) strdup(S) - -#endif /* H5_HAVE_WIN32_API */ - -/* - * HDF Boolean type. - */ -#ifndef FALSE -# define FALSE false -#endif -#ifndef TRUE -# define TRUE true -#endif - -/** From h5test.h **/ - -#ifdef H5_HAVE_PARALLEL -extern MPI_Info h5_io_info_g; /* MPI INFO object for IO */ -#endif - -#ifdef H5_HAVE_PARALLEL -H5TEST_DLL int h5_set_info_object(void); -H5TEST_DLL void h5_dump_info_object(MPI_Info info); -#endif - - - -/** From h5tools_utils.h **/ - -extern int opt_err; /* getoption prints errors if this is on */ -extern int opt_ind; /* token pointer */ -extern const char *opt_arg; /* flag argument (or value) */ - - -enum { - no_arg = 0, /* doesn't take an argument */ - require_arg, /* requires an argument */ - optional_arg /* argument is optional */ -}; - - -typedef struct long_options { - const char *name; /* name of the long option */ - int has_arg; /* whether we should look for an arg */ - char shortval; /* the shortname equivalent of long arg - * this gets returned from get_option */ -} long_options; - -extern int get_option(int argc, const char **argv, const char *opt, - const struct long_options *l_opt); - -extern int nCols; /*max number of columns for outputting */ - -/* Definitions of useful routines */ -extern void print_version(const char *progname); - -#endif diff --git a/tools/perform/sio_engine.c b/tools/perform/sio_engine.c deleted file mode 100644 index abf1fa6..0000000 --- a/tools/perform/sio_engine.c +++ /dev/null @@ -1,1313 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Author: Christian Chilan, April 2008 - */ - -#include "hdf5.h" - -#ifdef H5_STDC_HEADERS -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#endif - -#ifdef H5_HAVE_UNISTD_H -#include <sys/types.h> -#include <unistd.h> -#endif - -#ifdef H5_HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#include "sio_perf.h" - -/* Macro definitions */ - -/* sizes of various items. these sizes won't change during program execution */ -#define ELMT_H5_TYPE H5T_NATIVE_UCHAR - -#define GOTOERROR(errcode) { ret_code = errcode; goto done; } -#define ERRMSG(mesg) { \ - fprintf(stderr, "*** Assertion failed (%s) at line %4d in %s\n", \ - mesg, (int)__LINE__, __FILE__); \ -} - -/* verify: if val is false (0), print mesg. */ -#define VRFY(val, mesg) do { \ - if (!val) { \ - ERRMSG(mesg); \ - GOTOERROR(FAIL); \ - } \ -} while(0) - -/* POSIX I/O macros */ -#define POSIXCREATE(fn) HDopen(fn, O_CREAT|O_TRUNC|O_RDWR, 0600) -#define POSIXOPEN(fn, F) HDopen(fn, F, 0600) -#define POSIXCLOSE(F) HDclose(F) -#define POSIXSEEK(F,L) HDlseek(F, L, SEEK_SET) -#define POSIXWRITE(F,B,S) HDwrite(F,B,S) -#define POSIXREAD(F,B,S) HDread(F,B,S) - -enum { - SIO_CREATE = 1, - SIO_WRITE = 2, - SIO_READ = 4 -}; - -/* Global variables */ -static int clean_file_g = -1; /*whether to cleanup temporary test */ -/*files. -1 is not defined; */ -/*0 is no cleanup; 1 is do cleanup */ - -/* the different types of file descriptors we can expect */ -typedef union _file_descr { - int posixfd; /* POSIX file handle*/ - hid_t h5fd; /* HDF5 file */ -} file_descr; - -/* local functions */ -static char *sio_create_filename(iotype iot, const char *base_name, - char *fullname, size_t size, parameters *param); -static herr_t do_write(results *res, file_descr *fd, parameters *parms, void *buffer); -static herr_t do_read(results *res, file_descr *fd, parameters *parms, void *buffer); -static herr_t dset_write(int local_dim, file_descr *fd, parameters *parms, void *buffer); -static herr_t posix_buffer_write(int local_dim, file_descr *fd, parameters *parms, void *buffer); -static herr_t dset_read(int localrank, file_descr *fd, parameters *parms, void *buffer, const char *buffer2); -static herr_t posix_buffer_read(int local_dim, file_descr *fd, parameters *parms, void *buffer); -static herr_t do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, - int flags); -hid_t set_vfd(parameters *param); -static herr_t do_fclose(iotype iot, file_descr *fd); -static void do_cleanupfile(iotype iot, char *fname); - -/* global variables */ -static HDoff_t offset[MAX_DIMS]; /* dataset size in bytes */ -static size_t buf_offset[MAX_DIMS]; /* dataset size in bytes */ -static int order[MAX_DIMS]; /* dimension access order */ -static size_t linear_buf_size; /* linear buffer size */ -static int cont_dim; /* lowest dimension for contiguous POSIX - access */ -static size_t cont_size; /* size of contiguous POSIX access */ -static hid_t fapl; /* file access list */ -static unsigned char *buf_p; /* buffer pointer */ -static const char *multi_letters = "msbrglo"; /* string for multi driver */ - -/* HDF5 global variables */ -static hsize_t h5count[MAX_DIMS]; /*selection count */ -static hssize_t h5offset[MAX_DIMS]; /* Selection offset within dataspace */ -static hid_t h5dset_space_id = -1; /*dataset space ID */ -static hid_t h5mem_space_id = -1; /*memory dataspace ID */ -static hid_t h5ds_id = -1; /*dataset handle */ -static hid_t h5dcpl = -1; /* Dataset creation property list */ -static hid_t h5dxpl = -1; /* Dataset transfer property list */ - -/* - * Function: do_sio - * Purpose: SIO Engine where IO are executed. - * Return: results - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -void -do_sio(parameters param, results *res) -{ - char *buffer = NULL; /*data buffer pointer */ - size_t buf_size[MAX_DIMS]; /* general buffer size in bytes */ - file_descr fd; /* file handles */ - iotype iot; /* API type */ - char base_name[256]; /* test file base name */ - /* return codes */ - herr_t ret_code = 0; /*return code */ - - char fname[FILENAME_MAX]; /* test file name */ - int i; - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - - /* Sanity check parameters */ - - /* IO type */ - iot = param.io_type; - - switch (iot) { - case POSIXIO: - fd.posixfd = -1; - res->timers = io_time_new(SYS_CLOCK); - break; - case HDF5: - fd.h5fd = -1; - res->timers = io_time_new(SYS_CLOCK); - break; - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - GOTOERROR(FAIL); - } - - linear_buf_size = 1; - - for (i=0; i<param.rank; i++){ - buf_size[i] = param.buf_size[i]; - order[i] = param.order[i]; - linear_buf_size *= buf_size[i]; - buf_offset[i] = 0; - offset[i] = 0; - - /* Validate transfer buffer size */ - if (param.buf_size[i]<=0) { - HDfprintf(stderr, - "Transfer buffer size[%d] (%zu) must be > 0\n", i,buf_size[i]); - GOTOERROR(FAIL); - } - - if ((param.dset_size[i]%param.buf_size[i])!=0) { - HDfprintf(stderr, - "Dataset size[%d] (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "trasfer buffer size[%d] (%zu)\n",param.rank, - (long long)param.dset_size[i], param.rank, param.buf_size[i]); - GOTOERROR(FAIL); - } - - } - - /* Allocate transfer buffer */ - if ((buffer = (char *)malloc(linear_buf_size)) == NULL){ - HDfprintf(stderr, "malloc for transfer buffer size (%zu) failed\n", linear_buf_size); - GOTOERROR(FAIL); - } - - if (sio_debug_level >= 4) - - /* output all of the times for all iterations */ - fprintf(output, "Timer details:\n"); - - /* - * Write performance measurement - */ - /* Open file for write */ - - HDstrcpy(base_name, "#sio_tmp"); - sio_create_filename(iot, base_name, fname, sizeof(fname), ¶m); - - if (sio_debug_level > 0) - HDfprintf(output, "data filename=%s\n", - fname); - - set_time(res->timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, SIO_CREATE | SIO_WRITE); - VRFY((hrc == SUCCESS), "do_fopen failed"); - - set_time(res->timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTART); - hrc = do_write(res, &fd, ¶m, buffer); - set_time(res->timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_write failed"); - - /* Close file for write */ - hrc = do_fclose(iot, &fd); - set_time(res->timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - - if (!param.h5_write_only) { - /* - * Read performance measurement - */ - - /* Open file for read */ - set_time(res->timers, HDF5_GROSS_READ_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, SIO_READ); - VRFY((hrc == SUCCESS), "do_fopen failed"); - - set_time(res->timers, HDF5_FINE_READ_FIXED_DIMS, TSTART); - hrc = do_read(res, &fd, ¶m, buffer); - set_time(res->timers, HDF5_FINE_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_read failed"); - - /* Close file for read */ - hrc = do_fclose(iot, &fd); - - set_time(res->timers, HDF5_GROSS_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - } - - do_cleanupfile(iot, fname); - -done: - /* clean up */ - /* release HDF5 objects */ - - /* close any opened files */ - /* no remove(fname) because that should have happened normally. */ - switch (iot) { - case POSIXIO: - if (fd.posixfd != -1) - hrc = do_fclose(iot, &fd); - break; - case HDF5: - if (fd.h5fd != -1) - hrc = do_fclose(iot, &fd); - break; - default: - /* unknown request */ - HDassert(0 && "Unknown IO type"); - break; - } - - /* release generic resources */ - if (buffer) - free(buffer); - - res->ret_code = ret_code; -} - -/* - * Function: sio_create_filename - * Purpose: Create a new filename to write to. Determine the correct - * suffix to append to the filename by the type of I/O we're - * doing. Also, place in the /tmp/{$USER,$LOGIN} directory if - * USER or LOGIN are specified in the environment. - * Return: Pointer to filename or NULL - * Programmer: Bill Wendling, 21. November 2001 - * Modifications: Support for file drivers. Christian Chilan, April, 2008 - */ - static char * -sio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size, parameters *param) -{ - const char *prefix, *suffix=""; - char *ptr, last = '\0'; - size_t i, j; - vfdtype vfd; - vfd = param->vfd; - - if (!base_name || !fullname || size < 1) - return NULL; - - memset(fullname, 0, size); - - switch (iot) { - case POSIXIO: - suffix = ".posix"; - break; - case HDF5: - suffix = ".h5"; - if (vfd == family) - suffix = "%05d.h5"; - else if (vfd == multi) - suffix = NULL; - break; - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - HDassert(0 && "Unknown IO type"); - break; - } - - /* First use the environment variable and then try the constant */ - prefix = HDgetenv("HDF5_PREFIX"); - -#ifdef HDF5_PREFIX - if (!prefix) - prefix = HDF5_PREFIX; -#endif /* HDF5_PREFIX */ - - /* Prepend the prefix value to the base name */ - if (prefix && *prefix) { - /* If the prefix specifies the HDF5_PREFIX directory, then - * default to using the "/tmp/$USER" or "/tmp/$LOGIN" - * directory instead. */ - register char *user, *login, *subdir; - - user = HDgetenv("USER"); - login = HDgetenv("LOGIN"); - subdir = (user ? user : login); - - if (subdir) { - for (i = 0; i < size-1 && prefix[i]; i++) - fullname[i] = prefix[i]; - - fullname[i++] = '/'; - - for (j = 0; i < size && subdir[j]; i++, j++) - fullname[i] = subdir[j]; - } else { - /* We didn't append the prefix yet */ - HDstrncpy(fullname, prefix, size); - fullname[size - 1] = '\0'; - } - - if ((HDstrlen(fullname) + HDstrlen(base_name) + 1) < size) { - /* Append the base_name with a slash first. Multiple slashes are - * handled below. */ - h5_stat_t buf; - - if (HDstat(fullname, &buf) < 0) - /* The directory doesn't exist just yet */ - if (HDmkdir(fullname, 0755) < 0 && errno != EEXIST) { - /* We couldn't make the "/tmp/${USER,LOGIN}" subdirectory. - * Default to PREFIX's original prefix value. */ - HDstrcpy(fullname, prefix); - } - - HDstrcat(fullname, "/"); - HDstrcat(fullname, base_name); - } else { - /* Buffer is too small */ - return NULL; - } - } else if (strlen(base_name) >= size) { - /* Buffer is too small */ - return NULL; - } else { - HDstrcpy(fullname, base_name); - } - - /* Append a suffix */ - if (suffix) { - if (HDstrlen(fullname) + HDstrlen(suffix) >= size) - return NULL; - - HDstrcat(fullname, suffix); - } - - /* Remove any double slashes in the filename */ - for (ptr = fullname, i = j = 0; ptr && (i < size); i++, ptr++) { - if (*ptr != '/' || last != '/') - fullname[j++] = *ptr; - - last = *ptr; - } - - return fullname; -} - -/* - * Function: do_write - * Purpose: Write the required amount of data to the file. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -static herr_t -do_write(results *res, file_descr *fd, parameters *parms, void *buffer) -{ - int ret_code = SUCCESS; - char dname[64]; - int i; - size_t u; - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[MAX_DIMS]; /*dataset dim sizes */ - hsize_t h5chunk[MAX_DIMS]; /*dataset dim sizes */ - hsize_t h5block[MAX_DIMS]; /*dataspace selection */ - hsize_t h5stride[MAX_DIMS]; /*selection stride */ - hsize_t h5start[MAX_DIMS]; /*selection start */ - hsize_t h5maxdims[MAX_DIMS]; - int rank; /*rank of dataset */ - - /* Prepare buffer for verifying data */ -/* if (parms->verify) - memset(buffer,1,linear_buf_size); */ - - buf_p=(unsigned char *)buffer; - - for(u = 0; u < linear_buf_size; u++) - buf_p[u] = u % 128; - - rank = parms->rank; - - for(i = 0; i < rank; i++) - h5offset[i] = offset[i] = 0; - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - - /* determine lowest dimension for contiguous POSIX access */ - cont_dim = rank; - - for (i=rank-1; i>=0; i--) { - if (parms->buf_size[i]==parms->dset_size[i]) - cont_dim = i; - else - break; - } - - /* determine size of the contiguous POSIX access */ - cont_size = (!cont_dim)? 1 : parms->buf_size[cont_dim-1]; - for (i=cont_dim; i<rank; i++) - cont_size *= parms->buf_size[i]; - - break; - - case HDF5: /* HDF5 setup */ - - for (i=0; i < rank; i++){ - h5dims[i] = parms->dset_size[i]; - h5start[i] = 0; - h5stride[i] = 1; - h5block[i] = 1; - h5count[i] = parms->buf_size[i]; - h5chunk[i] = parms->chk_size[i]; - h5maxdims[i] = H5S_UNLIMITED; - - } - - if (parms->h5_use_chunks && parms->h5_extendable) { - h5dset_space_id = H5Screate_simple(rank, h5count, h5maxdims); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - } - else { - h5dset_space_id = H5Screate_simple(rank, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - } - - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, - h5start, h5stride, h5count, h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - - /* Create the memory dataspace that corresponds to the xfer buffer */ - h5mem_space_id = H5Screate_simple(rank, h5count, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - fprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - break; - - default: - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } /* end switch */ - - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - break; - - case HDF5: - h5dcpl = H5Pcreate(H5P_DATASET_CREATE); - - if (h5dcpl < 0) { - fprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - if(parms->h5_use_chunks) { - /* Set the chunk size to be the same as the buffer size */ - hrc = H5Pset_chunk(h5dcpl, rank, h5chunk); - if (hrc < 0) { - fprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - - sprintf(dname, "Dataset_%ld", (unsigned long)parms->num_bytes); - h5ds_id = H5Dcreate2(fd->h5fd, dname, ELMT_H5_TYPE, - h5dset_space_id, H5P_DEFAULT, h5dcpl, H5P_DEFAULT); - - if (h5ds_id < 0) { - HDfprintf(stderr, "HDF5 Dataset Create failed\n"); - GOTOERROR(FAIL); - } - - hrc = H5Pclose(h5dcpl); - /* verifying the close of the dcpl */ - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Close failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } - - /* Start "raw data" write timer */ - set_time(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTART); - - /* Perform write */ - hrc = dset_write(rank-1, fd, parms, buffer); - - if (hrc < 0) { - fprintf(stderr, "Error in dataset write\n"); - GOTOERROR(FAIL); - } - - - /* Stop "raw data" write timer */ - set_time(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTOP); - - /* Calculate write time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == HDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - fprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = -1; - } /* end if */ - -done: - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0){ - fprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } else { - h5dset_space_id = -1; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - fprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } else { - h5mem_space_id = -1; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - fprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } else { - h5dxpl = -1; - } - } - - return ret_code; -} - -/* - * Function: dset_write - * Purpose: Write buffer into the dataset. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -static herr_t -dset_write(int local_dim, file_descr *fd, parameters *parms, void *buffer) -{ - int cur_dim = order[local_dim]-1; - int ret_code = SUCCESS; - int k; - hsize_t dims[MAX_DIMS], maxdims[MAX_DIMS]; - hsize_t i; - int j; - herr_t hrc; - - /* iterates according to the dimensions in order array */ - for (i=0; i < parms->dset_size[cur_dim]; i += parms->buf_size[cur_dim]){ - - h5offset[cur_dim] = (hssize_t)i; - offset[cur_dim] = (HDoff_t)i; - - if (local_dim > 0){ - - dset_write(local_dim-1, fd, parms, buffer); - - }else{ - - switch (parms->io_type) { - - case POSIXIO: - /* initialize POSIX offset in the buffer */ - for(j = 0; j < parms->rank; j++) - buf_offset[j] = 0; - buf_p = (unsigned char *)buffer; - /* write POSIX buffer */ - posix_buffer_write(0, fd, parms, buffer); - break; - - case HDF5: - /* if dimensions are extendable, extend them as needed during access */ - if (parms->h5_use_chunks && parms->h5_extendable) { - - hrc=H5Sget_simple_extent_dims(h5dset_space_id,dims,maxdims); - VRFY((hrc >= 0), "H5Sget_simple_extent_dims"); - - for (k=0; k < parms->rank; k++){ - - HDassert(h5offset[k] >= 0); - if (dims[k] <= (hsize_t)h5offset[k]) { - dims[k] = dims[k]+h5count[k]; - hrc=H5Sset_extent_simple(h5dset_space_id,parms->rank,dims,maxdims); - VRFY((hrc >= 0), "H5Sset_extent_simple"); - hrc=H5Dset_extent(h5ds_id,dims); - VRFY((hrc >= 0), "H5Dextend"); - } - } - } - /* applies offset */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc=H5Sget_simple_extent_dims(h5dset_space_id,dims,maxdims); - hrc = H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, - h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dwrite"); - - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - HDassert(0 && "Unknown IO type"); - break; - } /* switch (parms->io_type) */ - } - } -done: - return ret_code; -} - -/* - * Function: posix_buffer_write - * Purpose: Write buffer into the POSIX file considering contiguity. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -static herr_t -posix_buffer_write(int local_dim, file_descr *fd, parameters *parms, void *buffer) -{ - int ret_code = SUCCESS; - - /* if dimension is not contiguous, call recursively */ - if (local_dim < parms->rank-1 && local_dim != cont_dim) { - size_t u; - - for(u = 0; u < parms->buf_size[local_dim]; u ++) { - buf_offset[local_dim] = u; - posix_buffer_write(local_dim+1, fd, parms, buffer); - - /* if next dimension is cont_dim, it will fill out the buffer - traversing the entire dimension local_dim without the need - of performing iteration */ - if (local_dim+1==cont_dim) - break; - } - /* otherwise, perform contiguous POSIX access */ - } else { - HDoff_t d_offset; - HDoff_t linear_dset_offset = 0; - int i, j, rc; - - buf_offset[local_dim] = 0; - - /* determine offset in the buffer */ - for(i = 0; i < parms->rank; i++) { - d_offset = 1; - - for(j = i + 1; j < parms->rank; j++) - d_offset *= (HDoff_t)parms->dset_size[j]; - - linear_dset_offset += (offset[i] + (HDoff_t)buf_offset[i]) * d_offset; - } - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, linear_dset_offset) < 0 ? -1 : 0; - VRFY((rc==0), "POSIXSEEK"); - /* check if all bytes are written */ - rc = ((ssize_t)cont_size == - POSIXWRITE(fd->posixfd, buf_p, cont_size)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance location in buffer */ - buf_p += cont_size; - - } - -done: - return ret_code; -} - -/* - * Function: do_read - * Purpose: Read the required amount of data to the file. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -static herr_t -do_read(results *res, file_descr *fd, parameters *parms, void *buffer) -{ - char *buffer2 = NULL; /* Buffer for data verification */ - int ret_code = SUCCESS; - char dname[64]; - int i; - size_t u; - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[MAX_DIMS]; /*dataset dim sizes */ - hsize_t h5block[MAX_DIMS]; /*dataspace selection */ - hsize_t h5stride[MAX_DIMS]; /*selection stride */ - hsize_t h5start[MAX_DIMS]; /*selection start */ - int rank; - - /* Allocate data verification buffer */ - if(NULL == (buffer2 = (char *)malloc(linear_buf_size))) { - HDfprintf(stderr, "malloc for data verification buffer size (%Zu) failed\n", linear_buf_size); - GOTOERROR(FAIL); - } /* end if */ - - /* Prepare buffer for verifying data */ - for(u = 0; u < linear_buf_size; u++) - buffer2[u] = (char)(u % 128); - - rank = parms->rank; - for(i = 0; i < rank; i++) - h5offset[i] = offset[i] = 0; - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - cont_dim = rank; - - for (i=rank-1; i>=0; i--) { - if (parms->buf_size[i]==parms->dset_size[i]) - cont_dim = i; - else - break; - } - cont_size = (!cont_dim)? 1 : parms->buf_size[cont_dim-1]; - for (i=cont_dim; i<rank; i++) - cont_size *= parms->buf_size[i]; - - break; - - case HDF5: /* HDF5 setup */ - for (i=0; i < rank; i++){ - h5dims[i] = parms->dset_size[i]; - h5start[i] = 0; - h5stride[i] = 1; - h5block[i] = 1; - h5count[i] = parms->buf_size[i]; - } - - h5dset_space_id = H5Screate_simple(rank, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, - h5start, h5stride, h5count, h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - - /* Create the memory dataspace that corresponds to the xfer buffer */ - h5mem_space_id = H5Screate_simple(rank, h5count, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - fprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } /* end switch */ - - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - break; - - case HDF5: - sprintf(dname, "Dataset_%ld", (long)parms->num_bytes); - h5ds_id = H5Dopen2(fd->h5fd, dname, H5P_DEFAULT); - if (h5ds_id < 0) { - HDfprintf(stderr, "HDF5 Dataset open failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } /* end switch */ - - /* Start "raw data" read timer */ - set_time(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTART); - hrc = dset_read(rank-1, fd, parms, buffer, buffer2); - - if (hrc < 0) { - fprintf(stderr, "Error in dataset read\n"); - GOTOERROR(FAIL); - } - - /* Stop "raw data" read timer */ - set_time(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTOP); - - /* Calculate read time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == HDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - fprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = -1; - } /* end if */ - -done: - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0){ - fprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } else { - h5dset_space_id = -1; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - fprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } else { - h5mem_space_id = -1; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - fprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } else { - h5dxpl = -1; - } - } - - /* release generic resources */ - if(buffer2) - free(buffer2); - - return ret_code; -} - -/* - * Function: dset_read - * Purpose: Read buffer into the dataset. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -static herr_t -dset_read(int local_dim, file_descr *fd, parameters *parms, void *buffer, - const char *buffer2) -{ - int cur_dim = order[local_dim]-1; - hsize_t i; - int j; - herr_t hrc; - int ret_code = SUCCESS; - - /* iterate on the current dimension */ - for (i=0; i < parms->dset_size[cur_dim]; i += parms->buf_size[cur_dim]){ - - h5offset[cur_dim] = (hssize_t)i; - offset[cur_dim] = (HDoff_t)i; - - /* if traverse in order array is incomplete, recurse */ - if (local_dim > 0){ - - ret_code = dset_read(local_dim-1, fd, parms, buffer, buffer2); - - /* otherwise, write buffer into dataset */ - }else{ - - switch (parms->io_type) { - - case POSIXIO: - for (j=0; j<parms->rank; j++) { - buf_offset[j] = 0; - } - buf_p = (unsigned char*)buffer; - posix_buffer_read(0, fd, parms, buffer); - break; - - case HDF5: - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - /* Read the buffer out */ - hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, - h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dread"); - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - HDassert(0 && "Unknown IO type"); - break; - } /* switch (parms->io_type) */ - } - } -done: - return ret_code; -} - -/* - * Function: posix_buffer_read - * Purpose: Read buffer into the POSIX file considering contiguity. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -static herr_t -posix_buffer_read(int local_dim, file_descr *fd, parameters *parms, void *buffer) -{ - int ret_code = SUCCESS; - - /* if local dimension is not contiguous, recurse */ - if (local_dim < parms->rank-1 && local_dim != cont_dim) { - size_t u; - - for(u = 0; u < parms->buf_size[local_dim]; u++) { - buf_offset[local_dim] = u; - ret_code = posix_buffer_read(local_dim+1, fd, parms, buffer); - if (local_dim+1==cont_dim) - break; - } - /* otherwise, perform contiguous POSIX access */ - } else { - HDoff_t d_offset; - HDoff_t linear_dset_offset = 0; - int i, j, rc; - - buf_offset[local_dim] = 0; - /* determine offset in buffer */ - for (i=0; i<parms->rank; i++){ - d_offset=1; - - for (j=i+1; j<parms->rank; j++) - d_offset *= (HDoff_t)parms->dset_size[j]; - - linear_dset_offset += (offset[i] + (HDoff_t)buf_offset[i]) * d_offset; - } - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, linear_dset_offset) < 0 ? -1 : 0; - VRFY((rc==0), "POSIXSEEK"); - /* check if all bytes are read */ - rc = ((ssize_t)cont_size == - POSIXREAD(fd->posixfd, buf_p, cont_size)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance location in buffer */ - buf_p += cont_size; - - } -done: - return ret_code; -} - - -/* - * Function: do_fopen - * Purpose: Open the specified file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: Support for file drivers, Christian Chilan, April, 2008 - */ - static herr_t -do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags) -{ - int ret_code = SUCCESS; - - switch (param->io_type) { - case POSIXIO: - if (flags & (SIO_CREATE | SIO_WRITE)) - fd->posixfd = POSIXCREATE(fname); - else - fd->posixfd = POSIXOPEN(fname, O_RDONLY); - - if (fd->posixfd < 0 ) { - HDfprintf(stderr, "POSIX File Open failed(%s)\n", fname); - GOTOERROR(FAIL); - } - - break; - - case HDF5: - - fapl = set_vfd(param); - - if (fapl < 0) { - fprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - /* create the parallel file */ - if (flags & (SIO_CREATE | SIO_WRITE)) { - fd->h5fd = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); - } else { - fd->h5fd = H5Fopen(fname, H5F_ACC_RDONLY, fapl); - } - - - if (fd->h5fd < 0) { - fprintf(stderr, "HDF5 File Create failed(%s)\n", fname); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)param->io_type); - GOTOERROR(FAIL); - break; - } - -done: - return ret_code; -} - -/* - * Function: set_vfd - * Purpose: Sets file driver. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -hid_t -set_vfd(parameters *param) -{ - hid_t my_fapl = -1; - vfdtype vfd; - - vfd = param->vfd; - - if ((my_fapl=H5Pcreate(H5P_FILE_ACCESS))<0) return -1; - - if (vfd == sec2) { - /* Unix read() and write() system calls */ - if (H5Pset_fapl_sec2(my_fapl)<0) return -1; - } else if (vfd == stdio) { - /* Standard C fread() and fwrite() system calls */ - if (H5Pset_fapl_stdio(my_fapl)<0) return -1; - } else if (vfd == core) { - /* In-core temporary file with 1MB increment */ - if (H5Pset_fapl_core(my_fapl, (size_t)1024*1024, TRUE)<0) return -1; - } else if (vfd == split) { - /* Split meta data and raw data each using default driver */ - if (H5Pset_fapl_split(my_fapl, - "-m.h5", H5P_DEFAULT, - "-r.h5", H5P_DEFAULT)<0) - return -1; - } else if (vfd == multi) { - /* Multi-file driver, general case of the split driver */ - H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; - hid_t memb_fapl[H5FD_MEM_NTYPES]; - const char *memb_name[H5FD_MEM_NTYPES]; - char sv[H5FD_MEM_NTYPES][1024]; - haddr_t memb_addr[H5FD_MEM_NTYPES]; - H5FD_mem_t mt; - - HDmemset(memb_map, 0, sizeof memb_map); - HDmemset(memb_fapl, 0, sizeof memb_fapl); - HDmemset(memb_name, 0, sizeof memb_name); - HDmemset(memb_addr, 0, sizeof memb_addr); - - HDassert(HDstrlen(multi_letters)==H5FD_MEM_NTYPES); - for (mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,mt)) { - memb_fapl[mt] = H5P_DEFAULT; - sprintf(sv[mt], "%%s-%c.h5", multi_letters[mt]); - memb_name[mt] = sv[mt]; - memb_addr[mt] = (haddr_t)MAX(mt - 1,0) * (HADDR_MAX / 10); - } - - if (H5Pset_fapl_multi(my_fapl, memb_map, memb_fapl, memb_name, - memb_addr, FALSE)<0) { - return -1; - } - } else if (vfd == family) { - hsize_t fam_size = 1*1024*1024; /*100 MB*/ - - /* Family of files, each 1MB and using the default driver */ - /* if ((val=HDstrtok(NULL, " \t\n\r"))) - fam_size = (hsize_t)(HDstrtod(val, NULL) * 1024*1024); */ - if (H5Pset_fapl_family(my_fapl, fam_size, H5P_DEFAULT)<0) - return -1; - } else if (vfd == direct) { -#ifdef H5_HAVE_DIRECT - /* Linux direct read() and write() system calls. Set memory boundary, file block size, - * and copy buffer size to the default values. */ - if (H5Pset_fapl_direct(my_fapl, 1024, 4096, 8*4096)<0) return -1; -#endif - } else { - /* Unknown driver */ - return -1; - } - - return my_fapl; -} - -/* - * Function: do_fclose - * Purpose: Close the specified file descriptor. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - */ - static herr_t -do_fclose(iotype iot, file_descr *fd /*out*/) -{ - herr_t ret_code = SUCCESS, hrc; - int rc = 0; - - switch (iot) { - case POSIXIO: - rc = POSIXCLOSE(fd->posixfd); - - if (rc != 0){ - fprintf(stderr, "POSIX File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->posixfd = -1; - break; - - case HDF5: - hrc = H5Fclose(fd->h5fd); - - if (hrc < 0) { - fprintf(stderr, "HDF5 File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->h5fd = -1; - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - GOTOERROR(FAIL); - break; - } - -done: - return ret_code; -} - - -/* - * Function: do_cleanupfile - * Purpose: Cleanup temporary file unless HDF5_NOCLEANUP is set. - * Return: void - * Programmer: Albert Cheng 2001/12/12 - * Modifications: Support for file drivers. Christian Chilan, April, 2008 - */ - static void -do_cleanupfile(iotype iot, char *filename) -{ - char temp[2048]; - int j; - hid_t driver; - - if (clean_file_g == -1) - clean_file_g = (HDgetenv("HDF5_NOCLEANUP")==NULL) ? 1 : 0; - - if (clean_file_g){ - - switch (iot) { - case POSIXIO: - HDremove(filename); - break; - - case HDF5: - driver = H5Pget_driver(fapl); - - if (driver == H5FD_FAMILY) { - for (j = 0; /*void*/; j++) { - HDsnprintf(temp, sizeof temp, filename, j); - - if (HDaccess(temp, F_OK) < 0) - break; - - HDremove(temp); - } - } else if (driver == H5FD_CORE) { - hbool_t backing; /* Whether the core file has backing store */ - - H5Pget_fapl_core(fapl,NULL,&backing); - - /* If the file was stored to disk with bacing store, remove it */ - if(backing) - HDremove(filename); - - } else if (driver == H5FD_MULTI) { - H5FD_mem_t mt; - assert(HDstrlen(multi_letters)==H5FD_MEM_NTYPES); - - for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,mt)) { - HDsnprintf(temp, sizeof temp, "%s-%c.h5", - filename, multi_letters[mt]); - HDremove(temp); /*don't care if it fails*/ - } - } else { - HDremove(filename); - } - H5Pclose(fapl); - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - HDassert(0 && "Unknown IO type"); - break; - } - } -} - diff --git a/tools/perform/sio_perf.c b/tools/perform/sio_perf.c deleted file mode 100644 index aceccb0..0000000 --- a/tools/perform/sio_perf.c +++ /dev/null @@ -1,1412 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Serial HDF5 Performance Testing Code - * -------------------------------------- - * - * Portable code to test performance on the different platforms we support. - * This is what the report should look like: - * - * nprocs = Max#Procs - * IO API = POSIXIO - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * - * IO API = HDF5 - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * - * . . . - * - */ - -/* system header files */ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> - -#include "hdf5.h" - - -/* our header files */ -#include "sio_perf.h" - -/* useful macros */ -#define TAB_SPACE 4 - -#define ONE_KB 1024 -#define ONE_MB (ONE_KB * ONE_KB) -#define ONE_GB (ONE_MB * ONE_KB) - -#define SIO_POSIX 0x1 -#define SIO_HDF5 0x4 - -/* report 0.0 in case t is zero too */ -#define MB_PER_SEC(bytes,t) (H5_DBL_ABS_EQUAL(t, (double)0.0F) ? (double)0.0F : ((((double)bytes) / (double)ONE_MB) / (t))) - -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE (!TRUE) -#endif /* FALSE */ - -/* global variables */ -FILE *output; /* output file */ -int sio_debug_level = 0;/* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Maximal & then some - */ - -/* local variables */ -static const char *progname = "h5perf_serial"; - -/* - * Command-line options: The user can specify short or long-named - * parameters. The long-named ones can be partially spelled. When - * adding more, make sure that they don't clash with each other. - */ - -/* - * It seems that only the options that accept additional information - * such as dataset size (-e) require the colon next to it. - */ -#if 1 -static const char *s_opts = "a:A:B:c:Cd:D:e:F:ghi:Imno:p:P:r:stT:v:wx:X:"; -#else -static const char *s_opts = "a:A:bB:c:Cd:D:e:F:ghi:Imno:p:P:r:stT:wx:X:"; -#endif /* 1 */ -static struct long_options l_opts[] = { - { "align", require_arg, 'a' }, - { "alig", require_arg, 'a' }, - { "ali", require_arg, 'a' }, - { "al", require_arg, 'a' }, - { "api", require_arg, 'A' }, - { "ap", require_arg, 'A' }, -#if 0 - /* a sighting of the elusive binary option */ - { "binary", no_arg, 'b' }, - { "binar", no_arg, 'b' }, - { "bina", no_arg, 'b' }, - { "bin", no_arg, 'b' }, - { "bi", no_arg, 'b' }, -#endif /* 0 */ - { "block-size", require_arg, 'B' }, - { "block-siz", require_arg, 'B' }, - { "block-si", require_arg, 'B' }, - { "block-s", require_arg, 'B' }, - { "block-", require_arg, 'B' }, - { "block", require_arg, 'B' }, - { "bloc", require_arg, 'B' }, - { "blo", require_arg, 'B' }, - { "bl", require_arg, 'B' }, - { "chunk", no_arg, 'c' }, - { "chun", no_arg, 'c' }, - { "chu", no_arg, 'c' }, - { "ch", no_arg, 'c' }, - { "collective", no_arg, 'C' }, - { "collectiv", no_arg, 'C' }, - { "collecti", no_arg, 'C' }, - { "collect", no_arg, 'C' }, - { "collec", no_arg, 'C' }, - { "colle", no_arg, 'C' }, - { "coll", no_arg, 'C' }, - { "col", no_arg, 'C' }, - { "co", no_arg, 'C' }, - { "debug", require_arg, 'D' }, - { "debu", require_arg, 'D' }, - { "deb", require_arg, 'D' }, - { "de", require_arg, 'D' }, - { "file-driver", require_arg, 'v' }, - { "file-drive", require_arg, 'v' }, - { "file-driv", require_arg, 'v' }, - { "file-dri", require_arg, 'v' }, - { "file-dr", require_arg, 'v' }, - { "file-d", require_arg, 'v' }, - { "file-", require_arg, 'v' }, - { "file", require_arg, 'v' }, - { "fil", require_arg, 'v' }, - { "fi", require_arg, 'v' }, - { "geometry", no_arg, 'g' }, - { "geometr", no_arg, 'g' }, - { "geomet", no_arg, 'g' }, - { "geome", no_arg, 'g' }, - { "geom", no_arg, 'g' }, - { "geo", no_arg, 'g' }, - { "ge", no_arg, 'g' }, - { "help", no_arg, 'h' }, - { "hel", no_arg, 'h' }, - { "he", no_arg, 'h' }, - { "interleaved", require_arg, 'I' }, - { "interleave", require_arg, 'I' }, - { "interleav", require_arg, 'I' }, - { "interlea", require_arg, 'I' }, - { "interle", require_arg, 'I' }, - { "interl", require_arg, 'I' }, - { "inter", require_arg, 'I' }, - { "inte", require_arg, 'I' }, - { "int", require_arg, 'I' }, - { "in", require_arg, 'I' }, - { "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' }, - { "num-bytes", require_arg, 'e' }, - { "num-byte", require_arg, 'e' }, - { "num-byt", require_arg, 'e' }, - { "num-by", require_arg, 'e' }, - { "num-b", require_arg, 'e' }, - { "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' }, - { "order", require_arg, 'r' }, - { "orde", require_arg, 'r' }, - { "ord", require_arg, 'r' }, - { "or", require_arg, 'r' }, - { "output", require_arg, 'o' }, - { "outpu", require_arg, 'o' }, - { "outp", require_arg, 'o' }, - { "out", require_arg, 'o' }, - { "ou", require_arg, 'o' }, - { "extendable", no_arg, 't' }, - { "extendabl", no_arg, 't' }, - { "extendab", no_arg, 't' }, - { "extenda", no_arg, 't' }, - { "extend", no_arg, 't' }, - { "exten", no_arg, 't' }, - { "exte", no_arg, 't' }, - { "ext", no_arg, 't' }, - { "ex", no_arg, 't' }, - { "threshold", require_arg, 'T' }, - { "threshol", require_arg, 'T' }, - { "thresho", require_arg, 'T' }, - { "thresh", require_arg, 'T' }, - { "thres", require_arg, 'T' }, - { "thre", require_arg, 'T' }, - { "thr", require_arg, 'T' }, - { "th", require_arg, 'T' }, - { "write-only", require_arg, 'w' }, - { "write-onl", require_arg, 'w' }, - { "write-on", require_arg, 'w' }, - { "write-o", require_arg, 'w' }, - { "write", require_arg, 'w' }, - { "writ", require_arg, 'w' }, - { "wri", require_arg, 'w' }, - { "wr", require_arg, 'w' }, - { 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 num_dsets; /* number of datasets */ - long num_files; /* number of files */ - off_t num_bpp; /* number of bytes per proc per dset */ - int num_iters; /* number of iterations */ - hsize_t dset_size[MAX_DIMS]; /* Dataset size */ - size_t buf_size[MAX_DIMS]; /* Buffer size */ - size_t chk_size[MAX_DIMS]; /* Chunk size */ - int order[MAX_DIMS]; /* Dimension access order */ - int dset_rank; /* Rank */ - int buf_rank; /* Rank */ - int order_rank; /* Rank */ - int chk_rank; /* Rank */ - int print_times; /* print times as well as throughputs */ - int print_raw; /* print raw data throughput info */ - hsize_t h5_alignment; /* alignment in HDF5 file */ - hsize_t h5_threshold; /* threshold for alignment in HDF5 file */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int h5_extendable; /* Perform the write tests only */ - int verify; /* Verify data correctness */ - vfdtype vfd; /* File driver */ - -}; - -typedef struct _minmax { - double min; - double max; - double sum; - int num; -} minmax; - -/* local functions */ -static hsize_t parse_size_directive(const char *size); -static struct options *parse_command_line(int argc, char *argv[]); -static void run_test_loop(struct options *options); -static int run_test(iotype iot, parameters parms, struct options *opts); -static void output_all_info(minmax *mm, int count, int indent_level); -static void get_minmax(minmax *mm, double val); -static void accumulate_minmax_stuff(const minmax *mm, int count, minmax *total_mm); -static void output_results(const struct options *options, const char *name, - minmax *table, int table_size, off_t data_size); -static void output_report(const char *fmt, ...); -static void print_indent(register int indent); -static void usage(const char *prog); -static void report_parameters(struct options *opts); - -/* - * Function: main - * Purpose: Start things up. - * Return: EXIT_SUCCESS or EXIT_FAILURE - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - */ -int -main(int argc, char **argv) -{ - int exit_value = EXIT_SUCCESS; - struct options *opts = NULL; - -#ifndef STANDALONE - /* Initialize h5tools lib */ - h5tools_init(); -#endif - - output = stdout; - - opts = parse_command_line(argc, argv); - - if (!opts) { - exit_value = EXIT_FAILURE; - goto finish; - } - - if (opts->output_file) { - if ((output = HDfopen(opts->output_file, "w")) == NULL) { - fprintf(stderr, "%s: cannot open output file\n", progname); - perror(opts->output_file); - goto finish; - } - } - - report_parameters(opts); - - run_test_loop(opts); - -finish: - free(opts); - return exit_value; -} - -/* - * Function: run_test_loop - * Purpose: Run the I/O tests. Write the results to OUTPUT. - * - * - The slowest changing part of the test is the number of - * processors to use. For each loop iteration, we divide that - * number by 2 and rerun the test. - * - * - The second slowest is what type of IO API to perform. We have - * three choices: POSIXIO, and HDF5. - * - * - Then we change the size of the buffer. This information is - * inferred from the number of datasets to create and the number - * of integers to put into each dataset. The backend code figures - * this out. - * - * Return: Nothing - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - * Added multidimensional testing (Christian Chilan, April, 2008) - */ -static void -run_test_loop(struct options *opts) -{ - parameters parms; - int i; - size_t buf_bytes; - - /* load options into parameter structure */ - parms.num_files = opts->num_files; - parms.num_dsets = opts->num_dsets; - parms.num_iters = opts->num_iters; - parms.rank = opts->dset_rank; - parms.h5_align = opts->h5_alignment; - parms.h5_thresh = opts->h5_threshold; - parms.h5_use_chunks = opts->h5_use_chunks; - parms.h5_extendable = opts->h5_extendable; - parms.h5_write_only = opts->h5_write_only; - parms.verify = opts->verify; - parms.vfd = opts->vfd; - - /* load multidimensional options */ - parms.num_bytes = 1; - buf_bytes = 1; - for (i=0; i<parms.rank; i++){ - parms.buf_size[i] = opts->buf_size[i]; - parms.dset_size[i] = opts->dset_size[i]; - parms.chk_size[i] = opts->chk_size[i]; - parms.order[i] = opts->order[i]; - parms.num_bytes *= opts->dset_size[i]; - buf_bytes *= opts->buf_size[i]; - } - - /* print size information */ - output_report("Transfer Buffer Size (bytes): %d\n", buf_bytes); - output_report("File Size(MB): %.2f\n",((double)parms.num_bytes) / ONE_MB); - - print_indent(0); - if (opts->io_types & SIO_POSIX) - run_test(POSIXIO, parms, opts); - - print_indent(0); - if (opts->io_types & SIO_HDF5) - run_test(HDF5, parms, opts); -} - -/* - * Function: run_test - * Purpose: Inner loop call to actually run the I/O test. - * Return: Nothing - * Programmer: Bill Wendling, 18. December 2001 - * Modifications: - */ -static int -run_test(iotype iot, parameters parms, struct options *opts) -{ - results res; - register int i, ret_value = SUCCESS; - off_t raw_size; - minmax *write_sys_mm_table=NULL; - minmax *write_mm_table=NULL; - minmax *write_gross_mm_table=NULL; - minmax *write_raw_mm_table=NULL; - minmax *read_sys_mm_table=NULL; - minmax *read_mm_table=NULL; - minmax *read_gross_mm_table=NULL; - minmax *read_raw_mm_table=NULL; - minmax write_sys_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax write_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax write_gross_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax write_raw_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_sys_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_gross_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_raw_mm = {0.0F, 0.0F, 0.0F, 0}; - - raw_size = (off_t)parms.num_bytes; - parms.io_type = iot; - print_indent(2); - output_report("IO API = "); - - switch (iot) { - case POSIXIO: - output_report("POSIX\n"); - break; - case HDF5: - output_report("HDF5\n"); - break; - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - HDassert(0 && "Unknown IO tpe"); - break; - } - - /* allocate space for tables minmax and that it is sufficient */ - /* to initialize all elements to zeros by calloc. */ - write_sys_mm_table = (minmax *)calloc((size_t)parms.num_iters , sizeof(minmax)); - write_mm_table = (minmax *)calloc((size_t)parms.num_iters , sizeof(minmax)); - write_gross_mm_table = (minmax *)calloc((size_t)parms.num_iters , sizeof(minmax)); - write_raw_mm_table = (minmax *)calloc((size_t)parms.num_iters , sizeof(minmax)); - - if (!parms.h5_write_only) { - read_sys_mm_table = (minmax *)calloc((size_t)parms.num_iters , sizeof(minmax)); - read_mm_table = (minmax *)calloc((size_t)parms.num_iters , sizeof(minmax)); - read_gross_mm_table = (minmax *)calloc((size_t)parms.num_iters , sizeof(minmax)); - read_raw_mm_table = (minmax *)calloc((size_t)parms.num_iters , sizeof(minmax)); - } - - /* Do IO iteration times, collecting statistics each time */ - for (i = 0; i < parms.num_iters; ++i) { - double t; - - do_sio(parms, &res); - - /* gather all of the "sys write" times */ - t = get_time(res.timers, HDF5_MPI_WRITE); - get_minmax(&write_sys_mm, t); - - write_sys_mm_table[i] = write_sys_mm; - - /* gather all of the "write" times */ - t = get_time(res.timers, HDF5_FINE_WRITE_FIXED_DIMS); - get_minmax(&write_mm, t); - - write_mm_table[i] = write_mm; - - /* gather all of the "write" times from open to close */ - t = get_time(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS); - get_minmax(&write_gross_mm, t); - - write_gross_mm_table[i] = write_gross_mm; - - /* gather all of the raw "write" times */ - t = get_time(res.timers, HDF5_RAW_WRITE_FIXED_DIMS); - get_minmax(&write_raw_mm, t); - - write_raw_mm_table[i] = write_raw_mm; - - if (!parms.h5_write_only) { - /* gather all of the "mpi read" times */ - t = get_time(res.timers, HDF5_MPI_READ); - get_minmax(&read_sys_mm, t); - - read_sys_mm_table[i] = read_sys_mm; - - /* gather all of the "read" times */ - t = get_time(res.timers, HDF5_FINE_READ_FIXED_DIMS); - get_minmax(&read_mm, t); - - read_mm_table[i] = read_mm; - - /* gather all of the "read" times from open to close */ - t = get_time(res.timers, HDF5_GROSS_READ_FIXED_DIMS); - get_minmax(&read_gross_mm, t); - - read_gross_mm_table[i] = read_gross_mm; - - /* gather all of the raw "read" times */ - t = get_time(res.timers, HDF5_RAW_READ_FIXED_DIMS); - get_minmax(&read_raw_mm, t); - - read_raw_mm_table[i] = read_gross_mm; - } - io_time_destroy(res.timers); - } - - /* - * Show various statistics - */ - /* Write statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw write" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Write details:\n"); - output_all_info(write_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts,"Raw Data Write",write_raw_mm_table,parms.num_iters,raw_size); - } /* end if */ - - /* show sys write statics */ -#if 0 - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Write details:\n"); - output_all_info(write_sys_mm_table, parms.num_iters, 4); - } -#endif - /* We don't currently output the MPI write results */ - - /* accumulate and output the max, min, and average "write" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write details:\n"); - output_all_info(write_mm_table, parms.num_iters, 4); - } - - output_results(opts,"Write",write_mm_table,parms.num_iters,raw_size); - - /* accumulate and output the max, min, and average "gross write" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write Open-Close details:\n"); - output_all_info(write_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts,"Write Open-Close",write_gross_mm_table,parms.num_iters,raw_size); - - if (!parms.h5_write_only) { - /* Read statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw read" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Read details:\n"); - output_all_info(read_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Raw Data Read", read_raw_mm_table, - parms.num_iters, raw_size); - } /* end if */ - - /* show mpi read statics */ -#if 0 - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Read details:\n"); - output_all_info(read_sys_mm_table, parms.num_iters, 4); - } -#endif - /* We don't currently output the MPI read results */ - - /* accumulate and output the max, min, and average "read" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read details:\n"); - output_all_info(read_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read", read_mm_table, parms.num_iters, raw_size); - - /* accumulate and output the max, min, and average "gross read" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read Open-Close details:\n"); - output_all_info(read_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read Open-Close", read_gross_mm_table, - parms.num_iters, raw_size); - } - - /* clean up our mess */ - free(write_sys_mm_table); - free(write_mm_table); - free(write_gross_mm_table); - free(write_raw_mm_table); - - if (!parms.h5_write_only) { - free(read_sys_mm_table); - free(read_mm_table); - free(read_gross_mm_table); - free(read_raw_mm_table); - } - - return ret_value; -} - -/* - * Function: output_all_info - * Purpose: - * Return: Nothing - * Programmer: Bill Wendling, 29. January 2002 - * Modifications: - */ -static void -output_all_info(minmax *mm, int count, int indent_level) -{ - int i; - - for (i = 0; i < count; ++i) { - print_indent(indent_level); - output_report("Iteration %d:\n", i + 1); - print_indent(indent_level + 1); - output_report("Minimum Time: %.2fs\n", mm[i].min); - print_indent(indent_level + 1); - output_report("Maximum Time: %.2fs\n", mm[i].max); - } -} - -/* - * Function: get_minmax - * Purpose: Gather all the min, max and total of val. - * Return: Nothing - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Use MPI_Allreduce to do it. -akc, 2002/01/11 - */ - -static void -get_minmax(minmax *mm, double val) -{ - mm->max = val; - mm->min = val; - mm->sum = val; -} - -/* - * Function: accumulate_minmax_stuff - * Purpose: Accumulate the minimum, maximum, and average of the times - * across all processes. - * Return: TOTAL_MM - the total of all of these. - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Changed to use seconds instead of MB/s - QAK, 5/9/02 - */ -static void -accumulate_minmax_stuff(const minmax *mm, int count, minmax *total_mm) -{ - int i; - - total_mm->sum = 0.0F; - total_mm->max = -DBL_MAX; - total_mm->min = DBL_MAX; - total_mm->num = count; - - for (i = 0; i < count; ++i) { - double m = mm[i].max; - - total_mm->sum += m; - - if (m < total_mm->min) - total_mm->min = m; - - if (m > total_mm->max) - total_mm->max = m; - } -} - - -/* - * Function: output_results - * Purpose: Print information about the time & bandwidth for a given - * minmax & # of iterations. - * Return: Nothing - * Programmer: Quincey Koziol, 9. May 2002 - * Modifications: - */ -static void -output_results(const struct options *opts, const char *name, minmax *table, - int table_size,off_t data_size) -{ - minmax total_mm; - - accumulate_minmax_stuff(table, table_size, &total_mm); - - print_indent(3); - output_report("%s (%d iteration(s)):\n", name,table_size); - - /* Note: The maximum throughput uses the minimum amount of time & vice versa */ - - print_indent(4); - output_report("Maximum Throughput: %6.2f MB/s", MB_PER_SEC(data_size,total_mm.min)); - if(opts->print_times) - output_report(" (%7.3f s)\n", total_mm.min); - else - output_report("\n"); - - print_indent(4); - output_report("Average Throughput: %6.2f MB/s", - MB_PER_SEC(data_size,total_mm.sum / total_mm.num)); - if(opts->print_times) - output_report(" (%7.3f s)\n", (total_mm.sum / total_mm.num)); - else - output_report("\n"); - - print_indent(4); - output_report("Minimum Throughput: %6.2f MB/s", MB_PER_SEC(data_size,total_mm.max)); - if(opts->print_times) - output_report(" (%7.3f s)\n", total_mm.max); - else - output_report("\n"); -} - -/* - * Function: output_report - * Purpose: Print a line of the report. Only do so if I'm the 0 process. - * Return: Nothing - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static void -output_report(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vfprintf(output, fmt, ap); - va_end(ap); -} - -/* - * Function: print_indent - * Purpose: Print spaces to indent a new line of text for pretty printing - * things. - * Return: Nothing - * Programmer: Bill Wendling, 29. October 2001 - * Modifications: - */ -static void -print_indent(register int indent) -{ - indent *= TAB_SPACE; - - for (; indent > 0; --indent) - fputc(' ', output); -} - -static void -recover_size_and_print(long long val, const char *end) -{ - if (val >= ONE_KB && (val % ONE_KB) == 0) { - if (val >= ONE_MB && (val % ONE_MB) == 0) { - if (val >= ONE_GB && (val % ONE_GB) == 0) - HDfprintf(output, "%" H5_PRINTF_LL_WIDTH "d""GB%s", val / ONE_GB, end); - else - HDfprintf(output, "%" H5_PRINTF_LL_WIDTH "d""MB%s", val / ONE_MB, end); - } else { - HDfprintf(output, "%" H5_PRINTF_LL_WIDTH "d""KB%s", val / ONE_KB, end); - } - } else { - HDfprintf(output, "%" H5_PRINTF_LL_WIDTH "d""%s", val, end); - } -} - -static void -print_io_api(long io_types) -{ - if (io_types & SIO_POSIX) - HDfprintf(output, "posix "); - if (io_types & SIO_HDF5) - HDfprintf(output, "hdf5 "); - HDfprintf(output, "\n"); -} - -static void -report_parameters(struct options *opts) -{ - int i, rank; - rank = opts->dset_rank; - - print_version("HDF5 Library"); /* print library version */ - HDfprintf(output, "==== Parameters ====\n"); - - HDfprintf(output, "IO API="); - print_io_api(opts->io_types); - - HDfprintf(output, "Number of iterations=%d\n", - opts->num_iters); - - HDfprintf(output, "Dataset size="); - - for (i=0; i<rank; i++) - recover_size_and_print((long long)opts->dset_size[i], " "); - HDfprintf(output, "\n"); - - - HDfprintf(output, "Transfer buffer size="); - for (i=0; i<rank; i++) - recover_size_and_print((long long)opts->buf_size[i], " "); - HDfprintf(output, "\n"); - - HDfprintf(output, "Dimension access order="); - for (i=0; i<rank; i++) - recover_size_and_print((long long)opts->order[i], " "); - HDfprintf(output, "\n"); - - if (opts->io_types & SIO_HDF5) { - - HDfprintf(output, "HDF5 data storage method="); - - if (opts->h5_use_chunks){ - - HDfprintf(output, "Chunked\n"); - HDfprintf(output, "HDF5 chunk size="); - for (i=0; i<rank; i++) - recover_size_and_print((long long)opts->chk_size[i], " "); - HDfprintf(output, "\n"); - - HDfprintf(output, "HDF5 dataset dimensions="); - if (opts->h5_extendable) { - HDfprintf(output, "Extendable\n"); - } - else { - HDfprintf(output, "Fixed\n"); - } - } - else { - HDfprintf(output, "Contiguous\n"); - } - - HDfprintf(output, "HDF5 file driver="); - if (opts->vfd==sec2) { - HDfprintf(output, "sec2\n"); - } else if (opts->vfd==stdio) { - HDfprintf(output, "stdio\n"); - } else if (opts->vfd==core) { - HDfprintf(output, "core\n"); - } else if (opts->vfd==split) { - HDfprintf(output, "split\n"); - } else if (opts->vfd==multi) { - HDfprintf(output, "multi\n"); - } else if (opts->vfd==family) { - HDfprintf(output, "family\n"); - } else if (opts->vfd==direct) { - HDfprintf(output, "direct\n"); - } - } - - { - char *prefix = HDgetenv("HDF5_PREFIX"); - - HDfprintf(output, "Env HDF5_PREFIX=%s\n", - (prefix ? prefix : "not set")); - } - - HDfprintf(output, "==== End of Parameters ====\n"); - HDfprintf(output, "\n"); -} - -/* - * Function: parse_command_line - * Purpose: Parse the command line options and return a STRUCT OPTIONS - * structure which will need to be freed by the calling function. - * Return: Pointer to an OPTIONS structure - * Programmer: Bill Wendling, 31. October 2001 - * Modifications: - * Added multidimensional testing (Christian Chilan, April, 2008) - */ -static struct options * -parse_command_line(int argc, char *argv[]) -{ - int opt; - struct options *cl_opts; - int i, default_rank, actual_rank, ranks[4]; - - cl_opts = (struct options *)HDmalloc(sizeof(struct options)); - - cl_opts->output_file = NULL; - cl_opts->io_types = 0; /* will set default after parsing options */ - cl_opts->num_iters = 1; - - default_rank = 2; - - cl_opts->dset_rank = 0; - cl_opts->buf_rank = 0; - cl_opts->chk_rank = 0; - cl_opts->order_rank = 0; - - for(i = 0; i < MAX_DIMS; i++) { - cl_opts->buf_size[i] = (size_t)((i + 1) * 10); - cl_opts->dset_size[i] = (hsize_t)((i + 1) * 100); - cl_opts->chk_size[i] = (size_t)((i + 1) * 10); - cl_opts->order[i] = i + 1; - } - - cl_opts->vfd = sec2; - - cl_opts->print_times = FALSE; /* Printing times is off by default */ - cl_opts->print_raw = FALSE; /* Printing raw data throughput is off by default */ - cl_opts->h5_alignment = 1; /* No alignment for HDF5 objects by default */ - cl_opts->h5_threshold = 1; /* No threshold for aligning HDF5 objects by default */ - cl_opts->h5_use_chunks = FALSE; /* Don't chunk the HDF5 dataset by default */ - cl_opts->h5_write_only = FALSE; /* Do both read and write by default */ - cl_opts->h5_extendable = FALSE; /* Use extendable dataset */ - cl_opts->verify = FALSE; /* No Verify data correctness by default */ - - while ((opt = get_option(argc, (const char **)argv, s_opts, l_opts)) != EOF) { - switch ((char)opt) { - case 'a': - cl_opts->h5_alignment = parse_size_directive(opt_arg); - break; - case 'A': - { - const char *end = opt_arg; - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (isalnum(*end) && i < 10) - buf[i++] = *end; - - if (!HDstrcasecmp(buf, "hdf5")) { - cl_opts->io_types |= SIO_HDF5; - } else if (!HDstrcasecmp(buf, "posix")) { - cl_opts->io_types |= SIO_POSIX; - } else { - fprintf(stderr, "sio_perf: invalid --api option %s\n", - buf); - exit(EXIT_FAILURE); - } - - if (*end == '\0') - break; - - end++; - } - } - - break; -#if 0 - case 'b': - /* the future "binary" option */ - break; -#endif /* 0 */ - case 'c': - /* Turn on chunked HDF5 dataset creation */ - cl_opts->h5_use_chunks = 1; - { - const char *end = opt_arg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (isalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->chk_size[j] = parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - cl_opts->chk_rank = j; - } - - break; - - - case 'D': - { - const char *end = opt_arg; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (isalnum(*end) && i < 10) - buf[i++] = *end; - - if (strlen(buf) > 1 || isdigit(buf[0])) { - size_t j; - - for (j = 0; j < 10 && buf[j] != '\0'; ++j) - if (!isdigit(buf[j])) { - fprintf(stderr, "sio_perf: invalid --debug option %s\n", - buf); - exit(EXIT_FAILURE); - } - - sio_debug_level = atoi(buf); - - if (sio_debug_level > 4) - sio_debug_level = 4; - else if (sio_debug_level < 0) - sio_debug_level = 0; - } else { - switch (*buf) { - case 'r': - /* Turn on raw data throughput info */ - cl_opts->print_raw = TRUE; - break; - case 't': - /* Turn on time printing */ - cl_opts->print_times = TRUE; - break; - case 'v': - /* Turn on verify data correctness*/ - cl_opts->verify = TRUE; - break; - default: - fprintf(stderr, "sio_perf: invalid --debug option %s\n", buf); - exit(EXIT_FAILURE); - } - } - - if (*end == '\0') - break; - - end++; - } - } - - break; - case 'e': - { - const char *end = opt_arg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (isalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->dset_size[j] = parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - cl_opts->dset_rank = j; - } - - break; - - case 'i': - cl_opts->num_iters = atoi(opt_arg); - break; - case 'o': - cl_opts->output_file = opt_arg; - break; - case 'T': - cl_opts->h5_threshold = parse_size_directive(opt_arg); - break; - case 'v': - if (!HDstrcasecmp(opt_arg, "sec2")) { - cl_opts->vfd=sec2; - } else if (!HDstrcasecmp(opt_arg, "stdio")) { - cl_opts->vfd=stdio; - } else if (!HDstrcasecmp(opt_arg, "core")) { - cl_opts->vfd=core; - } else if (!HDstrcasecmp(opt_arg, "split")) { - cl_opts->vfd=split; - } else if (!HDstrcasecmp(opt_arg, "multi")) { - cl_opts->vfd=multi; - } else if (!HDstrcasecmp(opt_arg, "family")) { - cl_opts->vfd=family; - } else if (!HDstrcasecmp(opt_arg, "direct")) { - cl_opts->vfd=direct; - } else { - fprintf(stderr, "sio_perf: invalid --api option %s\n", - opt_arg); - exit(EXIT_FAILURE); - } - break; - case 'w': - cl_opts->h5_write_only = TRUE; - break; - case 't': - cl_opts->h5_extendable = TRUE; - break; - case 'x': - { - const char *end = opt_arg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (isalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->buf_size[j] = parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - cl_opts->buf_rank = j; - } - - break; - - case 'r': - { - const char *end = opt_arg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (isalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->order[j] = (int)parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - - cl_opts->order_rank = j; - } - - break; - - case 'h': - case '?': - default: - usage(progname); - free(cl_opts); - return NULL; - } - } - - /* perform rank consistency analysis */ - actual_rank = 0; - - ranks[0] = cl_opts->dset_rank; - ranks[1] = cl_opts->buf_rank; - ranks[2] = cl_opts->order_rank; - ranks[3] = cl_opts->chk_rank; - - for (i=0; i<4; i++) { - if (ranks[i]>0) { - if (!actual_rank) { - actual_rank = ranks[i]; - } - else { - if (actual_rank != ranks[i]) - exit(EXIT_FAILURE); - } - } - } - - if (!actual_rank) - actual_rank = default_rank; - - cl_opts->dset_rank = actual_rank; - cl_opts->buf_rank = actual_rank; - cl_opts->order_rank = actual_rank; - cl_opts->chk_rank = actual_rank; - - for (i=0; i<actual_rank; i++) { - if (cl_opts->order[i] > actual_rank) { - exit(EXIT_FAILURE); - } - } - - /* set default if none specified yet */ - if (!cl_opts->io_types) - cl_opts->io_types = SIO_HDF5 | SIO_POSIX; /* run all API */ - - /* verify parameters sanity. Adjust if needed. */ - /* cap xfer_size with bytes per process */ - if (cl_opts->num_iters <= 0) - cl_opts->num_iters = 1; - - 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 off_t because this is related to file size. - * 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 hsize_t -parse_size_directive(const char *size) -{ - hsize_t s; - char *endptr; - - s = HDstrtoull(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) -{ - print_version(prog); - printf("usage: %s [OPTIONS]\n", prog); - printf(" OPTIONS\n"); - printf(" -h Print an usage message and exit\n"); - printf(" -A AL Which APIs to test\n"); - printf(" [default: all of them]\n"); - printf(" -c SL Selects chunked storage and defines chunks dimensions\n"); - printf(" and sizes\n"); - printf(" [default: Off]\n"); - printf(" -e SL Dimensions and sizes of dataset\n"); - printf(" [default: 100,200]\n"); - printf(" -i N Number of iterations to perform\n"); - printf(" [default: 1]\n"); - printf(" -r NL Dimension access order (see below for description)\n"); - printf(" [default: 1,2]\n"); - printf(" -t Selects extendable dimensions for HDF5 dataset\n"); - printf(" [default: Off]\n"); - printf(" -v VFD Selects file driver for HDF5 access\n"); - printf(" [default: sec2]\n"); - printf(" -w Perform write tests, not the read tests\n"); - printf(" [default: Off]\n"); - printf(" -x SL Dimensions and sizes of the transfer buffer\n"); - printf(" [default: 10,20]\n"); - printf("\n"); - printf(" N - is an integer > 0.\n"); - printf("\n"); - printf(" S - is a size specifier, an integer > 0 followed by a size indicator:\n"); - printf(" K - Kilobyte (%d)\n", ONE_KB); - printf(" M - Megabyte (%d)\n", ONE_MB); - printf(" G - Gigabyte (%d)\n", ONE_GB); - printf("\n"); - printf(" Example: '37M' is 37 megabytes or %d bytes\n", 37*ONE_MB); - printf("\n"); - printf(" AL - is an API list. Valid values are:\n"); - printf(" hdf5 - HDF5\n"); - printf(" posix - POSIX\n"); - printf("\n"); - printf(" Example: -A posix,hdf5\n"); - printf("\n"); - printf(" NL - is list of integers (N) separated by commas.\n"); - printf("\n"); - printf(" Example: 1,2,3\n"); - printf("\n"); - printf(" SL - is list of size specifiers (S) separated by commas.\n"); - printf("\n"); - printf(" Example: 2K,2K,3K\n"); - printf("\n"); - printf(" The example defines an object (dataset, tranfer buffer) with three\n"); - printf(" dimensions. Be aware that as the number of dimensions increases, the\n"); - printf(" the total size of the object increases exponentially.\n"); - printf("\n"); - printf(" VFD - is an HDF5 file driver specifier. Valid values are:\n"); - printf(" sec2, stdio, core, split, multi, family, direct\n"); - printf("\n"); - printf(" Dimension access order:\n"); - printf(" Data access starts at the cardinal origin of the dataset using the\n"); - printf(" transfer buffer. The next access occurs on a dataset region next to\n"); - printf(" the previous one. For a multidimensional dataset, there are several\n"); - printf(" directions as to where to proceed. This can be specified in the dimension\n"); - printf(" access order. For example, -r 1,2 states that the tool should traverse\n"); - printf(" dimension 1 first, and then dimension 2.\n"); - printf("\n"); - printf(" Environment variables:\n"); - printf(" HDF5_NOCLEANUP Do not remove data files if set [default remove]\n"); - printf(" HDF5_PREFIX Data file prefix\n"); - printf("\n"); - fflush(stdout); -} /* end usage() */ - diff --git a/tools/perform/sio_perf.h b/tools/perform/sio_perf.h deleted file mode 100644 index 7a7d708..0000000 --- a/tools/perform/sio_perf.h +++ /dev/null @@ -1,104 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef SIO_PERF_H__ -#define SIO_PERF_H__ - -#include "io_timer.h" -#ifndef STANDALONE -#include "H5private.h" -#include "h5test.h" -#include "h5tools.h" -#include "h5tools_utils.h" -#else -#include "sio_standalone.h" -#endif - -/* setup the dataset no fill option if this is v1.5 or more */ -#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR > 4 -#define H5_HAVE_NOFILL 1 -#endif - -#define MAX_DIMS 32 - -typedef enum iotype_ { - POSIXIO, - HDF5 - /*NUM_TYPES*/ -} iotype; - -typedef enum vfdtype_ { - sec2, - stdio, - core, - split, - multi, - family, - direct - /*NUM_TYPES*/ -} vfdtype; - -typedef struct parameters_ { - iotype io_type; /* The type of IO test to perform */ - vfdtype vfd; - long num_files; /* Number of files to create */ - long num_dsets; /* Number of datasets to create */ - hsize_t num_bytes; /* Number of bytes in each dset */ - int num_iters; /* Number of times to loop doing the IO */ - int rank; /* Rank of dataset */ - hsize_t dset_size[MAX_DIMS]; /* Dataset size */ - size_t buf_size[MAX_DIMS]; /* Buffer size */ - size_t chk_size[MAX_DIMS]; /* Chunk size */ - int order[MAX_DIMS]; /* Buffer size */ - hsize_t h5_align; /* HDF5 object alignment */ - hsize_t h5_thresh; /* HDF5 object alignment threshold */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_extendable; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int verify; /* Verify data correctness */ -} parameters; - -typedef struct results_ { - herr_t ret_code; - io_time_t *timers; -} results; - -#ifndef SUCCESS -#define SUCCESS 0 -#endif /* !SUCCESS */ - -#ifndef FAIL -#define FAIL -1 -#endif /* !FAIL */ - -extern FILE *output; /* output file */ -extern io_time_t *timer_g; /* timer: global for stub functions */ -extern int sio_debug_level; /* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Even More Debugging (timer stuff) - */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern void do_sio(parameters param, results *res); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* PIO_PERF_H__ */ diff --git a/tools/perform/sio_standalone.c b/tools/perform/sio_standalone.c deleted file mode 100644 index d92ed30..0000000 --- a/tools/perform/sio_standalone.c +++ /dev/null @@ -1,285 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - -/* This file contains the definition of functions required to build h5perf in - * STANDALONE mode. - * Created: Christian Chilan, 2005/5/18. - */ - -#include "sio_perf.h" - - -/** From h5tools_utils.c **/ - -/* global variables */ -int nCols = 80; - -/* ``get_option'' variables */ -int opt_err = 1; /*get_option prints errors if this is on */ -int opt_ind = 1; /*token pointer */ -const char *opt_arg; /*flag argument (or value) */ - - -int -get_option(int argc, const char **argv, const char *opts, const struct long_options *l_opts) -{ - static int sp = 1; /* character index in current token */ - int opt_opt = '?'; /* option character passed back to user */ - - if (sp == 1) { - /* check for more flag-like tokens */ - if (opt_ind >= argc || argv[opt_ind][0] != '-' || argv[opt_ind][1] == '\0') { - return EOF; - } else if (HDstrcmp(argv[opt_ind], "--") == 0) { - opt_ind++; - return EOF; - } - } - - if (sp == 1 && argv[opt_ind][0] == '-' && argv[opt_ind][1] == '-') { - /* long command line option */ - const char *arg = &argv[opt_ind][2]; - int i; - - for (i = 0; l_opts && l_opts[i].name; i++) { - size_t len = HDstrlen(l_opts[i].name); - - if (HDstrncmp(arg, l_opts[i].name, len) == 0) { - /* we've found a matching long command line flag */ - opt_opt = l_opts[i].shortval; - - if (l_opts[i].has_arg != no_arg) { - if (arg[len] == '=') { - opt_arg = &arg[len + 1]; - } else if (opt_ind < (argc - 1) && argv[opt_ind + 1][0] != '-') { - opt_arg = argv[++opt_ind]; - } else if (l_opts[i].has_arg == require_arg) { - if (opt_err) - HDfprintf(stderr, - "%s: option required for \"--%s\" flag\n", - argv[0], arg); - - opt_opt = '?'; - } - } else { - if (arg[len] == '=') { - if (opt_err) - HDfprintf(stderr, - "%s: no option required for \"%s\" flag\n", - argv[0], arg); - - opt_opt = '?'; - } - - opt_arg = NULL; - } - - break; - } - } - - if (l_opts[i].name == NULL) { - /* exhausted all of the l_opts we have and still didn't match */ - if (opt_err) - HDfprintf(stderr, "%s: unknown option \"%s\"\n", argv[0], arg); - - opt_opt = '?'; - } - - opt_ind++; - sp = 1; - } else { - register char *cp; /* pointer into current token */ - - /* short command line option */ - opt_opt = argv[opt_ind][sp]; - - if (opt_opt == ':' || (cp = strchr(opts, opt_opt)) == 0) { - - if (opt_err) - HDfprintf(stderr, "%s: unknown option \"%c\"\n", - argv[0], opt_opt); - - /* if no chars left in this token, move to next token */ - if (argv[opt_ind][++sp] == '\0') { - opt_ind++; - sp = 1; - } - - return '?'; - } - - if (*++cp == ':') { - /* if a value is expected, get it */ - if (argv[opt_ind][sp + 1] != '\0') { - /* flag value is rest of current token */ - opt_arg = &argv[opt_ind++][sp + 1]; - } else if (++opt_ind >= argc) { - if (opt_err) - HDfprintf(stderr, - "%s: value expected for option \"%c\"\n", - argv[0], opt_opt); - - opt_opt = '?'; - } else { - /* flag value is next token */ - opt_arg = argv[opt_ind++]; - } - - sp = 1; - } else { - /* set up to look at next char in token, next time */ - if (argv[opt_ind][++sp] == '\0') { - /* no more in current token, so setup next token */ - opt_ind++; - sp = 1; - } - - opt_arg = NULL; - } - } - - /* return the current flag character found */ - return opt_opt; -} - - -void -print_version(const char *progname) -{ - printf("%s: Version %u.%u.%u%s%s\n", - progname, H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE, - H5_VERS_SUBRELEASE[0] ? "-" : "", H5_VERS_SUBRELEASE); -} - - - -/** From h5test.c **/ - -#ifdef H5_HAVE_PARALLEL -MPI_Info h5_io_info_g=MPI_INFO_NULL;/* MPI INFO object for IO */ -#endif - -#if 0 -int -h5_set_info_object(void) -{ - char *envp; /* environment pointer */ - int ret_value=0; - - /* handle any MPI INFO hints via $HDF5_MPI_INFO */ - if ((envp = getenv("HDF5_MPI_INFO")) != NULL){ - char *next, *valp; - - - valp = envp = next = HDstrdup(envp); - - /* create an INFO object if not created yet */ - if (h5_io_info_g == MPI_INFO_NULL) - MPI_Info_create(&h5_io_info_g); - - do { - size_t len; - char *key_val, *endp, *namep; - - if (*valp == ';') - valp++; - - /* copy key/value pair into temporary buffer */ - len = strcspn(valp, ";"); - next = &valp[len]; - key_val = calloc(1, len + 1); - - /* increment the next pointer past the terminating semicolon */ - if (*next == ';') - ++next; - - namep = HDstrncpy(key_val, valp, len); - - /* pass up any beginning whitespaces */ - while (*namep && (*namep == ' ' || *namep == '\t')) - namep++; - - /* eat up any ending white spaces */ - endp = &namep[strlen(namep) - 1]; - - while (endp && (*endp == ' ' || *endp == '\t')) - *endp-- = '\0'; - - /* find the '=' */ - - valp = HDstrchr(namep, '='); - - if (valp != NULL) { /* it's a valid key/value pairing */ - char *tmp_val = valp + 1; - - /* change '=' to \0, move valp down one */ - *valp-- = '\0'; - - /* eat up ending whitespace on the "key" part */ - while (*valp == ' ' || *valp == '\t') - *valp-- = '\0'; - - valp = tmp_val; - - /* eat up beginning whitespace on the "value" part */ - while (*valp == ' ' || *valp == '\t') - *valp++ = '\0'; - - /* actually set the darned thing */ - if (MPI_SUCCESS != MPI_Info_set(h5_io_info_g, namep, valp)) { - printf("MPI_Info_set failed\n"); - ret_value = -1; - } - } - - valp = next; - HDfree(key_val); - } while (next && *next); - - HDfree(envp); - } - - return ret_value; -} - - -void -h5_dump_info_object(MPI_Info info) -{ - char key[MPI_MAX_INFO_KEY+1]; - char value[MPI_MAX_INFO_VAL+1]; - int flag; - int i, nkeys; - - printf("Dumping MPI Info Object(%d) (up to %d bytes per item):\n", (int)info, - MPI_MAX_INFO_VAL); - if (info==MPI_INFO_NULL){ - printf("object is MPI_INFO_NULL\n"); - } - else { - MPI_Info_get_nkeys(info, &nkeys); - printf("object has %d items\n", nkeys); - for (i=0; i<nkeys; i++){ - MPI_Info_get_nthkey(info, i, key); - MPI_Info_get(info, key, MPI_MAX_INFO_VAL, value, &flag); - printf("%s=%s\n", key, value); - } - - } -} - -#endif - diff --git a/tools/perform/sio_standalone.h b/tools/perform/sio_standalone.h deleted file mode 100644 index 83dffa2..0000000 --- a/tools/perform/sio_standalone.h +++ /dev/null @@ -1,546 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef SIO_STANDALONE_H__ -#define SIO_PERF_H__ - -/* Header file for building h5perf by standalone mode. - * Created: Christian Chilan, 2005/5/18. - */ - -/** From H5private.h **/ - -#include "H5public.h" /* Include Public Definitions */ - - -/* - * Include ANSI-C header files. - */ -#ifdef H5_STDC_HEADERS -# include <assert.h> -# include <ctype.h> -# include <errno.h> -# include <fcntl.h> -# include <float.h> -# include <limits.h> -# include <math.h> -# include <signal.h> -# include <stdarg.h> -# include <stdio.h> -# include <stdlib.h> -# include <string.h> -#endif - -/* maximum of two, three, or four values */ -#undef MAX -#define MAX(a,b) (((a)>(b)) ? (a) : (b)) -#define MAX2(a,b) MAX(a,b) -#define MAX3(a,b,c) MAX(a,MAX(b,c)) -#define MAX4(a,b,c,d) MAX(MAX(a,b),MAX(c,d)) - -/* - * A macro to portably increment enumerated types. - */ -#ifndef H5_INC_ENUM -# define H5_INC_ENUM(TYPE,VAR) (VAR)=((TYPE)((VAR)+1)) -#endif - -#define H5_FLT_ABS_EQUAL(X,Y) (HDfabsf((X)-(Y)) < FLT_EPSILON) -#define H5_DBL_ABS_EQUAL(X,Y) (HDfabs ((X)-(Y)) < DBL_EPSILON) -#define H5_LDBL_ABS_EQUAL(X,Y) (HDfabsl((X)-(Y)) < LDBL_EPSILON) - -#define H5_FLT_REL_EQUAL(X,Y,M) (HDfabsf(((Y)-(X)) / (X)) < (M)) -#define H5_DBL_REL_EQUAL(X,Y,M) (HDfabs (((Y)-(X)) / (X)) < (M)) -#define H5_LDBL_REL_EQUAL(X,Y,M) (HDfabsl(((Y)-(X)) / (X)) < (M)) - -/* - * Redefine all the POSIX functions. We should never see a POSIX - * function (or any other non-HDF5 function) in the source! - */ -#define HDabort() abort() -#define HDabs(X) abs(X) -#ifdef H5_HAVE_WIN32_API -#define HDaccess(F,M) _access(F, M) -#define R_OK 4 /* Test for read permission. */ -#define W_OK 2 /* Test for write permission. */ -#define X_OK 1 /* Test for execute permission. */ -#define F_OK 0 /* Test for existence. */ -#else /* H5_HAVE_WIN32_API */ -#define HDaccess(F,M) access(F, M) -#ifndef F_OK -#define F_OK 00 -#define W_OK 02 -#define R_OK 04 -#endif -#endif /* H5_HAVE_WIN32_API */ -#define HDacos(X) acos(X) -#ifdef H5_HAVE_ALARM -#define HDalarm(N) alarm(N) -#else /* H5_HAVE_ALARM */ -#define HDalarm(N) (0) -#endif /* H5_HAVE_ALARM */ -#define HDasctime(T) asctime(T) -#define HDasin(X) asin(X) -#define HDasprintf asprintf /*varargs*/ -#define HDassert(X) assert(X) -#define HDatan(X) atan(X) -#define HDatan2(X,Y) atan2(X,Y) -#define HDatexit(F) atexit(F) -#define HDatof(S) atof(S) -#define HDatoi(S) atoi(S) -#define HDatol(S) atol(S) -#define HDbsearch(K,B,N,Z,F) bsearch(K,B,N,Z,F) -#define HDcalloc(N,Z) calloc(N,Z) -#define HDceil(X) ceil(X) -#define HDcfgetispeed(T) cfgetispeed(T) -#define HDcfgetospeed(T) cfgetospeed(T) -#define HDcfsetispeed(T,S) cfsetispeed(T,S) -#define HDcfsetospeed(T,S) cfsetospeed(T,S) -#define HDchdir(S) chdir(S) -#define HDchmod(S,M) chmod(S,M) -#define HDchown(S,O,G) chown(S,O,G) -#define HDclearerr(F) clearerr(F) -#define HDclock() clock() -#define HDclose(F) close(F) -#define HDclosedir(D) closedir(D) -#define HDcos(X) cos(X) -#define HDcosh(X) cosh(X) -#define HDcreat(S,M) creat(S,M) -#define HDctermid(S) ctermid(S) -#define HDctime(T) ctime(T) -#define HDcuserid(S) cuserid(S) -#ifdef H5_HAVE_DIFFTIME -#define HDdifftime(X,Y) difftime(X,Y) -#else -#define HDdifftime(X,Y) ((double)(X)-(double)(Y)) -#endif -#define HDdiv(X,Y) div(X,Y) -#define HDdup(F) dup(F) -#define HDdup2(F,I) dup2(F,I) -/* execl() variable arguments */ -/* execle() variable arguments */ -/* execlp() variable arguments */ -#define HDexecv(S,AV) execv(S,AV) -#define HDexecve(S,AV,E) execve(S,AV,E) -#define HDexecvp(S,AV) execvp(S,AV) -#define HDexit(N) exit(N) -#define HD_exit(N) _exit(N) -#define HDexp(X) exp(X) -#define HDfabs(X) fabs(X) -/* use ABS() because fabsf() fabsl() are not common yet. */ -#define HDfabsf(X) ABS(X) -#define HDfabsl(X) ABS(X) -#define HDfclose(F) fclose(F) -/* fcntl() variable arguments */ -#define HDfdopen(N,S) fdopen(N,S) -#define HDfeof(F) feof(F) -#define HDferror(F) ferror(F) -#define HDfflush(F) fflush(F) -#define HDfgetc(F) fgetc(F) -#define HDfgetpos(F,P) fgetpos(F,P) -#define HDfgets(S,N,F) fgets(S,N,F) -#ifdef H5_HAVE_WIN32_API -#define HDfileno(F) _fileno(F) -#else /* H5_HAVE_WIN32_API */ -#define HDfileno(F) fileno(F) -#endif /* H5_HAVE_WIN32_API */ -#define HDfloor(X) floor(X) -#define HDfmod(X,Y) fmod(X,Y) -#define HDfopen(S,M) fopen(S,M) -#define HDfork() fork() -#define HDfpathconf(F,N) fpathconf(F,N) -H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...); -#define HDfputc(C,F) fputc(C,F) -#define HDfputs(S,F) fputs(S,F) -#define HDfread(M,Z,N,F) fread(M,Z,N,F) -#define HDfree(M) free(M) -#define HDfreopen(S,M,F) freopen(S,M,F) -#define HDfrexp(X,N) frexp(X,N) -/* Check for Cray-specific 'frexpf()' and 'frexpl()' routines */ -#ifdef H5_HAVE_FREXPF -#define HDfrexpf(X,N) frexpf(X,N) -#else /* H5_HAVE_FREXPF */ -#define HDfrexpf(X,N) frexp(X,N) -#endif /* H5_HAVE_FREXPF */ -#ifdef H5_HAVE_FREXPL -#define HDfrexpl(X,N) frexpl(X,N) -#else /* H5_HAVE_FREXPL */ -#define HDfrexpl(X,N) frexp(X,N) -#endif /* H5_HAVE_FREXPL */ -/* fscanf() variable arguments */ -#ifdef H5_HAVE_FSEEKO - #define HDfseek(F,O,W) fseeko(F,O,W) -#else - #define HDfseek(F,O,W) fseek(F,O,W) -#endif -#define HDfsetpos(F,P) fsetpos(F,P) -/* definitions related to the file stat utilities. - * Windows have its own function names. - * For Unix, if off_t is not 64bit big, try use the pseudo-standard - * xxx64 versions if available. - */ -#ifdef H5_HAVE_WIN32_API - #define HDfstat(F,B) _fstati64(F,B) - #define HDlstat(S,B) _lstati64(S,B) - #define HDstat(S,B) _stati64(S,B) - typedef struct _stati64 h5_stat_t; - typedef __int64 h5_stat_size_t; - #define HDoff_t __int64 -#elif H5_SIZEOF_OFF_T!=8 && H5_SIZEOF_OFF64_T==8 && defined(H5_HAVE_STAT64) - #define HDfstat(F,B) fstat64(F,B) - #define HDlstat(S,B) lstat64(S,B) - #define HDstat(S,B) stat64(S,B) - typedef struct stat64 h5_stat_t; - typedef off64_t h5_stat_size_t; - #define HDoff_t off64_t -#else - #define HDfstat(F,B) fstat(F,B) - #define HDlstat(S,B) lstat(S,B) - #define HDstat(S,B) stat(S,B) - typedef struct stat h5_stat_t; - typedef off_t h5_stat_size_t; - #define HDoff_t off_t -#endif - -#ifndef H5_HAVE_WIN32_API -/* These definitions differ in Windows and are defined in - * H5win32defs for that platform. - */ -typedef struct stat h5_stat_t; -typedef off_t h5_stat_size_t; -#define HDoff_t off_t -#endif /* H5_HAVE_WIN32_API */ - -#define HDftell(F) ftell(F) -#define HDftruncate(F,L) ftruncate(F,L) -#define HDfwrite(M,Z,N,F) fwrite(M,Z,N,F) -#define HDgetc(F) getc(F) -#define HDgetchar() getchar() -#define HDgetcwd(S,Z) getcwd(S,Z) -#define HDgetegid() getegid() -#define HDgetenv(S) getenv(S) -#define HDgeteuid() geteuid() -#define HDgetgid() getgid() -#define HDgetgrgid(G) getgrgid(G) -#define HDgetgrnam(S) getgrnam(S) -#define HDgetgroups(Z,G) getgroups(Z,G) -#ifdef H5_HAVE_WIN32_API -#define HDgetlogin() Wgetlogin() -#else /* H5_HAVE_WIN32_API */ -#define HDgetlogin() getlogin() -#endif /* H5_HAVE_WIN32_API */ -#define HDgetpgrp() getpgrp() -#define HDgetpid() getpid() -#define HDgetppid() getppid() -#define HDgetpwnam(S) getpwnam(S) -#define HDgetpwuid(U) getpwuid(U) -#define HDgetrusage(X,S) getrusage(X,S) -#define HDgets(S) gets(S) -#ifdef H5_HAVE_WIN32_API - H5_DLL int Wgettimeofday(struct timeval *tv, struct timezone *tz); -#define HDgettimeofday(V,Z) Wgettimeofday(V,Z) -#else /* H5_HAVE_WIN32_API */ -#define HDgettimeofday(S,P) gettimeofday(S,P) -#endif /* H5_HAVE_WIN32_API */ -#define HDgetuid() getuid() -#define HDgmtime(T) gmtime(T) -#define HDisalnum(C) isalnum((int)(C)) /*cast for solaris warning*/ -#define HDisalpha(C) isalpha((int)(C)) /*cast for solaris warning*/ -#define HDisatty(F) isatty(F) -#define HDiscntrl(C) iscntrl((int)(C)) /*cast for solaris warning*/ -#define HDisdigit(C) isdigit((int)(C)) /*cast for solaris warning*/ -#define HDisgraph(C) isgraph((int)(C)) /*cast for solaris warning*/ -#define HDislower(C) islower((int)(C)) /*cast for solaris warning*/ -#define HDisprint(C) isprint((int)(C)) /*cast for solaris warning*/ -#define HDispunct(C) ispunct((int)(C)) /*cast for solaris warning*/ -#define HDisspace(C) isspace((int)(C)) /*cast for solaris warning*/ -#define HDisupper(C) isupper((int)(C)) /*cast for solaris warning*/ -#define HDisxdigit(C) isxdigit((int)(C)) /*cast for solaris warning*/ -#define HDkill(P,S) kill(P,S) -#define HDlabs(X) labs(X) -#define HDldexp(X,N) ldexp(X,N) -#define HDldiv(X,Y) ldiv(X,Y) -#define HDlink(OLD,NEW) link(OLD,NEW) -#define HDlocaleconv() localeconv() -#define HDlocaltime(T) localtime(T) -#define HDlog(X) log(X) -#define HDlog10(X) log10(X) -#define HDlongjmp(J,N) longjmp(J,N) -#ifdef H5_HAVE_WIN32_API - #define HDlseek(F,O,W) _lseeki64(F,O,W) -#else - #ifdef H5_HAVE_LSEEK64 - #define HDlseek(F,O,W) lseek64(F,O,W) - #else - #define HDlseek(F,O,W) lseek(F,O,W) - #endif -#endif -#define HDmalloc(Z) malloc(Z) -#define HDposix_memalign(P,A,Z) posix_memalign(P,A,Z) -#define HDmblen(S,N) mblen(S,N) -#define HDmbstowcs(P,S,Z) mbstowcs(P,S,Z) -#define HDmbtowc(P,S,Z) mbtowc(P,S,Z) -#define HDmemchr(S,C,Z) memchr(S,C,Z) -#define HDmemcmp(X,Y,Z) memcmp(X,Y,Z) -/* - * The (char*) casts are required for the DEC when optimizations are turned - * on and the source and/or destination are not aligned. - */ -#define HDmemcpy(X,Y,Z) memcpy((char*)(X),(const char*)(Y),Z) -#define HDmemmove(X,Y,Z) memmove((char*)(X),(const char*)(Y),Z) -/* - * The (void*) cast just avoids a compiler warning in H5_HAVE_VISUAL_STUDIO - */ -#ifdef H5_HAVE_VISUAL_STUDIO -#define HDmemset(X,C,Z) memset((void*)(X),C,Z) -#else /* H5_HAVE_VISUAL_STUDIO */ -#define HDmemset(X,C,Z) memset(X,C,Z) -#endif /* H5_HAVE_VISUAL_STUDIO */ -#ifdef H5_HAVE_WIN32_API -#define HDmkdir(S,M) _mkdir(S) -#else /* H5_HAVE_WIN32_API */ -#define HDmkdir(S,M) mkdir(S,M) -#endif /* H5_HAVE_WIN32_API */ -#define HDmkfifo(S,M) mkfifo(S,M) -#define HDmktime(T) mktime(T) -#define HDmodf(X,Y) modf(X,Y) -#ifdef _O_BINARY -#define HDopen(S,F,M) open(S,F|_O_BINARY,M) -#else -#define HDopen(S,F,M) open(S,F,M) -#endif -#define HDopendir(S) opendir(S) -#define HDpathconf(S,N) pathconf(S,N) -#define HDpause() pause() -#define HDperror(S) perror(S) -#define HDpipe(F) pipe(F) -#define HDpow(X,Y) pow(X,Y) -/* printf() variable arguments */ -#define HDputc(C,F) putc(C,F) -#define HDputchar(C) putchar(C) -#define HDputs(S) puts(S) -#define HDqsort(M,N,Z,F) qsort(M,N,Z,F) -#define HDraise(N) raise(N) - -#ifdef H5_HAVE_RAND_R -#define HDrandom() HDrand() -H5_DLL int HDrand(void); -#elif H5_HAVE_RANDOM -#define HDrand() random() -#define HDrandom() random() -#else -#define HDrand() rand() -#define HDrandom() rand() -#endif - -#define HDread(F,M,Z) read(F,M,Z) -#define HDreaddir(D) readdir(D) -#define HDrealloc(M,Z) realloc(M,Z) -#define HDremove(S) remove(S) -#define HDrename(OLD,NEW) rename(OLD,NEW) -#define HDrewind(F) rewind(F) -#define HDrewinddir(D) rewinddir(D) -#define HDrmdir(S) rmdir(S) -/* scanf() variable arguments */ -#define HDsetbuf(F,S) setbuf(F,S) -#define HDsetgid(G) setgid(G) -#define HDsetjmp(J) setjmp(J) -#define HDsetlocale(N,S) setlocale(N,S) -#define HDsetpgid(P,PG) setpgid(P,PG) -#define HDsetsid() setsid() -#define HDsetuid(U) setuid(U) -/* Windows does not permit setting the buffer size to values - less than 2. */ -#ifndef H5_HAVE_WIN32_API -#define HDsetvbuf(F,S,M,Z) setvbuf(F,S,M,Z) -#else -#define HDsetvbuf(F,S,M,Z) setvbuf(F,S,M,(Z>1?Z:2)) -#endif -#define HDsigaddset(S,N) sigaddset(S,N) -#define HDsigdelset(S,N) sigdelset(S,N) -#define HDsigemptyset(S) sigemptyset(S) -#define HDsigfillset(S) sigfillset(S) -#define HDsigismember(S,N) sigismember(S,N) -#define HDsiglongjmp(J,N) siglongjmp(J,N) -#define HDsignal(N,F) signal(N,F) -#define HDsigpending(S) sigpending(S) -#define HDsigprocmask(H,S,O) sigprocmask(H,S,O) -#define HDsigsetjmp(J,N) sigsetjmp(J,N) -#define HDsigsuspend(S) sigsuspend(S) -#define HDsin(X) sin(X) -#define HDsinh(X) sinh(X) -#define HDsleep(N) sleep(N) -#ifdef H5_HAVE_WIN32_API -H5_DLL int c99_snprintf(char* str, size_t size, const char* format, ...); -#define HDsnprintf c99_snprintf /*varargs*/ -#else -#define HDsnprintf snprintf /*varargs*/ -#endif -/* sprintf() variable arguments */ -#define HDsqrt(X) sqrt(X) -#ifdef H5_HAVE_RAND_R -H5_DLL void HDsrand(unsigned int seed); -#define HDsrandom(S) HDsrand(S) -#elif H5_HAVE_RANDOM -#define HDsrand(S) srandom(S) -#define HDsrandom(S) srandom(S) -#else -#define HDsrand(S) srand(S) -#define HDsrandom(S) srand(S) -#endif -/* sscanf() variable arguments */ - -#ifdef H5_HAVE_WIN32_API -#define HDstrcasecmp(A,B) _stricmp(A,B) -#else -#define HDstrcasecmp(X,Y) strcasecmp(X,Y) -#endif -#define HDstrcat(X,Y) strcat(X,Y) -#define HDstrchr(S,C) strchr(S,C) -#define HDstrcmp(X,Y) strcmp(X,Y) -#define HDstrcoll(X,Y) strcoll(X,Y) -#define HDstrcpy(X,Y) strcpy(X,Y) -#define HDstrcspn(X,Y) strcspn(X,Y) -#define HDstrerror(N) strerror(N) -#define HDstrftime(S,Z,F,T) strftime(S,Z,F,T) -#define HDstrlen(S) strlen(S) -#define HDstrncat(X,Y,Z) strncat(X,Y,Z) -#define HDstrncmp(X,Y,Z) strncmp(X,Y,Z) -#define HDstrncpy(X,Y,Z) strncpy(X,Y,Z) -#define HDstrpbrk(X,Y) strpbrk(X,Y) -#define HDstrrchr(S,C) strrchr(S,C) -#define HDstrspn(X,Y) strspn(X,Y) -#define HDstrstr(X,Y) strstr(X,Y) -#define HDstrtod(S,R) strtod(S,R) -#define HDstrtok(X,Y) strtok(X,Y) -#define HDstrtol(S,R,N) strtol(S,R,N) -H5_DLL int64_t HDstrtoll (const char *s, const char **rest, int base); -#define HDstrtoul(S,R,N) strtoul(S,R,N) -#ifdef H5_HAVE_WIN32_API -#define HDstrtoull(S,R,N) _strtoui64(S,R,N) -#else -#define HDstrtoull(S,R,N) strtoull(S,R,N) -#endif -#define HDstrxfrm(X,Y,Z) strxfrm(X,Y,Z) -#define HDsysconf(N) sysconf(N) -#define HDsystem(S) system(S) -#define HDtan(X) tan(X) -#define HDtanh(X) tanh(X) -#define HDtcdrain(F) tcdrain(F) -#define HDtcflow(F,A) tcflow(F,A) -#define HDtcflush(F,N) tcflush(F,N) -#define HDtcgetattr(F,T) tcgetattr(F,T) -#define HDtcgetpgrp(F) tcgetpgrp(F) -#define HDtcsendbreak(F,N) tcsendbreak(F,N) -#define HDtcsetattr(F,O,T) tcsetattr(F,O,T) -#define HDtcsetpgrp(F,N) tcsetpgrp(F,N) -#define HDtime(T) time(T) -#define HDtimes(T) times(T) -#define HDtmpfile() tmpfile() -#define HDtmpnam(S) tmpnam(S) -#define HDtolower(C) tolower(C) -#define HDtoupper(C) toupper(C) -#define HDttyname(F) ttyname(F) -#define HDtzset() tzset() -#define HDumask(N) umask(N) -#define HDuname(S) uname(S) -#define HDungetc(C,F) ungetc(C,F) -#ifdef H5_HAVE_WIN32_API -#define HDunlink(S) _unlink(S) -#else -#define HDunlink(S) unlink(S) -#endif -#define HDutime(S,T) utime(S,T) -#define HDva_arg(A,T) va_arg(A,T) -#define HDva_end(A) va_end(A) -#define HDva_start(A,P) va_start(A,P) -#define HDvasprintf(RET,FMT,A) vasprintf(RET,FMT,A) -#define HDvfprintf(F,FMT,A) vfprintf(F,FMT,A) -#define HDvprintf(FMT,A) vprintf(FMT,A) -#define HDvsprintf(S,FMT,A) vsprintf(S,FMT,A) -#ifdef H5_HAVE_WIN32_API -H5_DLL int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap); -#define HDvsnprintf c99_vsnprintf -#else -# define HDvsnprintf(S,N,FMT,A) vsnprintf(S,N,FMT,A) -#endif -#define HDwait(W) wait(W) -#define HDwaitpid(P,W,O) waitpid(P,W,O) -#define HDwcstombs(S,P,Z) wcstombs(S,P,Z) -#define HDwctomb(S,C) wctomb(S,C) -#define HDwrite(F,M,Z) write(F,M,Z) - -/* - * And now for a couple non-Posix functions... Watch out for systems that - * define these in terms of macros. - */ -#ifdef H5_HAVE_WIN32_API -#define HDstrdup(S) _strdup(S) -#else /* H5_HAVE_WIN32_API */ - -#if !defined strdup && !defined H5_HAVE_STRDUP -extern char *strdup(const char *s); -#endif - -#define HDstrdup(S) strdup(S) - -#endif /* H5_HAVE_WIN32_API */ - -/* - * HDF Boolean type. - */ -#ifndef FALSE -# define FALSE false -#endif -#ifndef TRUE -# define TRUE true -#endif - -/** From h5test.h **/ - -#ifdef H5_HAVE_PARALLEL -extern MPI_Info h5_io_info_g; /* MPI INFO object for IO */ -#endif - -#ifdef H5_HAVE_PARALLEL -H5TEST_DLL int h5_set_info_object(void); -H5TEST_DLL void h5_dump_info_object(MPI_Info info); -#endif - - - -/** From h5tools_utils.h **/ - -extern int opt_err; /* getoption prints errors if this is on */ -extern int opt_ind; /* token pointer */ -extern const char *opt_arg; /* flag argument (or value) */ - - -enum { - no_arg = 0, /* doesn't take an argument */ - require_arg, /* requires an argument */ - optional_arg /* argument is optional */ -}; - - -typedef struct long_options { - const char *name; /* name of the long option */ - int has_arg; /* whether we should look for an arg */ - char shortval; /* the shortname equivalent of long arg - * this gets returned from get_option */ -} long_options; - -extern int get_option(int argc, const char **argv, const char *opt, - const struct long_options *l_opt); -#endif diff --git a/tools/perform/zip_perf.c b/tools/perform/zip_perf.c deleted file mode 100644 index d9b1fa2..0000000 --- a/tools/perform/zip_perf.c +++ /dev/null @@ -1,644 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * 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://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * - * access to either file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* =========================================================================== - * Usage: zip_perf [-d] [-f] [-h] [-1 to -9] [files...] - * -d : decompress - * -f : compress with Z_FILTERED - * -h : compress with Z_HUFFMAN_ONLY - * -1 to -9 : compression level - */ - -/* our header files */ -#include "h5test.h" -#include "h5tools.h" -#include "h5tools_utils.h" - -#ifdef H5_HAVE_FILTER_DEFLATE - -#include <zlib.h> - -#define ONE_KB 1024 -#define ONE_MB (ONE_KB * ONE_KB) -#define ONE_GB (ONE_MB * ONE_KB) - -#define MICROSECOND 1000000.0F - -/* report 0.0 in case t is zero too */ -#define MB_PER_SEC(bytes,t) ((fabs(t) < (double)0.0000000001F) ? (double)0.0F : ((((double)bytes) / (double)ONE_MB) / (t))) - -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ - -#ifndef FALSE -#define FALSE (!TRUE) -#endif /* FALSE */ - -#ifndef S_IRWXU -#define S_IRWXU (_S_IREAD|_S_IWRITE) -#endif - -/* internal variables */ -static const char *prog=NULL; -static const char *option_prefix=NULL; -static char *filename=NULL; -static int compress_percent = 0; -static int compress_level = Z_DEFAULT_COMPRESSION; -static int output, random_test = FALSE; -static int report_once_flag; -static double compression_time; - -/* internal functions */ -static void error(const char *fmt, ...); -static void compress_buffer(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen); - -/* commandline options : long and short form */ -static const char *s_opts = "hB:b:c:p:rs:0123456789"; -static struct long_options l_opts[] = { - { "help", no_arg, 'h' }, - { "compressability", require_arg, 'c' }, - { "compressabilit", require_arg, 'c' }, - { "compressabili", require_arg, 'c' }, - { "compressabil", require_arg, 'c' }, - { "compressabi", require_arg, 'c' }, - { "compressab", require_arg, 'c' }, - { "compressa", require_arg, 'c' }, - { "compress", require_arg, 'c' }, - { "compres", require_arg, 'c' }, - { "compre", require_arg, 'c' }, - { "compr", require_arg, 'c' }, - { "comp", require_arg, 'c' }, - { "com", require_arg, 'c' }, - { "co", require_arg, 'c' }, - { "file-size", require_arg, 's' }, - { "file-siz", require_arg, 's' }, - { "file-si", require_arg, 's' }, - { "file-s", require_arg, 's' }, - { "file", require_arg, 's' }, - { "fil", require_arg, 's' }, - { "fi", require_arg, 's' }, - { "max-buffer-size", require_arg, 'B' }, - { "max-buffer-siz", require_arg, 'B' }, - { "max-buffer-si", require_arg, 'B' }, - { "max-buffer-s", require_arg, 'B' }, - { "max-buffer", require_arg, 'B' }, - { "max-buffe", require_arg, 'B' }, - { "max-buff", require_arg, 'B' }, - { "max-buf", require_arg, 'B' }, - { "max-bu", require_arg, 'B' }, - { "max-b", require_arg, 'B' }, - { "max", require_arg, 'B' }, - { "min-buffer-size", require_arg, 'b' }, - { "min-buffer-siz", require_arg, 'b' }, - { "min-buffer-si", require_arg, 'b' }, - { "min-buffer-s", require_arg, 'b' }, - { "min-buffer", require_arg, 'b' }, - { "min-buffe", require_arg, 'b' }, - { "min-buff", require_arg, 'b' }, - { "min-buf", require_arg, 'b' }, - { "min-bu", require_arg, 'b' }, - { "min-b", require_arg, 'b' }, - { "min", require_arg, 'b' }, - { "prefix", require_arg, 'p' }, - { "prefi", require_arg, 'p' }, - { "pref", require_arg, 'p' }, - { "pre", require_arg, 'p' }, - { "pr", require_arg, 'p' }, - { "random-test", no_arg, 'r' }, - { "random-tes", no_arg, 'r' }, - { "random-te", no_arg, 'r' }, - { "random-t", no_arg, 'r' }, - { "random", no_arg, 'r' }, - { "rando", no_arg, 'r' }, - { "rand", no_arg, 'r' }, - { "ran", no_arg, 'r' }, - { "ra", no_arg, 'r' }, - { NULL, 0, '\0' } -}; - -/* - * Function: error - * Purpose: Display error message and exit. - * Programmer: Bill Wendling, 05. June 2002 - * Modifications: - */ -static void -error(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - HDfprintf(stderr, "%s: error: ", prog); - HDvfprintf(stderr, fmt, ap); - HDfprintf(stderr, "\n"); - va_end(ap); - HDexit(EXIT_FAILURE); -} - -/* - * Function: cleanup - * Purpose: Cleanup the output file. - * Returns: Nothing - * Programmer: Bill Wendling, 06. June 2002 - * Modifications: - */ -static void -cleanup(void) -{ - if (!HDgetenv("HDF5_NOCLEANUP")) - HDunlink(filename); - HDfree(filename); -} - -static void -write_file(Bytef *source, uLongf sourceLen) -{ - Bytef *d_ptr, *dest; - uLongf d_len, destLen; - struct timeval timer_start, timer_stop; - - /* destination buffer needs to be at least 0.1% larger than sourceLen - * plus 12 bytes */ - destLen = (uLongf)((double)sourceLen + ((double)sourceLen * (double)0.1F)) + 12; - dest = (Bytef *)HDmalloc(destLen); - - if (!dest) - error("out of memory"); - - HDgettimeofday(&timer_start, NULL); - compress_buffer(dest, &destLen, source, sourceLen); - HDgettimeofday(&timer_stop, NULL); - - compression_time += ((double)timer_stop.tv_sec + - ((double)timer_stop.tv_usec) / (double)MICROSECOND) - - ((double)timer_start.tv_sec + - ((double)timer_start.tv_usec) / (double)MICROSECOND); - - if (report_once_flag) { - HDfprintf(stdout, "\tCompression Ratio: %g\n", ((double)destLen) / (double)sourceLen); - report_once_flag = 0; - } - - d_ptr = dest; - d_len = destLen; - - /* loop to make sure we write everything out that we want to write */ - for (;;) { - int rc = (int)HDwrite(output, d_ptr, (size_t)d_len); - - if (rc == -1) - error(HDstrerror(errno)); - - if (rc == (int)d_len) - break; - - d_len -= (size_t)rc; - d_ptr += rc; - } - - HDfree(dest); -} - -/* - * Function: compress_buffer - * Purpose: Compress the buffer. - * Returns: Z_OK - success - * Z_MEM_ERROR - not enough memory - * Z_BUF_ERROR - not enough room in the output buffer - * Z_STREAM_ERROR - level parameter is invalid - * Programmer: Bill Wendling, 05. June 2002 - * Modifications: - */ -static void -compress_buffer(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen) -{ - int rc = compress2(dest, destLen, source, sourceLen, compress_level); - - if (rc != Z_OK) { - /* compress2 failed - cleanup and tell why */ - cleanup(); - - switch (rc) { - case Z_MEM_ERROR: - error("not enough memory"); - break; - case Z_BUF_ERROR: - error("not enough room in the output buffer"); - break; - case Z_STREAM_ERROR: - error("level parameter (%d) is invalid", compress_level); - break; - default: - error("unknown compression error"); - break; - } - } -} - -#ifdef LATER -/* - * Function: uncompress_buffer - * Purpose: Uncompress the buffer. - * Returns: Z_OK - success - * Z_MEM_ERROR - not enough memory - * Z_BUF_ERROR - not enough room in the output buffer - * Z_DATA_ERROR - the input data was corrupted - * Programmer: Bill Wendling, 05. June 2002 - * Modifications: - */ -static int -uncompress_buffer(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen) -{ - int rc = uncompress(dest, destLen, source, sourceLen); - - return rc; -} -#endif /* LATER */ - -/* - * Function: get_unique_name - * Purpose: Create a new file who's name doesn't conflict with - * pre-existing files. - * Returns: Nothing - * Programmer: Bill Wendling, 06. June 2002 - * Modifications: - */ -#define ZIP_PERF_FILE "zip_perf.data" -static void -get_unique_name(void) -{ - const char *prefix = NULL; - const char *env = HDgetenv("HDF5_PREFIX"); - - if (env) - prefix = env; - - if (option_prefix) - prefix = option_prefix; - - if (prefix) - /* 2 = 1 for '/' + 1 for null terminator */ - filename = (char *) HDmalloc(HDstrlen(prefix) + HDstrlen(ZIP_PERF_FILE) + 2); - else - filename = (char *) HDmalloc(HDstrlen(ZIP_PERF_FILE) + 1); - - if (!filename) - error("out of memory"); - - filename[0] = 0; - if (prefix){ - HDstrcpy(filename, prefix); - HDstrcat(filename, "/"); - } - HDstrcat(filename, ZIP_PERF_FILE); -} - -/* - * Function: usage - * Purpose: Print a usage message and then exit. - * Return: Nothing - * Programmer: Bill Wendling, 05. June 2002 - * Modifications: - */ -static void -usage(void) -{ - HDfprintf(stdout, "usage: %s [OPTIONS]\n", prog); - HDfprintf(stdout, " OPTIONS\n"); - HDfprintf(stdout, " -h, --help Print this usage message and exit\n"); - HDfprintf(stdout, " -1...-9 Level of compression, from 1 to 9\n"); - HDfprintf(stdout, " -c P, --compressability=P Percentage of compressability of the random\n"); - HDfprintf(stdout, " data you want [default: 0]"); - HDfprintf(stdout, " -s S, --file-size=S Maximum size of uncompressed file [default: 64M]\n"); - HDfprintf(stdout, " -B S, --max-buffer_size=S Maximum size of buffer [default: 1M]\n"); - HDfprintf(stdout, " -b S, --min-buffer_size=S Minumum size of buffer [default: 128K]\n"); - HDfprintf(stdout, " -p D, --prefix=D The directory prefix to place the file\n"); - HDfprintf(stdout, " -r, --random-test Use random data to write to the file\n"); - HDfprintf(stdout, " [default: no]\n"); - HDfprintf(stdout, "\n"); - HDfprintf(stdout, " D - a directory which exists\n"); - HDfprintf(stdout, " P - a number between 0 and 100\n"); - HDfprintf(stdout, " S - is a size specifier, an integer >=0 followed by a size indicator:\n"); - HDfprintf(stdout, "\n"); - HDfprintf(stdout, " K - Kilobyte (%d)\n", ONE_KB); - HDfprintf(stdout, " M - Megabyte (%d)\n", ONE_MB); - HDfprintf(stdout, " G - Gigabyte (%d)\n", ONE_GB); - HDfprintf(stdout, "\n"); - HDfprintf(stdout, " Example: 37M = 37 Megabytes = %d bytes\n", 37 * ONE_MB); - HDfprintf(stdout, "\n"); - HDfflush(stdout); -} - -/* - * 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 - * - * Return: The size as a size_t because this is related to buffer size. - * If an unknown size indicator is used, then the program will - * exit with EXIT_FAILURE as the return value. - * Programmer: Bill Wendling, 05. June 2002 - * Modifications: - */ -static unsigned long -parse_size_directive(const char *size) -{ - unsigned long s; - char *endptr; - - s = HDstrtoul(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: - error("illegal size specifier '%c'", *endptr); - break; - } - } - - return s; -} - -static void -fill_with_random_data(Bytef *src, uLongf src_len) -{ - register unsigned u; - h5_stat_t stat_buf; - - if (HDstat("/dev/urandom", &stat_buf) == 0) { - uLongf len = src_len; - Bytef *buf = src; - int fd = HDopen("/dev/urandom", O_RDONLY, 0); - - HDfprintf(stdout, "Using /dev/urandom for random data\n"); - - if (fd < 0) - error(HDstrerror(errno)); - - for (;;) { - ssize_t rc = HDread(fd, buf, src_len); - - if (rc == -1) - error(HDstrerror(errno)); - - if (rc == (ssize_t)len) - break; - - buf += rc; - len -= (size_t)rc; - } - } else { - HDfprintf(stdout, "Using random() for random data\n"); - - for (u = 0; u < src_len; ++u) - src[u] = (Bytef)(0xff & HDrandom()); - } - - if (compress_percent) { - size_t s = (size_t)((src_len * (uLongf)compress_percent) / 100); - - HDmemset(src, '\0', s); - } -} - -static void -do_write_test(unsigned long file_size, unsigned long min_buf_size, - unsigned long max_buf_size) -{ - uLongf src_len, total_len; - struct timeval timer_start, timer_stop; - double total_time; - Bytef *src; - - for (src_len = min_buf_size; src_len <= max_buf_size; src_len <<= 1) { - register unsigned long i, iters; - - iters = file_size / src_len; - src = (Bytef *)HDcalloc(1, sizeof(Bytef) * src_len); - - if (!src) { - cleanup(); - error("out of memory"); - } - - compression_time = 0.0F; - - if (random_test) - fill_with_random_data(src, src_len); - - HDfprintf(stdout, "Buffer size == "); - - if (src_len >= ONE_KB && (src_len % ONE_KB) == 0) { - if (src_len >= ONE_MB && (src_len % ONE_MB) == 0) { - HDfprintf(stdout, "%ldMB", src_len / ONE_MB); - } else { - HDfprintf(stdout, "%ldKB", src_len / ONE_KB); - } - } else { - HDfprintf(stdout, "%ld", src_len); - } - - HDfprintf(stdout, "\n"); - - /* do uncompressed data write */ - HDgettimeofday(&timer_start, NULL); - output = HDopen(filename, O_RDWR | O_CREAT, S_IRWXU); - - if (output == -1) - error(HDstrerror(errno)); - - for (i = 0; i <= iters; ++i) { - Bytef *s_ptr = src; - uLong s_len = src_len; - - /* loop to make sure we write everything out that we want to write */ - for (;;) { - ssize_t rc = HDwrite(output, s_ptr, s_len); - - if (rc == -1) - error(HDstrerror(errno)); - - if (rc == (ssize_t)s_len) - break; - - s_len -= (size_t)rc; - s_ptr += rc; - } - } - - HDclose(output); - HDgettimeofday(&timer_stop, NULL); - - total_time = ((double)timer_stop.tv_sec + - ((double)timer_stop.tv_usec) / (double)MICROSECOND) - - ((double)timer_start.tv_sec + - ((double)timer_start.tv_usec) / (double)MICROSECOND); - - HDfprintf(stdout, "\tUncompressed Write Time: %.2fs\n", total_time); - HDfprintf(stdout, "\tUncompressed Write Throughput: %.2fMB/s\n", - MB_PER_SEC(file_size, total_time)); - - HDunlink(filename); - - /* do compressed data write */ - output = HDopen(filename, O_RDWR | O_CREAT, S_IRWXU); - - if (output == -1) - error(HDstrerror(errno)); - - report_once_flag = 1; - HDgettimeofday(&timer_start, NULL); - - for (total_len = 0; total_len < file_size; total_len += src_len) - write_file(src, src_len); - - HDclose(output); - HDgettimeofday(&timer_stop, NULL); - - total_time = ((double)timer_stop.tv_sec + - ((double)timer_stop.tv_usec) / (double)MICROSECOND) - - ((double)timer_start.tv_sec + - ((double)timer_start.tv_usec) / (double)MICROSECOND); - - HDfprintf(stdout, "\tCompressed Write Time: %.2fs\n", total_time); - HDfprintf(stdout, "\tCompressed Write Throughput: %.2fMB/s\n", - MB_PER_SEC(file_size, total_time)); - HDfprintf(stdout, "\tCompression Time: %gs\n", compression_time); - - HDunlink(filename); - HDfree(src); - } -} - -/* - * Function: main - * Purpose: Run the program - * Return: EXIT_SUCCESS or EXIT_FAILURE - * Programmer: Bill Wendling, 05. June 2002 - * Modifications: - */ -int -main(int argc, char **argv) -{ - unsigned long min_buf_size = 128 * ONE_KB, max_buf_size = ONE_MB; - unsigned long file_size = 64 * ONE_MB; - int opt; - - prog = argv[0]; - - /* Initialize h5tools lib */ - h5tools_init(); - - while ((opt = get_option(argc, (const char **)argv, s_opts, l_opts)) > 0) { - switch ((char)opt) { - case '0': case '1': case '2': - case '3': case '4': case '5': - case '6': case '7': case '8': - case '9': - compress_level = opt - '0'; - break; - case 'B': - max_buf_size = parse_size_directive(opt_arg); - break; - case 'b': - min_buf_size = parse_size_directive(opt_arg); - break; - case 'c': - compress_percent = (int)HDstrtol(opt_arg, NULL, 10); - - if (compress_percent < 0) - compress_percent = 0; - else if (compress_percent > 100) - compress_percent = 100; - - break; - case 'p': - option_prefix = opt_arg; - break; - case 'r': - random_test = TRUE; - break; - case 's': - file_size = parse_size_directive(opt_arg); - break; - case '?': - usage(); - exit(EXIT_FAILURE); - break; - case 'h': - default: - usage(); - exit(EXIT_SUCCESS); - break; - } - } - - if (min_buf_size > max_buf_size) - error("minmum buffer size (%d) exceeds maximum buffer size (%d)", - min_buf_size, max_buf_size); - - HDfprintf(stdout, "Filesize: %ld\n", file_size); - - if (compress_level == Z_DEFAULT_COMPRESSION) - HDfprintf(stdout, "Compression Level: 6\n"); - else - HDfprintf(stdout, "Compression Level: %d\n", compress_level); - - get_unique_name(); - do_write_test(file_size, min_buf_size, max_buf_size); - cleanup(); - return EXIT_SUCCESS; -} - -#else - -/* - * Function: main - * Purpose: Dummy main() function for if HDF5 was configured without - * zlib stuff. - * Return: EXIT_SUCCESS - * Programmer: Bill Wendling, 10. June 2002 - * Modifications: - */ -int -main(void) -{ - HDfprintf(stdout, "No compression IO performance because zlib was not configured\n"); - return EXIT_SUCCESS; -} - -#endif /* !H5_HAVE_FILTER_DEFLATE */ |