summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Henderson <jhenderson@hdfgroup.org>2017-08-11 19:25:33 (GMT)
committerJordan Henderson <jhenderson@hdfgroup.org>2017-08-11 19:25:33 (GMT)
commitc34ee0b2a5fe8c142f58f31e44fd6eb53ecf8ba6 (patch)
tree8cc64cb219d19230d8f9454e19693610cb33a2b0
parent1eb775801535d787c521caaf72d68856eeb3b09c (diff)
parenta6d5bf1a86250cc660cd1ed420eeda6940792be5 (diff)
downloadhdf5-c34ee0b2a5fe8c142f58f31e44fd6eb53ecf8ba6.zip
hdf5-c34ee0b2a5fe8c142f58f31e44fd6eb53ecf8ba6.tar.gz
hdf5-c34ee0b2a5fe8c142f58f31e44fd6eb53ecf8ba6.tar.bz2
Merge branch 'develop' of https://bitbucket.hdfgroup.org/scm/hdffv/hdf5 into develop
-rw-r--r--MANIFEST19
-rwxr-xr-xbin/trace4
-rw-r--r--config/cmake_ext_mod/HDFLibMacros.cmake10
-rw-r--r--config/linux-gnulibc163
-rw-r--r--configure.ac39
-rw-r--r--fortran/examples/Makefile.am4
-rw-r--r--fortran/src/h5fc.in2
-rw-r--r--hl/fortran/examples/Makefile.am4
-rw-r--r--hl/tools/h5watch/CMakeTests.cmake11
-rw-r--r--java/src/jni/h5Constants.c1
-rw-r--r--java/test/TestH5PL.java88
-rw-r--r--release_docs/RELEASE.txt55
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/H5Dchunk.c7
-rw-r--r--src/H5Ddeprec.c5
-rw-r--r--src/H5Dint.c14
-rw-r--r--src/H5Fprivate.h4
-rw-r--r--src/H5MF.c2
-rw-r--r--src/H5MFsection.c34
-rw-r--r--src/H5PL.c987
-rw-r--r--src/H5PLextern.h4
-rw-r--r--src/H5PLint.c384
-rw-r--r--src/H5PLmodule.h10
-rw-r--r--src/H5PLpath.c776
-rw-r--r--src/H5PLpkg.h113
-rw-r--r--src/H5PLplugin_cache.c307
-rw-r--r--src/H5PLprivate.h4
-rw-r--r--src/H5PLpublic.h34
-rw-r--r--src/H5Pfcpl.c3
-rw-r--r--src/H5Smpio.c504
-rw-r--r--src/H5VMprivate.h6
-rw-r--r--src/H5system.c46
-rw-r--r--src/H5win32defs.h1
-rw-r--r--src/Makefile.am2
-rw-r--r--test/dsets.c97
-rw-r--r--test/fheap.c16
-rw-r--r--test/plugin.c487
-rw-r--r--test/tfile.c17
-rw-r--r--test/tmisc.c282
-rw-r--r--testpar/CMakeLists.txt1
-rw-r--r--testpar/Makefile.am2
-rw-r--r--testpar/t_bigio.c2153
-rw-r--r--tools/lib/h5diff.c2
-rw-r--r--tools/lib/h5diff_array.c20
-rw-r--r--tools/lib/h5tools.c6
-rw-r--r--tools/lib/h5tools_dump.c6
-rw-r--r--tools/lib/h5tools_ref.c2
-rw-r--r--tools/lib/h5tools_str.c8
-rw-r--r--tools/lib/h5tools_utils.c10
-rw-r--r--tools/lib/io_timer.c7
-rw-r--r--tools/lib/ph5diff.h4
-rw-r--r--tools/src/h5copy/h5copy.c2
-rw-r--r--tools/src/h5diff/h5diff_common.c2
-rw-r--r--tools/src/h5diff/h5diff_main.c3
-rw-r--r--tools/src/h5diff/ph5diff_main.c3
-rw-r--r--tools/src/h5dump/h5dump.c2
-rw-r--r--tools/src/h5dump/h5dump_ddl.c2
-rw-r--r--tools/src/h5dump/h5dump_xml.c10
-rw-r--r--tools/src/h5repack/h5repack.c4
-rw-r--r--tools/src/h5stat/h5stat.c2
-rw-r--r--tools/src/misc/h5mkgrp.c2
-rw-r--r--tools/src/misc/h5repart.c34
-rw-r--r--tools/test/h5copy/h5copygentest.c1
-rw-r--r--tools/test/h5diff/CMakeTests.cmake11
-rw-r--r--tools/test/h5diff/testfiles/h5diff_vlstr.txt16
-rw-r--r--tools/test/h5diff/testh5diff.sh.in5
-rw-r--r--tools/test/h5dump/CMakeTestsXML.cmake7
-rw-r--r--tools/test/h5dump/h5dumpgentest.c1
-rw-r--r--tools/test/h5dump/testh5dumpxml.sh.in5
-rw-r--r--tools/test/h5import/h5importtest.c1
-rw-r--r--tools/test/h5jam/h5jamgentest.c2
-rw-r--r--tools/test/h5jam/tellub.c6
-rw-r--r--tools/test/h5repack/CMakeTests.cmake97
-rw-r--r--tools/test/h5repack/h5repack.sh.in103
-rw-r--r--tools/test/h5repack/testfiles/GS.h5repack_paged_nopersist.h5.ddl15
-rw-r--r--tools/test/h5repack/testfiles/S.h5repack_fsm_aggr_persist.h5.ddl15
-rw-r--r--tools/test/h5repack/testfiles/SP.h5repack_fsm_aggr_nopersist.h5.ddl16
-rw-r--r--tools/test/h5repack/testfiles/SP.h5repack_paged_persist.h5.ddl15
-rw-r--r--tools/test/h5repack/testfiles/SPT.h5repack_aggr.h5.ddl16
-rw-r--r--tools/test/h5repack/testfiles/STG.h5repack_none.h5.ddl15
-rw-r--r--tools/test/h5repack/testfiles/h5repack_aggr.h5bin0 -> 2448 bytes
-rw-r--r--tools/test/h5repack/testfiles/h5repack_fsm_aggr_nopersist.h5bin0 -> 2448 bytes
-rw-r--r--tools/test/h5repack/testfiles/h5repack_fsm_aggr_persist.h5bin0 -> 2565 bytes
-rw-r--r--tools/test/h5repack/testfiles/h5repack_none.h5bin0 -> 1808 bytes
-rw-r--r--tools/test/h5repack/testfiles/h5repack_paged_nopersist.h5bin0 -> 8192 bytes
-rw-r--r--tools/test/h5repack/testfiles/h5repack_paged_persist.h5bin0 -> 16384 bytes
-rw-r--r--tools/test/h5repack/testh5repack_detect_szip.c1
-rw-r--r--tools/test/misc/repart_test.c95
-rw-r--r--tools/test/misc/talign.c3
-rw-r--r--tools/test/perform/CMakeTests.cmake1
-rw-r--r--tools/testfiles/test35.ncbin0 -> 14297 bytes
-rw-r--r--tools/testfiles/test35.nc.xml20
92 files changed, 5765 insertions, 1438 deletions
diff --git a/MANIFEST b/MANIFEST
index beaad19..dda7af8 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -799,8 +799,11 @@
./src/H5PBpkg.h
./src/H5PBprivate.h
./src/H5PL.c
+./src/H5PLint.c
./src/H5PLmodule.h
+./src/H5PLpath.c
./src/H5PLpkg.h
+./src/H5PLplugin_cache.c
./src/H5PLprivate.h
./src/H5PLpublic.h
./src/H5PLextern.h
@@ -1222,6 +1225,7 @@
./testpar/COPYING
./testpar/Makefile.am
+./testpar/t_bigio.c
./testpar/t_cache.c
./testpar/t_cache_image.c
./testpar/t_chunk_alloc.c
@@ -2090,6 +2094,8 @@
./tools/testfiles/tdset2.h5.xml
./tools/testfiles/tempty.h5.xml
./tools/testfiles/tenum.h5.xml
+./tools/testfiles/test35.nc
+./tools/testfiles/test35.nc.xml
./tools/testfiles/tfpformat.h5.xml
./tools/testfiles/tgroup.h5.xml
./tools/testfiles/thlink.h5.xml
@@ -2399,6 +2405,7 @@
./tools/test/h5diff/testfiles/h5diff_udfail.txt
./tools/test/h5diff/testfiles/diff_strings1.h5
./tools/test/h5diff/testfiles/diff_strings2.h5
+./tools/test/h5diff/testfiles/h5diff_vlstr.txt
#vds
./tools/test/h5diff/testfiles/h5diff_v1.txt
./tools/test/h5diff/testfiles/h5diff_v2.txt
@@ -2406,6 +2413,7 @@
#test files for h5repack
./tools/test/h5repack/testfiles/README
+./tools/test/h5repack/testfiles/h5repack_aggr.h5
./tools/test/h5repack/testfiles/h5repack_attr.h5
./tools/test/h5repack/testfiles/h5repack_attr_refs.h5
./tools/test/h5repack/testfiles/h5repack_deflate.h5
@@ -2415,6 +2423,8 @@
./tools/test/h5repack/testfiles/h5repack_fill.h5
./tools/test/h5repack/testfiles/h5repack_filters.h5
./tools/test/h5repack/testfiles/h5repack_fletcher.h5
+./tools/test/h5repack/testfiles/h5repack_fsm_aggr_nopersist.h5
+./tools/test/h5repack/testfiles/h5repack_fsm_aggr_persist.h5
./tools/test/h5repack/testfiles/h5repack_hlink.h5
./tools/test/h5repack/testfiles/h5repack.info
./tools/test/h5repack/testfiles/h5repack_layout.h5
@@ -2426,7 +2436,10 @@
./tools/test/h5repack/testfiles/h5repack_nested_8bit_enum_deflated.h5
./tools/test/h5repack/testfiles/h5repack_nested_8bit_enum.h5
./tools/test/h5repack/testfiles/h5repack_nbit.h5
+./tools/test/h5repack/testfiles/h5repack_none.h5
./tools/test/h5repack/testfiles/h5repack_objs.h5
+./tools/test/h5repack/testfiles/h5repack_paged_nopersist.h5
+./tools/test/h5repack/testfiles/h5repack_paged_persist.h5
./tools/test/h5repack/testfiles/h5repack_refs.h5
./tools/test/h5repack/testfiles/h5repack_shuffle.h5
./tools/test/h5repack/testfiles/h5repack_soffset.h5
@@ -2445,6 +2458,12 @@
./tools/test/h5repack/testfiles/h5repack_layout.h5-plugin_test.ddl
./tools/test/h5repack/testfiles/h5repack_layout.h5-plugin_version_test.ddl
./tools/test/h5repack/testfiles/h5repack_layout.h5-plugin_zero.tst
+./tools/test/h5repack/testfiles/GS.h5repack_paged_nopersist.h5.ddl
+./tools/test/h5repack/testfiles/S.h5repack_fsm_aggr_persist.h5.ddl
+./tools/test/h5repack/testfiles/SP.h5repack_fsm_aggr_nopersist.h5.ddl
+./tools/test/h5repack/testfiles/SP.h5repack_paged_persist.h5.ddl
+./tools/test/h5repack/testfiles/SPT.h5repack_aggr.h5.ddl
+./tools/test/h5repack/testfiles/STG.h5repack_none.h5.ddl
./tools/test/h5repack/testfiles/1_vds.h5-vds_dset_chunk20x10x5-v.ddl
./tools/test/h5repack/testfiles/2_vds.h5-vds_chunk3x6x9-v.ddl
./tools/test/h5repack/testfiles/3_1_vds.h5-vds_chunk2x5x8-v.ddl
diff --git a/bin/trace b/bin/trace
index 3f532ab..cf41238 100755
--- a/bin/trace
+++ b/bin/trace
@@ -76,7 +76,7 @@ $Source = "";
"off_t" => "o",
"H5O_type_t" => "Ot",
"H5P_class_t" => "p",
- "hobj_ref_t" => "r",
+ "hobj_ref_t" => "r",
"H5R_type_t" => "Rt",
"char" => "s",
"unsigned char" => "s",
@@ -124,7 +124,7 @@ $Source = "";
"H5G_iterate_t" => "x",
"H5G_info_t" => "x",
"H5I_free_t" => "x",
- "H5I_search_func_t" => "x",
+ "H5I_search_func_t" => "x",
"H5L_class_t" => "x",
"H5L_elink_traverse_t" => "x",
"H5L_iterate_t" => "x",
diff --git a/config/cmake_ext_mod/HDFLibMacros.cmake b/config/cmake_ext_mod/HDFLibMacros.cmake
index f2e03d7..54e408b 100644
--- a/config/cmake_ext_mod/HDFLibMacros.cmake
+++ b/config/cmake_ext_mod/HDFLibMacros.cmake
@@ -74,14 +74,14 @@ macro (EXTERNAL_JPEG_LIBRARY compress_type jpeg_pic)
HDF_IMPORT_SET_LIB_OPTIONS (jpeg-static "jpeg" STATIC "")
add_dependencies (JPEG jpeg-static)
set (JPEG_STATIC_LIBRARY "jpeg-static")
- set (JPEG_LIBRARIES ${JPEG_static_LIBRARY})
+ set (JPEG_LIBRARIES ${JPEG_STATIC_LIBRARY})
if (BUILD_SHARED_LIBS)
# Create imported target jpeg-shared
add_library(jpeg-shared SHARED IMPORTED)
HDF_IMPORT_SET_LIB_OPTIONS (jpeg-shared "jpeg" SHARED "")
add_dependencies (JPEG jpeg-shared)
set (JPEG_SHARED_LIBRARY "jpeg-shared")
- set (JPEG_LIBRARIES ${JPEG_LIBRARIES} ${JPEG_shared_LIBRARY})
+ set (JPEG_LIBRARIES ${JPEG_LIBRARIES} ${JPEG_SHARED_LIBRARY})
endif ()
set (JPEG_INCLUDE_DIR_GEN "${BINARY_DIR}")
@@ -167,14 +167,14 @@ macro (EXTERNAL_SZIP_LIBRARY compress_type encoding)
HDF_IMPORT_SET_LIB_OPTIONS (szip-static "szip" STATIC "")
add_dependencies (SZIP szip-static)
set (SZIP_STATIC_LIBRARY "szip-static")
- set (SZIP_LIBRARIES ${SZIP_static_LIBRARY})
+ set (SZIP_LIBRARIES ${SZIP_STATIC_LIBRARY})
if (BUILD_SHARED_LIBS)
# Create imported target szip-shared
add_library(szip-shared SHARED IMPORTED)
HDF_IMPORT_SET_LIB_OPTIONS (szip-shared "szip" SHARED "")
add_dependencies (SZIP szip-shared)
set (SZIP_SHARED_LIBRARY "szip-shared")
- set (SZIP_LIBRARIES ${SZIP_LIBRARIES} ${SZIP_shared_LIBRARY})
+ set (SZIP_LIBRARIES ${SZIP_LIBRARIES} ${SZIP_SHARED_LIBRARY})
endif ()
set (SZIP_INCLUDE_DIR_GEN "${BINARY_DIR}")
@@ -262,7 +262,7 @@ macro (EXTERNAL_ZLIB_LIBRARY compress_type)
HDF_IMPORT_SET_LIB_OPTIONS (zlib-static ${ZLIB_LIB_NAME} STATIC "")
add_dependencies (ZLIB zlib-static)
set (ZLIB_STATIC_LIBRARY "zlib-static")
- set (ZLIB_LIBRARIES ${ZLIB_static_LIBRARY})
+ set (ZLIB_LIBRARIES ${ZLIB_STATIC_LIBRARY})
if (BUILD_SHARED_LIBS)
# Create imported target zlib-shared
add_library(zlib-shared SHARED IMPORTED)
diff --git a/config/linux-gnulibc1 b/config/linux-gnulibc1
index 1785e0e..39225e7 100644
--- a/config/linux-gnulibc1
+++ b/config/linux-gnulibc1
@@ -84,7 +84,20 @@ else
$RM $tmpfile
fc_version_info=`$FC -V | grep Absoft`
;;
-
+ # The NAG compiler
+ nagfor*|nagftn*)
+ RM='rm -f'
+ tmpfile=/tmp/cmpver.$$
+ $FC -V >& $tmpfile
+ if test -s "$tmpfile"; then
+ if( grep -s 'NAG Fortran' $tmpfile > /dev/null) then
+ FC_BASENAME=nagfor
+ fi
+ fi
+ fc_version_info=`grep "NAG Fortran" $tmpfile`
+ echo "compiler '$FC' is $fc_version_info"
+ $RM $tmpfile
+ ;;
*)
;;
esac
@@ -108,10 +121,10 @@ case $FC_BASENAME in
#
f95)
# Set required flag for compiling C stubs
- H5_CFLAGS="$H5_CFLAGS"
+ H5_CFLAGS="$H5_CFLAGS"
F9XSUFFIXFLAG=""
-# We force compiler to use upper case for external names
+# We force compiler to use upper case for external names
# (just in case since this should be a default EIP)
H5_FCFLAGS="$H5_FCFLAGS"
FSEARCH_DIRS=""
@@ -136,6 +149,37 @@ case $FC_BASENAME in
f9x_flags_set=yes
;;
+#
+# NAG compiler
+#
+ nagfor)
+
+ F9XSUFFIXFLAG=""
+# We force compiler to use upper case for external names
+# (just in case since this should be a default EIP)
+ H5_FCFLAGS="$H5_FCFLAGS"
+ FSEARCH_DIRS=""
+
+ # Production
+ PROD_FCFLAGS=
+
+ # Debug
+ DEBUG_FCFLAGS="-C"
+
+ # Symbols
+ SYMBOLS_FCFLAGS="-g"
+ NO_SYMBOLS_FCFLAGS="-s"
+
+ # Profiling
+ PROFILE_FCFLAGS="-pg"
+
+ # Optimization
+ HIGH_OPT_FCFLAGS="-O"
+ DEBUG_OPT_FCFLAGS="-O0"
+ NO_OPT_FCFLAGS="-O0"
+
+ f9x_flags_set=yes
+ ;;
esac
@@ -230,6 +274,19 @@ case $FC in
*pgf90*)
fc_version_info=`$FC $FCFLAGS $H5_FCFLAGS -V 2>&1 | grep 'pgf90'`
;;
+ *nagfor*|*nagftn*)
+ RM='rm -f'
+ tmpfile=/tmp/cmpver.$$
+ $FC -V >& $tmpfile
+ if test -s "$tmpfile"; then
+ if( grep -s 'NAG Fortran' $tmpfile > /dev/null) then
+ FC_BASENAME=nagfor
+ fi
+ fi
+ fc_version_info=`grep "NAG Fortran" $tmpfile`
+ $RM $tmpfile
+ echo "compiler '$FC' is $fc_version_info"
+ ;;
*)
echo "No match to get fc_version_info for $FC"
diff --git a/configure.ac b/configure.ac
index 163f6d3..91800e7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3338,6 +3338,27 @@ else
STATIC_SHARED="none"
fi
+if test "X$HDF_FORTRAN" = "Xyes"; then
+
+ ### libtool does not pass the correct argument linking (-Wl,-Wl,,) for the NAG Fortran compiler
+ ### on Linux (other OSs have not been tested).
+ ### Therefore, detect if we are using the NAG Fortran compiler, and replace the wl="-Wl," for Fortran to
+ ### wl="-Wl,-Wl,," in the libtool file. (HDFFV-10037)
+ case "`uname`" in
+ Linux*)
+
+ fortran_linux_linker_option="-Wl,"
+ if test "X$FC_BASENAME" = "Xnagfor"; then
+ fortran_linux_linker_option="-Wl,-Wl,,"
+ fi
+
+ ## Set the correct linker option for use in h5fc.in markup
+ AC_SUBST([fortran_linux_linker_option])
+ ;;
+ esac
+
+fi
+
## ----------------------------------------------------------------------
## Set a macro if shared library is enabled.
##
@@ -3473,6 +3494,10 @@ AC_CONFIG_COMMANDS([.classes], [], [$MKDIR_P java/src/.classes;
AC_OUTPUT
chmod 755 tools/src/misc/h5cc
+if test "X$HDF_CXX" = "Xyes"; then
+ chmod 755 c++/src/h5c++
+fi
+
if test "X$HDF_FORTRAN" = "Xyes"; then
chmod 755 fortran/src/h5fc
@@ -3484,10 +3509,18 @@ if test "X$HDF_FORTRAN" = "Xyes"; then
cat libtool | awk '/wl=\"/{c++;if(c==3){sub("wl=\"\"","wl=\"-Wl,\"");c=0}}1' > libtool.tmp && mv -f libtool.tmp libtool && chmod 755 libtool
;;
esac
-fi
-if test "X$HDF_CXX" = "Xyes"; then
- chmod 755 c++/src/h5c++
+ ### libtool does not pass the correct argument linking (-Wl,-Wl,,) for the NAG Fortran compiler
+ ### on Linux (other OSs have not been tested).
+ ### Therefore, detect if we are using the NAG Fortran compiler, and replace the wl="-Wl," for Fortran to
+ ### wl="-Wl,-Wl,," in the libtool file. (HDFFV-10037)
+ case "`uname`" in
+ Linux*)
+ if test "X$FC_BASENAME" = "Xnagfor"; then
+ cat libtool | awk '/NAG_Fortran/{flag=1}flag&&/wl=/{$NF="wl=\"-Wl,Wl,,\"";flag=0}1' > libtool.tmp && mv -f libtool.tmp libtool && chmod 755 libtool
+ fi
+ ;;
+ esac
fi
## HDF5 configure code created by autotools with gcc 4.9.2 is adding problematic
diff --git a/fortran/examples/Makefile.am b/fortran/examples/Makefile.am
index db85c09..6bf2edb 100644
--- a/fortran/examples/Makefile.am
+++ b/fortran/examples/Makefile.am
@@ -66,10 +66,10 @@ h5_crtatt.chkexe_: h5_rdwt.chkexe_
# Additional dependencies for the examples are listed below
if BUILD_PARALLEL_CONDITIONAL
$(EXTRA_PROG): $(H5FC_PP)
- $(H5FC_PP) $(H5CCFLAGS) $(FCFLAGS) -o $@ $(srcdir)/$@.f90;
+ $(H5FC_PP) $(H5CCFLAGS) -o $@ $(srcdir)/$@.f90;
else
$(EXTRA_PROG): $(H5FC)
- $(H5FC) $(H5CCFLAGS) $(FCFLAGS) -o $@ $(srcdir)/$@.f90;
+ $(H5FC) $(H5CCFLAGS) -o $@ $(srcdir)/$@.f90;
endif
# Tell automake how to install examples
diff --git a/fortran/src/h5fc.in b/fortran/src/h5fc.in
index 47642c9..29ef83f 100644
--- a/fortran/src/h5fc.in
+++ b/fortran/src/h5fc.in
@@ -307,7 +307,7 @@ if test "x$do_link" = "xyes"; then
link_args="$link_args -L${libdir}"
case "$host_os" in
- linux*) flag="-Wl,-rpath -Wl," ;;
+ linux*) flag="@fortran_linux_linker_option@-rpath -Wl," ;;
hpux*) flag="-Wl,+b -Wl," ;;
freebsd*|solaris*) flag="-R" ;;
rs6000*|aix*) flag="-L" ;;
diff --git a/hl/fortran/examples/Makefile.am b/hl/fortran/examples/Makefile.am
index 6709fb7..d383f9a 100644
--- a/hl/fortran/examples/Makefile.am
+++ b/hl/fortran/examples/Makefile.am
@@ -43,10 +43,10 @@ FORTRAN_API=yes
# Tell automake how to build examples using h5fc
if BUILD_PARALLEL_CONDITIONAL
$(EXTRA_PROG): $(H5FC_PP)
- $(H5FC_PP) $(H5CCFLAGS) $(FCFLAGS) -o $@ $(srcdir)/$@.f90;
+ $(H5FC_PP) $(H5CCFLAGS) -o $@ $(srcdir)/$@.f90;
else
$(EXTRA_PROG): $(H5FC)
- $(H5FC) $(H5CCFLAGS) $(FCFLAGS) -o $@ $(srcdir)/$@.f90;
+ $(H5FC) $(H5CCFLAGS) -o $@ $(srcdir)/$@.f90;
endif
# Tell automake how to install examples
diff --git a/hl/tools/h5watch/CMakeTests.cmake b/hl/tools/h5watch/CMakeTests.cmake
index 35e7829..0b7b4d4 100644
--- a/hl/tools/h5watch/CMakeTests.cmake
+++ b/hl/tools/h5watch/CMakeTests.cmake
@@ -56,18 +56,11 @@ set (H5WATCH_TEST_FILES
# make test dir
file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles")
-add_custom_target(h5watch-files ALL COMMENT "Copying files needed by h5watch tests")
foreach (h5watch_file ${H5WATCH_TEST_FILES})
- set (dest "${PROJECT_BINARY_DIR}/testfiles/${h5watch_file}")
- #message (STATUS " Copying ${h5watch_file}")
- add_custom_command (
- TARGET h5watch-files
- POST_BUILD
- COMMAND ${CMAKE_COMMAND}
- ARGS -E copy_if_different ${HDF5_HL_TOOLS_DIR}/testfiles/${h5watch_file} ${dest}
- )
+ HDFTEST_COPY_FILE("${HDF5_HL_TOOLS_DIR}/testfiles/${h5watch_file}" "${PROJECT_BINARY_DIR}/testfiles/${h5watch_file}" "H5WATCH_files")
endforeach ()
+add_custom_target(H5WATCH_files ALL COMMENT "Copying files needed by H5WATCH tests" DEPENDS ${H5WATCH_files_list})
##############################################################################
##############################################################################
diff --git a/java/src/jni/h5Constants.c b/java/src/jni/h5Constants.c
index d4511e1..f6f8bfa 100644
--- a/java/src/jni/h5Constants.c
+++ b/java/src/jni/h5Constants.c
@@ -26,6 +26,7 @@ extern "C" {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
JNIEXPORT jlong JNICALL
Java_hdf_hdf5lib_HDF5Constants_H5_1QUARTER_1HADDR_1MAX(JNIEnv *env, jclass cls) { return (hsize_t)HADDR_MAX/4; }
diff --git a/java/test/TestH5PL.java b/java/test/TestH5PL.java
index aa59478..8ce708b 100644
--- a/java/test/TestH5PL.java
+++ b/java/test/TestH5PL.java
@@ -70,26 +70,74 @@ public class TestH5PL {
@Test
public void TestH5PLpaths() {
try {
- int original_entries = H5.H5PLsize();
- H5.H5PLappend("path_one");
- int plugin_entries = H5.H5PLsize();
- assertTrue("H5.H5PLsize: "+plugin_entries, (original_entries+1) == plugin_entries);
- H5.H5PLprepend("path_two");
- plugin_entries = H5.H5PLsize();
- assertTrue("H5.H5PLsize: "+plugin_entries, (original_entries+2) == plugin_entries);
- H5.H5PLinsert("path_three", original_entries);
- plugin_entries = H5.H5PLsize();
- assertTrue("H5.H5PLsize: "+plugin_entries, (original_entries+3) == plugin_entries);
- String first_path = H5.H5PLget(original_entries);
- assertTrue("First path was : "+first_path + " ",first_path.compareToIgnoreCase("path_three")==0);
- H5.H5PLreplace("path_four", original_entries);
- first_path = H5.H5PLget(original_entries);
- assertTrue("First path changed to : "+first_path + " ",first_path.compareToIgnoreCase("path_four")==0);
- H5.H5PLremove(original_entries);
- first_path = H5.H5PLget(original_entries);
- assertTrue("First path now : "+first_path + " ",first_path.compareToIgnoreCase("path_two")==0);
- plugin_entries = H5.H5PLsize();
- assertTrue("H5.H5PLsize: "+plugin_entries, (original_entries+2) == plugin_entries);
+ // Get the original number of paths
+ int nStartPaths = H5.H5PLsize();
+
+ int nPaths; /* # paths from H5PLSize() */
+ int nTruePaths = nStartPaths; /* What the # paths should be */
+ int index; /* Path table index */
+ String path; /* Path from H5PLget() */
+
+ // APPEND a path and ensure it was added correctly
+ String pathAppend = "path_append";
+ H5.H5PLappend(pathAppend);
+
+ nPaths = H5.H5PLsize();
+ nTruePaths++;
+ assertTrue("# paths should be " + nTruePaths + " but was " + nPaths, nTruePaths == nPaths);
+
+ index = nTruePaths - 1;
+ path = H5.H5PLget(index);
+ assertTrue("Path should be " + pathAppend + " but was " + path, path.compareToIgnoreCase(pathAppend) == 0);
+
+ // PREPEND a path and ensure it was added correctly
+ String pathPrepend = "path_prepend";
+ H5.H5PLprepend(pathPrepend);
+
+ nPaths = H5.H5PLsize();
+ nTruePaths++;
+ assertTrue("# paths should be " + nTruePaths + " but was " + nPaths, nTruePaths == nPaths);
+
+ index = 0;
+ path = H5.H5PLget(index);
+ assertTrue("Path should be " + pathPrepend + " but was " + path, path.compareToIgnoreCase(pathPrepend) == 0);
+
+ // INSERT a path and ensure it was added correctly
+ // Inserting at the index == # of start paths ensures we're in the middle
+ String pathInsert = "path_insert";
+ index = nStartPaths;
+ H5.H5PLinsert(pathInsert, index);
+
+ nPaths = H5.H5PLsize();
+ nTruePaths++;
+ assertTrue("# paths should be " + nTruePaths + " but was " + nPaths, nTruePaths == nPaths);
+
+ path = H5.H5PLget(index);
+ assertTrue("Path should be " + pathInsert + " but was " + path, path.compareToIgnoreCase(pathInsert) == 0);
+
+ // REPLACE the path we just added and ensure it updated correctly
+ String pathReplace = "path_replace";
+ index = nStartPaths;
+ H5.H5PLreplace(pathReplace, index);
+
+ nPaths = H5.H5PLsize();
+ assertTrue("# paths should be " + nTruePaths + " but was " + nPaths, nTruePaths == nPaths);
+
+ path = H5.H5PLget(index);
+ assertTrue("Path should be " + pathReplace + " but was " + path, path.compareToIgnoreCase(pathReplace) == 0);
+
+ // REMOVE the path we just replaced and check that the table was compacted
+ // The (index+1) path should move down to fill the space when the path is removed.
+ index = nStartPaths;
+ String pathRemove = H5.H5PLget(index + 1);
+ H5.H5PLremove(index);
+
+ nPaths = H5.H5PLsize();
+ nTruePaths--;
+ assertTrue("# paths should be " + nTruePaths + " but was " + nPaths, nTruePaths == nPaths);
+
+ path = H5.H5PLget(index);
+ assertTrue("Path should be " + pathRemove + " but was " + path, path.compareToIgnoreCase(pathRemove) == 0);
}
catch (Throwable err) {
err.printStackTrace();
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 20d58b3..2dbe7e9 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -62,7 +62,29 @@ New Features
Parallel Library:
-----------------
- -
+ - Large MPI-IO transfers
+
+ Previous releases of PHDF5 would fail when attempting to
+ read or write greater than 2GB of data in a single IO operation.
+ This issue stems principally from an MPI API whose definitions
+ utilize 32 bit integers to describe the number of data elements
+ and datatype that MPI should use to effect a data transfer.
+ Historically, HDF5 has invoked MPI-IO with the number of
+ elements in a contiguous buffer represented as the length
+ of that buffer in bytes.
+
+ Resolving the issue and thus enabling larger MPI-IO transfers
+ is accomplished first, by detecting when a user IO request would
+ exceed the 2GB limit as described above. Once a transfer request
+ is identified as requiring special handling, PHDF5 now creates a
+ derived datatype consisting of a vector of fixed sized blocks
+ which is in turn wrapped within a single MPI_Type_struct to
+ contain the vector and any remaining data. The newly created
+ datatype is then used in place of MPI_BYTE and can be used to
+ fulfill the original user request without encountering API
+ errors.
+
+ (RAW – 2017/07/11, HDFFV-8839)
Fortran Library:
----------------
@@ -105,7 +127,15 @@ Bug Fixes since HDF5-1.10.1 release
Configuration
-------------
- -
+ - cmake
+
+ Too many commands for POST_BUILD step caused command line to be
+ too big on windows.
+
+ Changed foreach of copy command to use a custom command with the
+ use of the HDFTEST_COPY_FILE macro.
+
+ (ADB - 2017/07/12, HDFFV-10254)
Performance
-------------
@@ -117,6 +147,25 @@ Bug Fixes since HDF5-1.10.1 release
Tools
-----
+ - h5dump
+
+ h5dump segfaulted on output of XML file.
+
+ Function that escape'd strings used the full buffer length
+ instead of just the length of the replacement string in a
+ strncpy call. Using the correct length fixed the issue.
+
+ (ADB - 2017/08/01, HDFFV-10256)
+
+ - h5diff
+
+ h5diff segfaulted on compare of a NULL variable length string.
+
+ Improved h5diff compare of strings by adding a check for
+ NULL strings and setting the lengths to zero.
+
+ (ADB - 2017/07/25, HDFFV-10246)
+
- h5import
h5import crashed trying to import data from a subset of a dataset.
@@ -127,7 +176,7 @@ Bug Fixes since HDF5-1.10.1 release
The import from h5dump function expects the binary files to use native
types (FILE '-b' option) in the binary file.
- (ADB - 2017/06/15, HDFFV-102191)
+ (ADB - 2017/06/15, HDFFV-10219)
- h5repack
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 178c954..96ea589 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -516,6 +516,9 @@ IDE_GENERATED_PROPERTIES ("H5PB" "${H5PB_HDRS}" "${H5PB_SOURCES}" )
set (H5PL_SOURCES
${HDF5_SRC_DIR}/H5PL.c
+ ${HDF5_SRC_DIR}/H5PLint.c
+ ${HDF5_SRC_DIR}/H5PLpath.c
+ ${HDF5_SRC_DIR}/H5PLplugin_cache.c
)
set (H5PL_HDRS
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index e26581c..af6599a 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -1016,11 +1016,16 @@ H5D__chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, hid_t dapl_id)
unsigned u; /* Local index value */
for(u = 0; u < dset->shared->ndims; u++) {
+ hsize_t scaled_power2up; /* Scaled value, rounded to next power of 2 */
+
/* Initial scaled dimension sizes */
rdcc->scaled_dims[u] = dset->shared->curr_dims[u] / dset->shared->layout.u.chunk.dim[u];
+ if( !(scaled_power2up = H5VM_power2up(rdcc->scaled_dims[u])) )
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get the next power of 2")
+
/* Inital 'power2up' values for scaled dimensions */
- rdcc->scaled_power2up[u] = H5VM_power2up(rdcc->scaled_dims[u]);
+ rdcc->scaled_power2up[u] = scaled_power2up;
/* Number of bits required to encode scaled dimension size */
rdcc->scaled_encode_bits[u] = H5VM_log2_gen(rdcc->scaled_power2up[u]);
diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c
index 8d9461c..0807048 100644
--- a/src/H5Ddeprec.c
+++ b/src/H5Ddeprec.c
@@ -329,8 +329,11 @@ H5D__extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
dataset->shared->cache.chunk.scaled_dims[u] > dataset->shared->cache.chunk.nslots))
update_chunks = TRUE;
+ if( !(scaled_power2up = H5VM_power2up(scaled)) )
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get the next power of 2")
+
/* Check if the number of bits required to encode the scaled size value changed */
- if(dataset->shared->cache.chunk.scaled_power2up[u] != (scaled_power2up = H5VM_power2up(scaled))) {
+ if(dataset->shared->cache.chunk.scaled_power2up[u] != scaled_power2up) {
/* Update the 'power2up' & 'encode_bits' values for the current dimension */
dataset->shared->cache.chunk.scaled_power2up[u] = scaled_power2up;
dataset->shared->cache.chunk.scaled_encode_bits[u] = H5VM_log2_gen(scaled_power2up);
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 0928afe..bdedd1e 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -745,8 +745,13 @@ H5D__cache_dataspace_info(const H5D_t *dset)
dset->shared->ndims = (unsigned)sndims;
/* Compute the inital 'power2up' values */
- for(u = 0; u < dset->shared->ndims; u++)
- dset->shared->curr_power2up[u] = H5VM_power2up(dset->shared->curr_dims[u]);
+ for(u = 0; u < dset->shared->ndims; u++) {
+ hsize_t scaled_power2up; /* Scaled value, rounded to next power of 2 */
+
+ if( !(scaled_power2up = H5VM_power2up(dset->shared->curr_dims[u])) )
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get the next power of 2")
+ dset->shared->curr_power2up[u] = scaled_power2up;
+ }
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2805,8 +2810,11 @@ H5D__set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
dset->shared->cache.chunk.scaled_dims[u] > dset->shared->cache.chunk.nslots))
update_chunks = TRUE;
+ if( !(scaled_power2up = H5VM_power2up(scaled)) )
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get the next power of 2")
+
/* Check if the number of bits required to encode the scaled size value changed */
- if(dset->shared->cache.chunk.scaled_power2up[u] != (scaled_power2up = H5VM_power2up(scaled))) {
+ if(dset->shared->cache.chunk.scaled_power2up[u] != scaled_power2up) {
/* Update the 'power2up' & 'encode_bits' values for the current dimension */
dset->shared->cache.chunk.scaled_power2up[u] = scaled_power2up;
dset->shared->cache.chunk.scaled_encode_bits[u] = H5VM_log2_gen(scaled_power2up);
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 6f68a62..eba48de 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -549,9 +549,11 @@
#define H5F_FILE_SPACE_PAGE_SIZE_DEF 4096
/* For paged aggregation: minimum value for file space page size */
#define H5F_FILE_SPACE_PAGE_SIZE_MIN 512
+/* For paged aggregation: maxiumum value for file space page size: 1 gigabyte */
+#define H5F_FILE_SPACE_PAGE_SIZE_MAX 1024*1024*1024
/* For paged aggregation: drop free-space with size <= this threshold for small meta section */
-#define H5F_FILE_SPACE_PGEND_META_THRES 10
+#define H5F_FILE_SPACE_PGEND_META_THRES 0
/* Default for threshold for alignment (can be set via H5Pset_alignment()) */
#define H5F_ALIGN_DEF 1
diff --git a/src/H5MF.c b/src/H5MF.c
index e54d809..d7af56a 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -1519,7 +1519,7 @@ H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, hid_t dxpl_id, haddr_t addr,
H5AC_ring_t fsm_ring = H5AC_RING_INV; /* Ring of fsm */
H5F_mem_page_t fs_type; /* Free space type */
hbool_t reset_ring = FALSE; /* Whether the ring was set */
- htri_t ret_value = FAIL; /* Return value */
+ htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI_TAG(dxpl_id, H5AC__FREESPACE_TAG, FAIL)
#ifdef H5MF_ALLOC_DEBUG
diff --git a/src/H5MFsection.c b/src/H5MFsection.c
index 02fc2d9..02e3218 100644
--- a/src/H5MFsection.c
+++ b/src/H5MFsection.c
@@ -130,27 +130,27 @@ H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SIMPLE[1] = {{
/* Class info for "small" free space sections */
H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SMALL[1] = {{
/* Class variables */
- H5MF_FSPACE_SECT_SMALL, /* Section type */
- 0, /* Extra serialized size */
- H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */
- NULL, /* Class private info */
+ H5MF_FSPACE_SECT_SMALL, /* Section type */
+ 0, /* Extra serialized size */
+ H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */
+ NULL, /* Class private info */
/* Class methods */
- NULL, /* Initialize section class */
- NULL, /* Terminate section class */
+ NULL, /* Initialize section class */
+ NULL, /* Terminate section class */
/* Object methods */
- H5MF_sect_small_add, /* Add section */
- NULL, /* Serialize section */
+ H5MF_sect_small_add, /* Add section */
+ NULL, /* Serialize section */
H5MF_sect_deserialize, /* Deserialize section */
- H5MF_sect_small_can_merge, /* Can sections merge? */
- H5MF_sect_small_merge, /* Merge sections */
- H5MF_sect_small_can_shrink, /* Can section shrink container?*/
- H5MF_sect_small_shrink, /* Shrink container w/section */
- H5MF_sect_free, /* Free section */
- H5MF_sect_valid, /* Check validity of section */
- H5MF_sect_split, /* Split section node for alignment */
- NULL, /* Dump debugging for section */
+ H5MF_sect_small_can_merge, /* Can sections merge? */
+ H5MF_sect_small_merge, /* Merge sections */
+ NULL, /* Can section shrink container?*/
+ NULL, /* Shrink container w/section */
+ H5MF_sect_free, /* Free section */
+ H5MF_sect_valid, /* Check validity of section */
+ H5MF_sect_split, /* Split section node for alignment */
+ NULL, /* Dump debugging for section */
}};
/* Class info for "large" free space sections */
@@ -674,7 +674,7 @@ HDfprintf(stderr, "%s: Entering, section {%a, %Hu}\n", FUNC, (*sect)->sect_info.
HDfprintf(stderr, "%s: section is dropped\n", FUNC);
#endif /* H5MF_ALLOC_DEBUG_MORE */
} /* end if */
- /* Adjust the section if it is not at page end but its size + pgend threshold is at page end */
+ /* Adjust the section if it is not at page end but its size + prem is at page end */
else
if(prem <= H5F_PGEND_META_THRES(udata->f)) {
(*sect)->sect_info.size += prem;
diff --git a/src/H5PL.c b/src/H5PL.c
index 65d6c91..fc42554 100644
--- a/src/H5PL.c
+++ b/src/H5PL.c
@@ -22,135 +22,28 @@
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
-#include "H5MMprivate.h" /* Memory management */
#include "H5PLpkg.h" /* Plugin */
-#include "H5Zprivate.h" /* Filter pipeline */
/****************/
/* Local Macros */
/****************/
-#ifdef H5_HAVE_WIN32_API
-#define H5PL_EXPAND_ENV_VAR { \
- long bufCharCount; \
- char *tempbuf; \
- if(NULL == (tempbuf = (char *)H5MM_malloc(H5PL_EXPAND_BUFFER_SIZE))) \
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for expanded path") \
- if((bufCharCount = ExpandEnvironmentStringsA(dl_path, tempbuf, H5PL_EXPAND_BUFFER_SIZE)) > H5PL_EXPAND_BUFFER_SIZE) { \
- tempbuf = (char *)H5MM_xfree(tempbuf); \
- HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "expanded path is too long") \
- } \
- if(bufCharCount == 0) { \
- tempbuf = (char *)H5MM_xfree(tempbuf); \
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "failed to expand path") \
- } \
- dl_path = (char *)H5MM_xfree(dl_path); \
- dl_path = tempbuf; \
- }
-#else
-#define H5PL_EXPAND_ENV_VAR
-#endif /* H5_HAVE_WIN32_API */
-
-/****************************/
-/* Macros for supporting
- * both Windows and Unix */
-/****************************/
-/* Windows support
- *
- * SPECIAL WINDOWS NOTE
- *
- * Some of the Win32 API functions expand to fooA or fooW depending on
- * whether UNICODE or _UNICODE are defined. You MUST explicitly use
- * the A version of the functions to force char * behavior until we
- * work out a scheme for proper Windows Unicode support.
- *
- * If you do not do this, people will be unable to incorporate our
- * source code into their own CMake builds if they define UNICODE.
- */
-#ifdef H5_HAVE_WIN32_API
-
-#define H5PL_PATH_SEPARATOR ";"
-
-/* Handle for dynamic library */
-#define H5PL_HANDLE HINSTANCE
-
-/* Get a handle to a plugin library. Windows: TEXT macro handles Unicode strings */
-#define H5PL_OPEN_DLIB(S) LoadLibraryExA(S, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)
-
-/* Get the address of a symbol in dynamic library */
-#define H5PL_GET_LIB_FUNC(H,N) GetProcAddress(H,N)
-
-/* Close dynamic library */
-#define H5PL_CLOSE_LIB(H) FreeLibrary(H)
-
-/* Clear error - nothing to do */
-#define H5PL_CLR_ERROR
-
-/* maximum size for expanding env vars */
-#define H5PL_EXPAND_BUFFER_SIZE 32767
-
-typedef const void *(__cdecl *H5PL_get_plugin_info_t)(void);
-
-/* Unix support */
-#else /* H5_HAVE_WIN32_API */
-
-#define H5PL_PATH_SEPARATOR ":"
-
-/* Handle for dynamic library */
-#define H5PL_HANDLE void *
-
-/* Get a handle to a plugin library. Windows: TEXT macro handles Unicode strings */
-#define H5PL_OPEN_DLIB(S) dlopen(S, RTLD_LAZY)
-
-/* Get the address of a symbol in dynamic library */
-#define H5PL_GET_LIB_FUNC(H,N) dlsym(H,N)
-
-/* Close dynamic library */
-#define H5PL_CLOSE_LIB(H) dlclose(H)
-
-/* Clear error */
-#define H5PL_CLR_ERROR HERROR(H5E_PLUGIN, H5E_CANTGET, "can't dlopen:%s", dlerror())
-
-typedef const void *(*H5PL_get_plugin_info_t)(void);
-#endif /* H5_HAVE_WIN32_API */
-
-/* Whether to preload pathnames for plugin libraries */
-#define H5PL_DEFAULT_PATH H5_DEFAULT_PLUGINDIR
-
-/* Special symbol to indicate no plugin loading */
-#define H5PL_NO_PLUGIN "::"
/******************/
/* Local Typedefs */
/******************/
-/* Type for the list of info for opened plugin libraries */
-typedef struct H5PL_table_t {
- H5PL_type_t pl_type; /* plugin type */
- int pl_id; /* ID for the plugin */
- H5PL_HANDLE handle; /* plugin handle */
-} H5PL_table_t;
-
/********************/
/* Local Prototypes */
/********************/
-static herr_t H5PL__init_path_table(void);
-static htri_t H5PL__find(H5PL_type_t plugin_type, int type_id, char *dir, const void **info);
-static htri_t H5PL__open(H5PL_type_t pl_type, char *libname, int plugin_id, const void **pl_info);
-static htri_t H5PL__search_table(H5PL_type_t plugin_type, int type_id, const void **info);
-static herr_t H5PL__close(H5PL_HANDLE handle);
-
/*********************/
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
@@ -161,145 +54,43 @@ hbool_t H5_PKG_INIT_VAR = FALSE;
/* Local Variables */
/*******************/
-/* Table for opened plugin libraries */
-static size_t H5PL_table_alloc_g = 0;
-static size_t H5PL_table_used_g = 0;
-static H5PL_table_t *H5PL_table_g = NULL;
-
-/* Table of location paths for plugin libraries */
-static char *H5PL_path_table_g[H5PL_MAX_PATH_NUM];
-static size_t H5PL_num_paths_g = 0;
-static hbool_t H5PL_path_found_g = FALSE;
-
-/* Enable all plugin libraries */
-static unsigned int H5PL_plugin_g = H5PL_ALL_PLUGIN;
-
-
-
-/*--------------------------------------------------------------------------
-NAME
- H5PL__init_package -- Initialize interface-specific information
-USAGE
- herr_t H5PL__init_package()
-RETURNS
- Non-negative on success/Negative on failure
-DESCRIPTION
- Initializes any interface-specific data or routines.
-
---------------------------------------------------------------------------*/
-herr_t
-H5PL__init_package(void)
-{
- char *preload_path;
-
- FUNC_ENTER_PACKAGE_NOERR
-
- /* Retrieve pathnames from HDF5_PLUGIN_PRELOAD if the user sets it
- * to tell the library to load plugin libraries without search.
- */
- if(NULL != (preload_path = HDgetenv("HDF5_PLUGIN_PRELOAD")))
- /* Special symbol "::" means no plugin during data reading. */
- if(!HDstrcmp(preload_path, H5PL_NO_PLUGIN))
- H5PL_plugin_g = 0;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5PL__init_package() */
/*-------------------------------------------------------------------------
- * Function: H5PL_term_package
- *
- * Purpose: Terminate the H5PL interface: release all memory, reset all
- * global variables to initial values. This only happens if all
- * types have been destroyed from other interfaces.
+ * Function: H5PLset_loading_state
*
- * Return: Success: Positive if any action was taken that might
- * affect some other interface; zero otherwise.
- * Failure: Negative.
- *
- * Programmer: Raymond Lu
- * 20 February 2013
- *
- *-------------------------------------------------------------------------
- */
-int
-H5PL_term_package(void)
-{
- int n = 0;
-
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- if(H5_PKG_INIT_VAR) {
- size_t u; /* Local index variable */
-
- /* Close opened dynamic libraries */
- if(H5PL_table_g) {
- for(u = 0; u < H5PL_table_used_g; u++)
- H5PL__close((H5PL_table_g[u]).handle);
-
- /* Free the table of dynamic libraries */
- H5PL_table_g = (H5PL_table_t *)H5MM_xfree(H5PL_table_g);
- H5PL_table_used_g = H5PL_table_alloc_g = 0;
-
- n++;
- } /* end if */
-
- /* Free the table of search paths */
- if(H5PL_num_paths_g > 0) {
- for(u = 0; u < H5PL_num_paths_g; u++)
- if(H5PL_path_table_g[u])
- H5PL_path_table_g[u] = (char *)H5MM_xfree(H5PL_path_table_g[u]);
- H5PL_num_paths_g = 0;
- H5PL_path_found_g = FALSE;
-
- n++;
- } /* end if */
-
- /* Mark the interface as uninitialized */
- if(0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end if */
-
- FUNC_LEAVE_NOAPI(n)
-} /* end H5PL_term_package() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5PLset_loading_state
+ * Purpose: Control the loading of dynamic plugin types.
*
- * Purpose: Control the loading of dynamic plugin types.
+ * The plugin_control_mask parameter is a bitfield that controls
+ * whether certain classes of plugins (e.g.: filters,
+ * VOL drivers) will be loaded by the library.
*
- * This function will not allow plugin types if the pathname from the HDF5_PLUGIN_PRELOAD
- * environment variable is set to the special "::" string.
+ * plugin bit = 0, will prevent the use of that dynamic plugin type.
+ * plugin bit = 1, will allow the use of that dynamic plugin type.
*
- * plugin bit = 0, will prevent the use of that dynamic plugin type.
- * plugin bit = 1, will allow the use of that dynamic plugin type.
+ * A list of pre-defined masks can be found in H5PLpublic.h.
+ * Set the mask to 0 to disable all plugins.
*
- * H5PL_TYPE_FILTER changes just dynamic filters
- * A H5PL_ALL_PLUGIN will enable all dynamic plugin types
- * A zero value will disable all dynamic plugin types
+ * This function will not allow plugin types if the pathname
+ * from the HDF5_PLUGIN_PRELOAD environment variable is set to
+ * the special "::" string.
*
- * Return: Non-negative or success
+ * Return: Success: Non-negative
+ * Failture: Negative
*
*-------------------------------------------------------------------------
*/
herr_t
-H5PLset_loading_state(unsigned int plugin_type)
+H5PLset_loading_state(unsigned int plugin_control_mask)
{
- char *preload_path;
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
- H5TRACE1("e", "Iu", plugin_type);
-
- /* change the bit value of the requested plugin type(s) */
- H5PL_plugin_g = plugin_type;
+ H5TRACE1("e", "Iu", plugin_control_mask);
- /* check if special ENV variable is set and disable all plugin types */
- if(NULL != (preload_path = HDgetenv("HDF5_PLUGIN_PRELOAD")))
- /* Special symbol "::" means no plugin during data reading. */
- if(!HDstrcmp(preload_path, H5PL_NO_PLUGIN))
- H5PL_plugin_g = 0;
+ /* Set the plugin control mask */
+ if(H5PL__set_plugin_control_mask(plugin_control_mask) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "error setting plugin control mask")
done:
FUNC_LEAVE_API(ret_value)
@@ -307,27 +98,35 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5PLget_loading_state
+ * Function: H5PLget_loading_state
*
- * Purpose: Query state of the loading of dynamic plugin types.
+ * Purpose: Get the bitmask that controls whether certain classes
+ * of plugins (e.g.: filters, VOL drivers) will be loaded
+ * by the library.
*
- * This function will return the state of the global flag.
+ * Zero if all plugin types are disabled
+ * Negative if all plugin types are enabled
+ * Positive if one or more of the plugin types are enabled
*
- * Return: Zero if all plugin types are disabled, negative if all
- * plugin types are enabled, positive if one or more of the plugin types are enabled.
+ * Return: Success: Non-negative
+ * Failture: Negative
*
*-------------------------------------------------------------------------
*/
herr_t
-H5PLget_loading_state(unsigned int *plugin_type)
+H5PLget_loading_state(unsigned int *plugin_control_mask)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
- H5TRACE1("e", "*Iu", plugin_type);
+ H5TRACE1("e", "*Iu", plugin_control_mask);
+
+ if (NULL == plugin_control_mask)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_control_mask parameter cannot be NULL")
- if(plugin_type)
- *plugin_type = H5PL_plugin_g;
+ /* Set the plugin control mask */
+ if(H5PL__get_plugin_control_mask(plugin_control_mask) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "error getting plugin control mask")
done:
FUNC_LEAVE_API(ret_value)
@@ -335,674 +134,282 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5PL_load
- *
- * Purpose: Given the plugin type and identifier, this function searches
- * and/or loads a dynamic plugin library first among the already
- * opened libraries then in the designated location paths.
- *
- * Return: Non-NULL on success/NULL on failure
- *
- * Programmer: Raymond Lu
- * 13 February 2013
- *
- *-------------------------------------------------------------------------
- */
-const void *
-H5PL_load(H5PL_type_t type, int id)
-{
- htri_t found; /* Whether the plugin was found */
- const void *plugin_info = NULL;
- const void *ret_value = NULL;
-
- FUNC_ENTER_NOAPI(NULL)
-
- switch(type) {
- case H5PL_TYPE_FILTER:
- if((H5PL_plugin_g & H5PL_FILTER_PLUGIN) == 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "required dynamically loaded plugin filter '%d' is not available", id)
- break;
-
- case H5PL_TYPE_ERROR:
- case H5PL_TYPE_NONE:
- default:
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "required dynamically loaded plugin '%d' is not valid", id)
- } /* end switch */
-
- /* Initialize the location paths for dynamic libraries, if they aren't
- * already set up.
- */
- if(FALSE == H5PL_path_found_g)
- if(H5PL__init_path_table() < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINIT, NULL, "can't initialize search path table")
-
- /* Search in the table of already loaded plugin libraries */
- if((found = H5PL__search_table(type, id, &plugin_info)) < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in table failed")
-
- /* If not found, iterate through the path table to find the right dynamic library */
- if(!found) {
- size_t i; /* Local index variable */
-
- for(i = 0; i < H5PL_num_paths_g; i++) {
- if((found = H5PL__find(type, id, H5PL_path_table_g[i], &plugin_info)) < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in paths failed")
-
- /* Break out if found */
- if(found) {
- HDassert(plugin_info);
- break;
- } /* end if */
- } /* end for */
- } /* end if */
-
- /* Check if we found the plugin */
- if(found)
- ret_value = plugin_info;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5PL_load() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5PLappend
+ * Function: H5PLappend
*
- * Purpose: Insert a plugin path at the end of the list.
+ * Purpose: Insert a plugin search path at the end of the list.
*
- * Return: Non-negative or success.
+ * Return: Success: Non-negative
+ * Failture: Negative
*
*-------------------------------------------------------------------------
*/
herr_t
-H5PLappend(const char *plugin_path)
+H5PLappend(const char *search_path)
{
herr_t ret_value = SUCCEED; /* Return value */
- char *dl_path = NULL;
FUNC_ENTER_API(FAIL)
- H5TRACE1("e", "*s", plugin_path);
- if(H5PL_num_paths_g == H5PL_MAX_PATH_NUM)
- HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table")
- if(NULL == plugin_path)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided")
- if(NULL == (dl_path = H5MM_strdup(plugin_path)))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
+ H5TRACE1("e", "*s", search_path);
- H5PL_EXPAND_ENV_VAR
+ /* Check args */
+ if (NULL == search_path)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot be NULL")
+ if (0 == HDstrlen(search_path))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot have length zero")
- H5PL_path_table_g[H5PL_num_paths_g] = dl_path;
- H5PL_num_paths_g++;
+ /* Append the search path to the path table */
+ if (H5PL__append_path(search_path) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTAPPEND, FAIL, "unable to append search path")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5PLappend() */
-
+
/*-------------------------------------------------------------------------
- * Function: H5PLprepend
+ * Function: H5PLprepend
*
- * Purpose: Insert a plugin path at the beginning of the list.
+ * Purpose: Insert a plugin search path at the beginning of the list.
*
- * Return: Non-negative or success.
+ * Return: Success: Non-negative
+ * Failture: Negative
*
*-------------------------------------------------------------------------
*/
herr_t
-H5PLprepend(const char *plugin_path)
+H5PLprepend(const char *search_path)
{
herr_t ret_value = SUCCEED; /* Return value */
- char *dl_path = NULL;
- unsigned int plindex;
FUNC_ENTER_API(FAIL)
- H5TRACE1("e", "*s", plugin_path);
- if(H5PL_num_paths_g == H5PL_MAX_PATH_NUM)
- HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table")
- if(NULL == plugin_path)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided")
- if(NULL == (dl_path = H5MM_strdup(plugin_path)))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
+ H5TRACE1("e", "*s", search_path);
- H5PL_EXPAND_ENV_VAR
+ /* Check args */
+ if (NULL == search_path)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot be NULL")
+ if (0 == HDstrlen(search_path))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot have length zero")
- for (plindex = (unsigned int)H5PL_num_paths_g; plindex > 0; plindex--)
- H5PL_path_table_g[plindex] = H5PL_path_table_g[plindex - 1];
- H5PL_path_table_g[0] = dl_path;
- H5PL_num_paths_g++;
+ /* Prepend the search path to the path table */
+ if (H5PL__prepend_path(search_path) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to prepend search path")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5PLprepend() */
-
+
/*-------------------------------------------------------------------------
- * Function: H5PLreplace
+ * Function: H5PLreplace
*
- * Purpose: Replace the path at the specified index.
+ * Purpose: Replace the path at the specified index. The path at the
+ * index must exist.
*
- * Return: Non-negative or success.
+ * Return: Non-negative or success.
*
*-------------------------------------------------------------------------
*/
herr_t
-H5PLreplace(const char *plugin_path, unsigned int index)
+H5PLreplace(const char *search_path, unsigned int index)
{
- herr_t ret_value = SUCCEED; /* Return value */
- char *dl_path = NULL;
+ unsigned num_paths; /* Current number of stored paths */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
- H5TRACE2("e", "*sIu", plugin_path, index);
- if(NULL == plugin_path)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided")
- if(index >= H5PL_MAX_PATH_NUM)
- HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table")
- if(NULL == (dl_path = H5MM_strdup(plugin_path)))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
+ H5TRACE2("e", "*sIu", search_path, index);
- H5PL_EXPAND_ENV_VAR
+ /* Check args */
+ if (NULL == search_path)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot be NULL")
+ if (0 == HDstrlen(search_path))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot have length zero")
- if(H5PL_path_table_g[index])
- H5PL_path_table_g[index] = (char *)H5MM_xfree(H5PL_path_table_g[index]);
- H5PL_path_table_g[index] = dl_path;
+ /* Check index */
+ num_paths = H5PL__get_num_paths();
+ if (0 == num_paths)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "path table is empty")
+ else if (index >= num_paths)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "index path out of bounds for table - can't be more than %u", (num_paths - 1))
+
+ /* Insert the search path into the path table */
+ if (H5PL__replace_path(search_path, index) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to replace search path")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5PLreplace() */
-
+
/*-------------------------------------------------------------------------
- * Function: H5PLinsert
+ * Function: H5PLinsert
*
- * Purpose: Insert a plugin path at the specified index, moving other paths after the index.
+ * Purpose: Insert a plugin search path at the specified index, moving
+ * other paths after the index.
*
- * Return: Non-negative or success.
+ * Return: Success: Non-negative
+ * Failture: Negative
*
*-------------------------------------------------------------------------
*/
herr_t
-H5PLinsert(const char *plugin_path, unsigned int index)
+H5PLinsert(const char *search_path, unsigned int index)
{
- herr_t ret_value = SUCCEED; /* Return value */
- char *dl_path = NULL;
- unsigned int plindex;
+ unsigned num_paths; /* Current number of stored paths */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
- H5TRACE2("e", "*sIu", plugin_path, index);
- if(H5PL_num_paths_g == H5PL_MAX_PATH_NUM)
- HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table")
- if(NULL == plugin_path)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no path provided")
- if(index >= H5PL_MAX_PATH_NUM)
- HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table")
- if(NULL == (dl_path = H5MM_strdup(plugin_path)))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
-
- H5PL_EXPAND_ENV_VAR
-
- for(plindex = (unsigned int)H5PL_num_paths_g; plindex > index; plindex--)
- H5PL_path_table_g[plindex] = H5PL_path_table_g[plindex - 1];
- H5PL_path_table_g[index] = dl_path;
- H5PL_num_paths_g++;
+ H5TRACE2("e", "*sIu", search_path, index);
+
+ /* Check args */
+ if (NULL == search_path)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot be NULL")
+ if (0 == HDstrlen(search_path))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "plugin_path parameter cannot have length zero")
+
+ /* Check index */
+ num_paths = H5PL__get_num_paths();
+ if ((0 != num_paths) && (index >= num_paths))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "index path out of bounds for table - can't be more than %u", (num_paths - 1))
+
+ /* Insert the search path into the path table */
+ if (H5PL__insert_path(search_path, index) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to insert search path")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5PLinsert() */
-
+
/*-------------------------------------------------------------------------
- * Function: H5PLremove
+ * Function: H5PLremove
+ *
+ * Purpose: Remove the plugin path at the specifed index and compact
+ * the list.
*
- * Purpose: Remove the plugin path at the specifed index and compacting the list.
+ * Return: Success: Non-negative
+ * Failture: Negative
*
- * Return: Non-negative or success.
+ * Return: Non-negative or success.
*
*-------------------------------------------------------------------------
*/
herr_t
H5PLremove(unsigned int index)
{
- herr_t ret_value = SUCCEED; /* Return value */
- unsigned int plindex;
+ unsigned num_paths; /* Current number of stored paths */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE1("e", "Iu", index);
- if(H5PL_num_paths_g == 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "no directories in table")
- if(index >= H5PL_MAX_PATH_NUM)
- HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table")
- if(NULL == H5PL_path_table_g[index])
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no directory path at index")
- H5PL_path_table_g[index] = (char *)H5MM_xfree(H5PL_path_table_g[index]);
-
- H5PL_num_paths_g--;
- for(plindex = index; plindex < (unsigned int)H5PL_num_paths_g; plindex++)
- H5PL_path_table_g[plindex] = H5PL_path_table_g[plindex + 1];
- H5PL_path_table_g[H5PL_num_paths_g] = NULL;
+
+ /* Check index */
+ num_paths = H5PL__get_num_paths();
+ if (0 == num_paths)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "path table is empty")
+ else if (index >= num_paths)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "index path out of bounds for table - can't be more than %u", (num_paths - 1))
+
+ /* Delete the search path from the path table */
+ if (H5PL__remove_path(index) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTDELETE, FAIL, "unable to remove search path")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5PLremove() */
-
+
/*-------------------------------------------------------------------------
- * Function: H5PLget
+ * Function: H5PLget
+ *
+ * Purpose: Query the plugin path at a specified index.
+ *
+ * If 'path_buf' is non-NULL then up to 'buf_size' bytes will be written into
+ * that buffer and the length of the path name will be returned.
*
- * Purpose: Query the plugin path at the specified index.
+ * If 'path_buf' is NULL, this function will simply return the number of
+ * characters required to store the path name, ignoring 'path_buf' and
+ * 'buf_size'
*
- * Return: Success: The length of path.
+ * If an error occurs then the buffer pointed to by 'path_buf'
+ * (NULL or non-NULL) will be unchanged and the function will return a
+ * negative value.
*
- * If `pathname' is non-NULL then write up to `size' bytes into that
- * buffer and always return the length of the pathname.
- * Otherwise `size' is ignored and the function does not store the pathname,
- * just returning the number of characters required to store the pathname.
- * If an error occurs then the buffer pointed to by `pathname' (NULL or non-NULL)
- * is unchanged and the function returns a negative value.
- * If a zero is returned for the name's length, then there is no pathname
- * associated with the index.
+ * If a zero is returned for the name's length, then there is no path name
+ * associated with the index and the 'path_buf' buffer will be unchanged.
+ *
+ * Return: Success: The length of path
+ * Failure: A negative value
*
*-------------------------------------------------------------------------
*/
ssize_t
-H5PLget(unsigned int index, char *pathname/*out*/, size_t size)
+H5PLget(unsigned int index, char *path_buf, size_t buf_size)
{
- ssize_t ret_value = 0; /* Return value */
- size_t len = 0; /* Length of pathname */
- char *dl_path = NULL;
+ unsigned num_paths; /* Current number of stored paths */
+ const char *path = NULL; /* path from table */
+ size_t path_len = 0; /* Length of path */
+ ssize_t ret_value = 0; /* Return value */
FUNC_ENTER_API(FAIL)
- H5TRACE3("Zs", "Iuxz", index, pathname, size);
- if(H5PL_num_paths_g == 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "no directories in table")
- if(index >= H5PL_MAX_PATH_NUM)
- HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "index path out of bounds for table")
- if(NULL == (dl_path = H5PL_path_table_g[index]))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "no directory path at index")
- len = HDstrlen(dl_path);
- if(pathname) {
- HDstrncpy(pathname, dl_path, MIN((size_t)(len + 1), size));
- if((size_t)len >= size)
- pathname[size - 1] = '\0';
+ H5TRACE3("Zs", "Iu*sz", index, path_buf, buf_size);
+
+ /* Check index */
+ num_paths = H5PL__get_num_paths();
+ if (0 == num_paths)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "path table is empty")
+ else if (index >= num_paths)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "index path out of bounds for table - can't be more than %u", (num_paths - 1))
+
+ /* Check if the search table is empty */
+ if (H5PL__get_num_paths() == 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, (-1), "plugin search path table is empty")
+
+ /* Get the path at the specified index and its length */
+ if (NULL == (path = H5PL__get_path(index)))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, (-1), "no path stored at that index")
+ path_len = HDstrlen(path);
+
+ /* If the path buffer is not NULL, copy the path to the buffer */
+ if (path_buf) {
+ HDstrncpy(path_buf, path, MIN((size_t)(path_len + 1), buf_size));
+ if ((size_t)path_len >= buf_size)
+ path_buf[buf_size - 1] = '\0';
} /* end if */
/* Set return value */
- ret_value = (ssize_t)len;
+ ret_value = (ssize_t)path_len;
done:
FUNC_LEAVE_API(ret_value)
} /* end H5PLget() */
-
+
/*-------------------------------------------------------------------------
- * Function: H5PLsize
+ * Function: H5PLsize
*
- * Purpose: Query the size of the current list of plugin paths.
+ * Purpose: Get the number of stored plugin paths.
+ * XXX: This is a terrible name. Can it be changed?
*
- * Return: Plugin path size
+ * Return: SUCCEED/FAIL
*
*-------------------------------------------------------------------------
*/
herr_t
-H5PLsize(unsigned int *listsize)
+H5PLsize(unsigned int *num_paths)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
- H5TRACE1("e", "*Iu", listsize);
+ H5TRACE1("e", "*Iu", num_paths);
- *listsize = (unsigned int)H5PL_num_paths_g;
+ /* Check arguments */
+ if (!num_paths)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "num_paths parameter cannot be NULL")
+
+ /* Get the number of stored plugin paths */
+ *num_paths = H5PL__get_num_paths();
done:
FUNC_LEAVE_API(ret_value)
} /* end H5PLsize() */
-
-/*-------------------------------------------------------------------------
- * Function: H5PL__init_path_table
- *
- * Purpose: Initialize the path table.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * 18 March 2013
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5PL__init_path_table(void)
-{
- char *dl_path = NULL;
- char *origin_dl_path;
- char *dir;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_STATIC
-
- /* Retrieve paths from HDF5_PLUGIN_PATH if the user sets it
- * or from the default paths if it isn't set.
- */
- origin_dl_path = HDgetenv("HDF5_PLUGIN_PATH");
- if(NULL == origin_dl_path)
- dl_path = H5MM_strdup(H5PL_DEFAULT_PATH);
- else
- dl_path = H5MM_strdup(origin_dl_path);
- if(NULL == dl_path)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
-
- H5PL_EXPAND_ENV_VAR
-
- /* Put paths in the path table. They are separated by ":" */
- dir = HDstrtok(dl_path, H5PL_PATH_SEPARATOR);
- while(dir) {
- /* Check for too many directories in path */
- if(H5PL_num_paths_g == H5PL_MAX_PATH_NUM)
- HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "too many directories in path for table")
- if(NULL == (H5PL_path_table_g[H5PL_num_paths_g] = H5MM_strdup(dir)))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
- H5PL_num_paths_g++;
- dir = HDstrtok(NULL, H5PL_PATH_SEPARATOR);
- } /* end while */
-
- H5PL_path_found_g = TRUE;
-
-done:
- if(dl_path)
- dl_path = (char *)H5MM_xfree(dl_path);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5PL__init_path_table() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5PL__find
- *
- * Purpose: Given a path, this function opens the directory and envokes
- * another function to go through all files to find the right
- * plugin library. Two function definitions are for Unix and
- * Windows.
- *
- * Return: TRUE on success,
- * FALSE on not found,
- * negative on failure
- *
- * Programmer: Raymond Lu
- * 13 February 2013
- *
- *-------------------------------------------------------------------------
- */
-#ifndef H5_HAVE_WIN32_API
-static htri_t
-H5PL__find(H5PL_type_t plugin_type, int type_id, char *dir, const void **info)
-{
- char *pathname = NULL;
- DIR *dirp = NULL;
- struct dirent *dp;
- htri_t ret_value = FALSE;
-
- FUNC_ENTER_STATIC
-
- /* Open the directory */
- if(!(dirp = HDopendir(dir)))
- HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, FAIL, "can't open directory: %s", dir)
-
- /* Iterates through all entries in the directory to find the right plugin library */
- while(NULL != (dp = HDreaddir(dirp))) {
- /* The library we are looking for should be called libxxx.so... on Unix
- * or libxxx.xxx.dylib on Mac.
- */
-#ifndef __CYGWIN__
- if(!HDstrncmp(dp->d_name, "lib", (size_t)3) &&
- (HDstrstr(dp->d_name, ".so") || HDstrstr(dp->d_name, ".dylib"))) {
-#else
- if(!HDstrncmp(dp->d_name, "cyg", (size_t)3) &&
- HDstrstr(dp->d_name, ".dll") ) {
-
-#endif
- h5_stat_t my_stat;
- size_t pathname_len;
- htri_t found_in_dir;
-
- /* Allocate & initialize the path name */
- pathname_len = HDstrlen(dir) + HDstrlen(dp->d_name) + 2;
- if(NULL == (pathname = (char *)H5MM_malloc(pathname_len)))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
- HDsnprintf(pathname, pathname_len, "%s/%s", dir, dp->d_name);
-
- /* Get info for directory entry */
- if(HDstat(pathname, &my_stat) == -1)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't stat file: %s", HDstrerror(errno))
-
- /* If it is a directory, skip it */
- if(S_ISDIR(my_stat.st_mode))
- continue;
-
- /* Attempt to open the dynamic library as a filter library */
- if((found_in_dir = H5PL__open(plugin_type, pathname, type_id, info)) < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in directory failed")
- if(found_in_dir)
- HGOTO_DONE(TRUE) /* Indicate success */
- pathname = (char *)H5MM_xfree(pathname);
- } /* end if */
- } /* end while */
-
-done:
- if(dirp)
- if(HDclosedir(dirp) < 0)
- HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "can't close directory: %s", HDstrerror(errno))
- pathname = (char *)H5MM_xfree(pathname);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5PL__find() */
-#else /* H5_HAVE_WIN32_API */
-static htri_t
-H5PL__find(H5PL_type_t plugin_type, int type_id, char *dir, const void **info)
-{
- WIN32_FIND_DATAA fdFile;
- HANDLE hFind;
- char *pathname = NULL;
- char service[2048];
- htri_t ret_value = FALSE;
-
- FUNC_ENTER_STATIC
-
- /* Specify a file mask. *.* = We want everything! */
- sprintf(service, "%s\\*.dll", dir);
- if((hFind = FindFirstFileA(service, &fdFile)) == INVALID_HANDLE_VALUE)
- HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, FAIL, "can't open directory")
-
- do {
- /* Find first file will always return "."
- * and ".." as the first two directories.
- */
- if(HDstrcmp(fdFile.cFileName, ".") != 0 && HDstrcmp(fdFile.cFileName, "..") != 0) {
- size_t pathname_len;
- htri_t found_in_dir;
-
- /* Allocate & initialize the path name */
- pathname_len = HDstrlen(dir) + HDstrlen(fdFile.cFileName) + 2;
- if(NULL == (pathname = (char *)H5MM_malloc(pathname_len)))
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
- HDsnprintf(pathname, pathname_len, "%s\\%s", dir, fdFile.cFileName);
-
- /* Is the entity a File or Folder? */
- if(fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- continue;
-
- if((found_in_dir = H5PL__open(plugin_type, pathname, type_id, info)) < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in directory failed")
- if(found_in_dir)
- HGOTO_DONE(TRUE) /* Indicate success */
- pathname = (char *)H5MM_xfree(pathname);
- } /* end if */
- } while(FindNextFileA(hFind, &fdFile)); /* Find the next file. */
-
-done:
- if(hFind)
- FindClose(hFind);
- if(pathname)
- pathname = (char *)H5MM_xfree(pathname);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5PL__find() */
-#endif /* H5_HAVE_WIN32_API */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5PL__open
- *
- * Purpose: Iterates through all files to find the right plugin library.
- * It loads the dynamic plugin library and keeps it on the list
- * of loaded libraries.
- *
- * Return: TRUE on success,
- * FALSE on not found,
- * negative on failure
- *
- * Programmer: Raymond Lu
- * 13 February 2013
- *
- *-------------------------------------------------------------------------
- */
-static htri_t
-H5PL__open(H5PL_type_t pl_type, char *libname, int pl_id, const void **pl_info)
-{
- H5PL_HANDLE handle = NULL;
- htri_t ret_value = FALSE;
-
- FUNC_ENTER_STATIC
-
- /* There are different reasons why a library can't be open, e.g. wrong architecture.
- * simply continue if we can't open it.
- */
- if(NULL == (handle = H5PL_OPEN_DLIB(libname))) {
- H5PL_CLR_ERROR; /* clear error */
- } /* end if */
- else {
- H5PL_get_plugin_info_t get_plugin_info = NULL;
-
- /* Return a handle for the function H5PLget_plugin_info in the dynamic library.
- * The plugin library is suppose to define this function.
- */
- if(NULL == (get_plugin_info = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC(handle, "H5PLget_plugin_info"))) {
- if(H5PL__close(handle) < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library")
- } /* end if */
- else {
- const H5Z_class2_t *plugin_info;
-
- /* Invoke H5PLget_plugin_info to verify this is the right library we are looking for.
- * Move on if it isn't.
- */
- if(NULL == (plugin_info = (const H5Z_class2_t *)(*get_plugin_info)())) {
- if(H5PL__close(handle) < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library")
- HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info")
- } /* end if */
-
- /* Successfully found plugin library, check if it's the right one */
- if(plugin_info->id == pl_id) {
- /* Expand the table if it is too small */
- if(H5PL_table_used_g >= H5PL_table_alloc_g) {
- size_t n = MAX(H5Z_MAX_NFILTERS, 2 * H5PL_table_alloc_g);
- H5PL_table_t *table = (H5PL_table_t *)H5MM_realloc(H5PL_table_g, n * sizeof(H5PL_table_t));
-
- if(!table)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "unable to extend dynamic library table")
-
- H5PL_table_g = table;
- H5PL_table_alloc_g = n;
- } /* end if */
-
- (H5PL_table_g[H5PL_table_used_g]).handle = handle;
- (H5PL_table_g[H5PL_table_used_g]).pl_type = pl_type;
- (H5PL_table_g[H5PL_table_used_g]).pl_id = plugin_info->id;
- H5PL_table_used_g++;
-
- /* Set the plugin info to return */
- *pl_info = (const void *)plugin_info;
-
- /* Indicate success */
- ret_value = TRUE;
- } /* end if */
- else
- if(H5PL__close(handle) < 0)
- HGOTO_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library")
- } /* end if */
- } /* end else */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5PL__open() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5PL__search_table
- *
- * Purpose: Search in the list of already opened dynamic libraries
- * to see if the one we are looking for is already opened.
- *
- * Return: TRUE on success,
- * FALSE on not found,
- * Negative on failure
- *
- * Programmer: Raymond Lu
- * 13 February 2013
- *
- *-------------------------------------------------------------------------
- */
-static htri_t
-H5PL__search_table(H5PL_type_t plugin_type, int type_id, const void **info)
-{
- htri_t ret_value = FALSE;
-
- FUNC_ENTER_STATIC
-
- /* Search in the table of already opened dynamic libraries */
- if(H5PL_table_used_g > 0) {
- size_t i;
-
- for(i = 0; i < H5PL_table_used_g; i++) {
- if((plugin_type == (H5PL_table_g[i]).pl_type) && (type_id == (H5PL_table_g[i]).pl_id)) {
- H5PL_get_plugin_info_t get_plugin_info;
- const H5Z_class2_t *plugin_info;
-
- if(NULL == (get_plugin_info = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC((H5PL_table_g[i]).handle, "H5PLget_plugin_info")))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info")
-
- if(NULL == (plugin_info = (const H5Z_class2_t *)(*get_plugin_info)()))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get plugin info")
-
- *info = plugin_info;
- HGOTO_DONE(TRUE)
- } /* end if */
- } /* end for */
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5PL__search_table() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5PL__close
- *
- * Purpose: Closes the handle for dynamic library
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Raymond Lu
- * 13 February 2013
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5PL__close(H5PL_HANDLE handle)
-{
- FUNC_ENTER_STATIC_NOERR
-
- H5PL_CLOSE_LIB(handle);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5PL__close() */
-
diff --git a/src/H5PLextern.h b/src/H5PLextern.h
index 7547ad7..cd5464d 100644
--- a/src/H5PLextern.h
+++ b/src/H5PLextern.h
@@ -11,9 +11,9 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * Programmer: Raymond Lu <songyulu@hdfgroup.org>
- * 13 February 2013
+ * Purpose: Header file for writing external HDF5 plugins.
*/
+
#ifndef _H5PLextern_H
#define _H5PLextern_H
diff --git a/src/H5PLint.c b/src/H5PLint.c
new file mode 100644
index 0000000..c887f86
--- /dev/null
+++ b/src/H5PLint.c
@@ -0,0 +1,384 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: Internal routines for managing plugins.
+ *
+ */
+
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5PLmodule.h" /* This source code file is part of the H5PL module */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5PLpkg.h" /* Plugin */
+#include "H5Zprivate.h" /* Filter pipeline */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Package initialization variable */
+hbool_t H5_PKG_INIT_VAR = FALSE;
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Bitmask that controls whether classes of plugins
+ * (e.g.: filters, VOL drivers) can be loaded.
+ */
+static unsigned int H5PL_plugin_control_mask_g = H5PL_ALL_PLUGIN;
+
+/* This flag will be set to FALSE if the HDF5_PLUGIN_PRELOAD
+ * environment variable was set to H5PL_NO_PLUGIN at
+ * package initialization.
+ */
+static hbool_t H5PL_allow_plugins_g = TRUE;
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__get_plugin_control_mask
+ *
+ * Purpose: Gets the internal plugin control mask value.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__get_plugin_control_mask(unsigned int *mask /*out*/)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Check args - Just assert on package functions */
+ HDassert(mask);
+
+ /* Return the mask */
+ *mask = H5PL_plugin_control_mask_g;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* end H5PL__get_plugin_control_mask() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__set_plugin_control_mask
+ *
+ * Purpose: Sets the internal plugin control mask value.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__set_plugin_control_mask(unsigned int mask)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Only allow setting this if plugins have not been disabled.
+ * XXX: Note that we don't consider this an error, but instead
+ * silently ignore it. We may want to consider this behavior
+ * more carefully.
+ */
+ if (H5PL_allow_plugins_g)
+ H5PL_plugin_control_mask_g = mask;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* end H5PL__set_plugin_control_mask() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__init_package
+ *
+ * Purpose: Initialize any package-specific data and call any init
+ * routines for the package.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__init_package(void)
+{
+ char *env_var = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check the environment variable to determine if the user wants
+ * to ignore plugins. The special symbol H5PL_NO_PLUGIN (defined in
+ * H5PLpublic.h) means we don't want to load plugins.
+ */
+ if (NULL != (env_var = HDgetenv("HDF5_PLUGIN_PRELOAD")))
+ if (!HDstrcmp(env_var, H5PL_NO_PLUGIN)) {
+ H5PL_plugin_control_mask_g = 0;
+ H5PL_allow_plugins_g = FALSE;
+ }
+
+ /* Create the table of previously-loaded plugins */
+ if (H5PL__create_plugin_cache() < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINIT, FAIL, "can't create plugin cache")
+
+ /* Create the table of search paths for dynamic libraries */
+ if (H5PL__create_path_table() < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINIT, FAIL, "can't create plugin search path table")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__init_package() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL_term_package
+ *
+ * Purpose: Terminate the H5PL interface: release all memory, reset all
+ * global variables to initial values. This only happens if all
+ * types have been destroyed from other interfaces.
+ *
+ * Return: Success: Positive if any action was taken that might
+ * affect some other interface; zero otherwise
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5PL_term_package(void)
+{
+ hbool_t already_closed = FALSE;
+ int ret_value = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if (H5_PKG_INIT_VAR) {
+
+ /* Close the plugin cache.
+ * We need to bump the return value if we did any real work here.
+ */
+ if (H5PL__close_plugin_cache(&already_closed) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing plugin cache")
+ if (!already_closed)
+ ret_value++;
+
+ /* Close the search path table and free the paths */
+ if (H5PL__close_path_table() < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, (-1), "problem closing search path table")
+
+ /* Mark the interface as uninitialized */
+ if (0 == ret_value)
+ H5_PKG_INIT_VAR = FALSE;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL_term_package() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL_load
+ *
+ * Purpose: Given the plugin type and identifier, this function searches
+ * for and, if found, loads a dynamic plugin library.
+ *
+ * The function searches first in the cached plugins and then
+ * in the paths listed in the path table.
+ *
+ * Return: Success: A pointer to the plugin info
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+const void *
+H5PL_load(H5PL_type_t type, int id)
+{
+ H5PL_search_params_t search_params;
+ hbool_t found = FALSE; /* Whether the plugin was found */
+ const void *plugin_info = NULL;
+ const void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ /* Check if plugins can be loaded for this plugin type */
+ switch (type) {
+ case H5PL_TYPE_FILTER:
+ if ((H5PL_plugin_control_mask_g & H5PL_FILTER_PLUGIN) == 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "required dynamically loaded plugin filter '%d' is not available", id)
+ break;
+
+ case H5PL_TYPE_ERROR:
+ case H5PL_TYPE_NONE:
+ default:
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "required dynamically loaded plugin '%d' is not valid", id)
+ }
+
+ /* Set up the search parameters */
+ search_params.type = type;
+ search_params.id = id;
+
+ /* Search in the table of already loaded plugin libraries */
+ if(H5PL__find_plugin_in_cache(&search_params, &found, &plugin_info) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in plugin cache failed")
+
+ /* If not found, try iterating through the path table to find an appropriate plugin */
+ if (!found)
+ if (H5PL__find_plugin_in_path_table(&search_params, &found, &plugin_info) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, NULL, "search in path table failed")
+
+ /* Set the return value we found the plugin */
+ if (found)
+ ret_value = plugin_info;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__open
+ *
+ * Purpose: Opens a plugin.
+ *
+ * The success parameter will be set to TRUE and the plugin_info
+ * parameter will be filled in on success. Otherwise, they
+ * will be FALSE and NULL, respectively.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+/* NOTE: We turn off -Wpedantic in gcc to quiet a warning about converting
+ * object pointers to function pointers, which is undefined in ANSI C.
+ * This is basically unavoidable due to the nature of dlsym() and *is*
+ * defined in POSIX, so it's fine.
+ *
+ * This pragma only needs to surround the assignment of the
+ * get_plugin_info function pointer, but early (4.4.7, at least) gcc
+ * only allows diagnostic pragmas to be toggled outside of functions.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+herr_t
+H5PL__open(const char *path, H5PL_type_t type, int id, hbool_t *success, const void **plugin_info)
+{
+ H5PL_HANDLE handle = NULL;
+ H5PL_get_plugin_info_t get_plugin_info = NULL;
+ htri_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check args - Just assert on package functions */
+ HDassert(path);
+ HDassert(success);
+ HDassert(plugin_info);
+
+ /* Initialize out parameters */
+ *success = FALSE;
+ *plugin_info = NULL;
+
+ /* There are different reasons why a library can't be open, e.g. wrong architecture.
+ * If we can't open the library, just return.
+ */
+ if (NULL == (handle = H5PL_OPEN_DLIB(path))) {
+ H5PL_CLR_ERROR; /* clear error */
+ HGOTO_DONE(SUCCEED);
+ }
+
+ /* Return a handle for the function H5PLget_plugin_info in the dynamic library.
+ * The plugin library is suppose to define this function.
+ */
+ if (NULL != (get_plugin_info = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC(handle, "H5PLget_plugin_info"))) {
+
+ const H5Z_class2_t *info;
+
+ /* Get the plugin info */
+ if (NULL == (info = (const H5Z_class2_t *)(*get_plugin_info)()))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info")
+
+ /* Check if the filter IDs match */
+ if (info->id == id) {
+
+ /* Store the plugin in the cache */
+ if (H5PL__add_plugin(type, id, handle))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to add new plugin to plugin cache")
+
+ /* Set output parameters */
+ *success = TRUE;
+ *plugin_info = (const void *)info;
+ }
+ }
+
+done:
+ if (!success && handle)
+ if (H5PL__close(handle) < 0)
+ HDONE_ERROR(H5E_PLUGIN, H5E_CLOSEERROR, FAIL, "can't close dynamic library")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__open() */
+#pragma GCC diagnostic pop
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__close
+ *
+ * Purpose: Closes the handle for dynamic library
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__close(H5PL_HANDLE handle)
+{
+ FUNC_ENTER_PACKAGE_NOERR
+
+ H5PL_CLOSE_LIB(handle);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5PL__close() */
+
diff --git a/src/H5PLmodule.h b/src/H5PLmodule.h
index b441aed..945441e 100644
--- a/src/H5PLmodule.h
+++ b/src/H5PLmodule.h
@@ -11,13 +11,11 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * Programmer: Quincey Koziol <koziol@hdfgroup.org>
- * Saturday, September 12, 2015
- *
- * Purpose: This file contains declarations which define macros for the
- * H5PL package. Including this header means that the source file
- * is part of the H5PL package.
+ * Purpose: This file contains declarations which define macros for the
+ * H5PL package. Including this header means that the source file
+ * is part of the H5PL package.
*/
+
#ifndef _H5PLmodule_H
#define _H5PLmodule_H
diff --git a/src/H5PLpath.c b/src/H5PLpath.c
new file mode 100644
index 0000000..435802a
--- /dev/null
+++ b/src/H5PLpath.c
@@ -0,0 +1,776 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: Code to implement a path table which stores plugin search paths.
+ *
+ * The path table is implemented as a dynamic, global array which
+ * will grow as new paths are inserted. The capacity of the path
+ * table never shrinks (though given the low number of paths
+ * expected and the low likelihood of paths being removed, this
+ * seems unlikely to be a problem). Inserts and removals rework
+ * the array so that there are no 'holes' in the in-use part
+ * of the array.
+ *
+ * Note that it's basically up to the user to manage the indexes
+ * when a complicated series of insert, overwrite, and, remove
+ * operations take place.
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5PLmodule.h" /* This source code file is part of the H5PL module */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5PLpkg.h" /* Plugin */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Initial capacity of the path table */
+#define H5PL_INITIAL_PATH_CAPACITY 16
+
+/* The amount to add to the capacity when the table is full */
+#define H5PL_PATH_CAPACITY_ADD 16
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+static herr_t H5PL__insert_at(const char *path, unsigned int index);
+static herr_t H5PL__make_space_at(unsigned int index);
+static herr_t H5PL__replace_at(const char *path, unsigned int index);
+static herr_t H5PL__expand_path_table(void);
+static herr_t H5PL__find_plugin_in_path(const H5PL_search_params_t *search_params, hbool_t *found, const char *dir, const void **plugin_info);
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Stored plugin paths to search */
+static char **H5PL_paths_g = NULL;
+
+/* The number of stored paths */
+static unsigned H5PL_num_paths_g = 0;
+
+/* The capacity of the path table */
+static unsigned H5PL_path_capacity_g = H5PL_INITIAL_PATH_CAPACITY;
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__insert_at()
+ *
+ * Purpose: Insert a path at a particular index in the path table.
+ * Does not clobber! Will move existing paths up to make
+ * room. Use H5PL__replace_at(index) if you want to clobber.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5PL__insert_at(const char *path, unsigned int index)
+{
+ char *path_copy = NULL; /* copy of path string (for storing) */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check args - Just assert on package functions */
+ HDassert(path);
+ HDassert(HDstrlen(path));
+
+ /* Expand the table if it is full */
+ if (H5PL_num_paths_g == H5PL_path_capacity_g)
+ if (H5PL__expand_path_table() < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't expand path table")
+
+ /* Copy the path for storage so the caller can dispose of theirs */
+ if (NULL == (path_copy = H5MM_strdup(path)))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't make internal copy of path")
+
+#ifdef H5_HAVE_WIN32_API
+ /* Clean up Microsoft Windows environment variables in the path string */
+ if(H5_expand_windows_env_vars(&path_copy))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTCONVERT, FAIL, "can't expand environment variable string")
+#endif /* H5_HAVE_WIN32_API */
+
+ /* If the table entry is in use, make some space */
+ if (H5PL_paths_g[index])
+ if (H5PL__make_space_at(index) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "unable to make space in the table for the new entry")
+
+ /* Insert the copy of the search path into the table at the specified index */
+ H5PL_paths_g[index] = path_copy;
+ H5PL_num_paths_g++;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__insert_at() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__make_space_at()
+ *
+ * Purpose: Free up a slot in the path table, moving existing path
+ * entries as necessary.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5PL__make_space_at(unsigned int index)
+{
+ unsigned u; /* iterator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Check args - Just assert on package functions */
+ HDassert(index < H5PL_path_capacity_g);
+
+ /* Copy the paths back to make a space */
+ for (u = H5PL_num_paths_g; u > index; u--)
+ H5PL_paths_g[u] = H5PL_paths_g[u-1];
+
+ H5PL_paths_g[index] = NULL;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__make_space_at() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__replace_at()
+ *
+ * Purpose: Replace a path at a particular index in the path table.
+ * The path in the table must exist and will be freed by this
+ * function.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5PL__replace_at(const char *path, unsigned int index)
+{
+ char *path_copy = NULL; /* copy of path string (for storing) */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check args - Just assert on package functions */
+ HDassert(path);
+ HDassert(HDstrlen(path));
+
+ /* Check that the table entry is in use */
+ if (!H5PL_paths_g[index])
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTFREE, FAIL, "path entry at index %u in the table is NULL", index)
+
+ /* Copy the path for storage so the caller can dispose of theirs */
+ if (NULL == (path_copy = H5MM_strdup(path)))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't make internal copy of path")
+
+#ifdef H5_HAVE_WIN32_API
+ /* Clean up Microsoft Windows environment variables in the path string */
+ if (H5_expand_windows_env_vars(&path_copy))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTCONVERT, FAIL, "can't expand environment variable string")
+#endif /* H5_HAVE_WIN32_API */
+
+ /* Free the existing path entry */
+ H5PL_paths_g[index] = (char *)H5MM_xfree(H5PL_paths_g[index]);
+
+ /* Copy the search path into the table at the specified index */
+ H5PL_paths_g[index] = path_copy;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__replace_at() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__create_path_table
+ *
+ * Purpose: Create the collection of paths that will be searched
+ * when loading plugins.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__create_path_table(void)
+{
+ char *env_var= NULL; /* Path string from environment variable */
+ char *paths = NULL; /* Delimited paths string. Either from the
+ * environment variable or the default.
+ */
+ char *next_path = NULL; /* A path tokenized from the paths string */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Allocate memory for the path table */
+ H5PL_num_paths_g = 0;
+ H5PL_path_capacity_g = H5PL_INITIAL_PATH_CAPACITY;
+ if (NULL == (H5PL_paths_g = (char **)H5MM_calloc((size_t)H5PL_path_capacity_g * sizeof(char *))))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path table")
+
+ /* Retrieve paths from HDF5_PLUGIN_PATH if the user sets it
+ * or from the default paths if it isn't set.
+ */
+ env_var = HDgetenv("HDF5_PLUGIN_PATH");
+ if (NULL == env_var)
+ paths = H5MM_strdup(H5PL_DEFAULT_PATH);
+ else
+ paths = H5MM_strdup(env_var);
+
+ if (NULL == paths)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path copy")
+
+ /* Separate the paths and store them */
+ /* XXX: strtok() is not thread-safe */
+ next_path = HDstrtok(paths, H5PL_PATH_SEPARATOR);
+ while (next_path) {
+
+ /* Insert the path into the table */
+ if (H5PL__append_path(next_path) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't insert path: %s", next_path)
+
+ /* Get the next path from the environment string */
+ next_path = HDstrtok(NULL, H5PL_PATH_SEPARATOR);
+ } /* end while */
+
+done:
+ if (paths)
+ paths = (char *)H5MM_xfree(paths);
+
+ /* Try to clean up on errors */
+ if (FAIL == ret_value) {
+ if (H5PL_paths_g)
+ H5PL_paths_g = (char **)H5MM_xfree(H5PL_paths_g);
+ H5PL_path_capacity_g = 0;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__create_path_table() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__close_path_table
+ *
+ * Purpose: Close the collection of paths that will be searched
+ * when loading plugins.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__close_path_table(void)
+{
+ unsigned u; /* iterator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Free paths */
+ for (u = 0; u < H5PL_num_paths_g; u++)
+ if (H5PL_paths_g[u])
+ H5PL_paths_g[u] = (char *)H5MM_xfree(H5PL_paths_g[u]);
+
+ /* Free path table */
+ H5PL_paths_g = (char **)H5MM_xfree(H5PL_paths_g);
+
+ /* Reset values */
+ H5PL_num_paths_g = 0;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* end H5PL__close_path_table() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__get_num_paths
+ *
+ * Purpose: Gets the number of plugin paths that have been stored.
+ *
+ * Return: Success: The number of paths
+ * Failture: Can't fail
+ *-------------------------------------------------------------------------
+ */
+unsigned
+H5PL__get_num_paths(void)
+{
+ FUNC_ENTER_PACKAGE_NOERR
+
+ FUNC_LEAVE_NOAPI(H5PL_num_paths_g)
+
+} /* end H5PL__get_num_paths() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__expand_path_table
+ *
+ * Purpose: Expand the path table when it's full.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5PL__expand_path_table(void)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Update the capacity */
+ H5PL_path_capacity_g += H5PL_PATH_CAPACITY_ADD;
+
+ /* Resize the array */
+ if(NULL == (H5PL_paths_g = (char **)H5MM_realloc(H5PL_paths_g, (size_t)H5PL_path_capacity_g * sizeof(char *))))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "allocating additional memory for path table failed")
+
+ /* Initialize the new memory */
+ HDmemset(H5PL_paths_g + H5PL_num_paths_g, 0, (size_t)H5PL_PATH_CAPACITY_ADD * sizeof(char *));
+
+done:
+ /* Set the path capacity back if there were problems */
+ if (FAIL == ret_value)
+ H5PL_path_capacity_g -= H5PL_PATH_CAPACITY_ADD;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__expand_path_table() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__append_path
+ *
+ * Purpose: Insert a path at the end of the table.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__append_path(const char *path)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check args - Just assert on package functions */
+ HDassert(path);
+ HDassert(HDstrlen(path));
+
+ /* Insert the path at the end of the table */
+ if (H5PL__insert_at(path, H5PL_num_paths_g) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to append search path")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__append_path() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__prepend_path
+ *
+ * Purpose: Insert a path at the beginning of the table.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__prepend_path(const char *path)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check args - Just assert on package functions */
+ HDassert(path);
+ HDassert(HDstrlen(path));
+
+ /* Insert the path at the beginning of the table */
+ if (H5PL__insert_at(path, 0) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to prepend search path")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__prepend_path() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__replace_path
+ *
+ * Purpose: Replace a path at particular index in the table.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__replace_path(const char *path, unsigned int index)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check args - Just assert on package functions */
+ HDassert(path);
+ HDassert(HDstrlen(path));
+ HDassert(index < H5PL_path_capacity_g);
+
+ /* Insert the path at the requested index */
+ if (H5PL__replace_at(path, index) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to replace search path")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__replace_path() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__insert_path
+ *
+ * Purpose: Insert a path at particular index in the table, moving
+ * any existing paths back to make space.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__insert_path(const char *path, unsigned int index)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check args - Just assert on package functions */
+ HDassert(path);
+ HDassert(HDstrlen(path));
+ HDassert(index < H5PL_path_capacity_g);
+
+ /* Insert the path at the requested index */
+ if (H5PL__insert_at(path, index) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTINSERT, FAIL, "unable to insert search path")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__insert_path() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__remove_path
+ *
+ * Purpose: Remove a path at particular index in the table, freeing
+ * the path string and moving the paths down to close the gap.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__remove_path(unsigned int index)
+{
+ unsigned u; /* iterator */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check args - Just assert on package functions */
+ HDassert(index < H5PL_path_capacity_g);
+
+ /* Check if the path at that index is set */
+ if (!H5PL_paths_g[index])
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTDELETE, FAIL, "search path at index %u is NULL", index)
+
+ /* Delete the path */
+ H5PL_num_paths_g--;
+ H5PL_paths_g[index] = (char *)H5MM_xfree(H5PL_paths_g[index]);
+
+ /* Shift the paths down to close the gap */
+ for (u = index; u < H5PL_num_paths_g; u++)
+ H5PL_paths_g[u] = H5PL_paths_g[u+1];
+
+ /* Set the (former) last path to NULL */
+ H5PL_paths_g[H5PL_num_paths_g] = NULL;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__remove_path() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__get_path
+ *
+ * Purpose: Get a pointer to a path at particular index in the table.
+ *
+ * Return: Success: A pointer to a path string stored in the table
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+const char *
+H5PL__get_path(unsigned int index)
+{
+ char *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Get the path at the requested index */
+ if (index >= H5PL_num_paths_g)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "path index %u is out of range in table", index)
+
+ return H5PL_paths_g[index];
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__replace_path() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__find_plugin_in_path_table
+ *
+ * Purpose: Attempts to find a matching plugin in the file system
+ * using the paths stored in the path table.
+ *.
+ * The 'found' parameter will be set appropriately.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__find_plugin_in_path_table(const H5PL_search_params_t *search_params, hbool_t *found, const void **plugin_info)
+{
+ unsigned int u; /* iterator */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check args - Just assert on package functions */
+ HDassert(search_params);
+ HDassert(found);
+ HDassert(plugin_info);
+
+ /* Initialize output parameters */
+ *found = FALSE;
+ *plugin_info = NULL;
+
+ /* Loop over the paths in the table, checking for an appropriate plugin */
+ for (u = 0; u < H5PL_num_paths_g; u++) {
+
+ /* Search for the plugin in this path */
+ if (H5PL__find_plugin_in_path(search_params, found, H5PL_paths_g[u], plugin_info) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in path %s encountered an error", H5PL_paths_g[u])
+
+ /* Break out if found */
+ if (*found) {
+ if (!plugin_info)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, FAIL, "plugin info should not be NULL")
+ break;
+ }
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__find_plugin_in_path_table() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__find_plugin_in_path
+ *
+ * Purpose: Given a path, this function opens the directory and envokes
+ * another function to go through all files to find the right
+ * plugin library. Two function definitions are for Unix and
+ * Windows.
+ *
+ * The found parameter will be set to TRUE and the info
+ * parameter will be filled in on success.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef H5_HAVE_WIN32_API
+static herr_t
+H5PL__find_plugin_in_path(const H5PL_search_params_t *search_params, hbool_t *found, const char *dir, const void **plugin_info)
+{
+ char *path = NULL;
+ DIR *dirp = NULL; /* Directory stream */
+ struct dirent *dp = NULL; /* Directory entry */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Check args - Just assert on package functions */
+ HDassert(search_params);
+ HDassert(found);
+ HDassert(dir);
+ HDassert(plugin_info);
+
+ /* Initialize the found parameter */
+ *found = FALSE;
+
+ /* Open the directory */
+ if (!(dirp = HDopendir(dir)))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, FAIL, "can't open directory: %s", dir)
+
+ /* Iterate through all entries in the directory */
+ while (NULL != (dp = HDreaddir(dirp))) {
+
+ /* The library we are looking for should be called libxxx.so... on Unix
+ * or libxxx.xxx.dylib on Mac.
+ */
+#ifndef __CYGWIN__
+ if (!HDstrncmp(dp->d_name, "lib", (size_t)3) &&
+ (HDstrstr(dp->d_name, ".so") || HDstrstr(dp->d_name, ".dylib"))) {
+#else
+ if (!HDstrncmp(dp->d_name, "cyg", (size_t)3) &&
+ HDstrstr(dp->d_name, ".dll") ) {
+#endif
+
+ h5_stat_t my_stat;
+ size_t len;
+
+ /* Allocate & initialize the path name */
+ len = HDstrlen(dir) + HDstrlen(H5PL_PATH_SEPARATOR) + HDstrlen(dp->d_name) + 1 /*\0*/;
+
+ if (NULL == (path = (char *)H5MM_calloc(len)))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
+
+ HDsnprintf(path, len, "%s/%s", dir, dp->d_name);
+
+ /* Get info for directory entry */
+ if (HDstat(path, &my_stat) == -1)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't stat file %s -- error was: %s", path, HDstrerror(errno))
+
+ /* If it is a directory, skip it */
+ if (S_ISDIR(my_stat.st_mode))
+ continue;
+
+ /* attempt to open the dynamic library as a filter library */
+ if (H5PL__open(path, search_params->type, search_params->id, found, plugin_info) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in directory failed")
+ if (*found)
+ HGOTO_DONE(SUCCEED)
+
+ path = (char *)H5MM_xfree(path);
+ } /* end if */
+ } /* end while */
+
+done:
+ if (dirp)
+ if (HDclosedir(dirp) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "can't close directory: %s", HDstrerror(errno))
+
+ path = (char *)H5MM_xfree(path);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__find_plugin_in_path() */
+#else /* H5_HAVE_WIN32_API */
+static herr_t
+H5PL__find_plugin_in_path(const H5PL_search_params_t *search_params, hbool_t *found, const char *dir, const void **plugin_info)
+{
+ WIN32_FIND_DATAA fdFile;
+ HANDLE hFind = INVALID_HANDLE_VALUE;
+ char *path = NULL;
+ char service[2048];
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Check args - Just assert on package functions */
+ HDassert(search_params);
+ HDassert(found);
+ HDassert(dir);
+ HDassert(plugin_info);
+
+ /* Initialize the found parameter */
+ *found = FALSE;
+
+ /* Specify a file mask. *.* = We want everything! */
+ HDsprintf(service, "%s\\*.dll", dir);
+ if ((hFind = FindFirstFileA(service, &fdFile)) == INVALID_HANDLE_VALUE)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_OPENERROR, FAIL, "can't open directory")
+
+ /* Loop over all the files */
+ do {
+ /* Ignore '.' and '..' */
+ if (HDstrcmp(fdFile.cFileName, ".") != 0 && HDstrcmp(fdFile.cFileName, "..") != 0) {
+
+ /* XXX: Probably just continue here and move the code below over one tab */
+
+ size_t len;
+
+ /* Allocate & initialize the path name */
+ len = HDstrlen(dir) + HDstrlen(H5PL_PATH_SEPARATOR) + HDstrlen(fdFile.cFileName) + 1;
+
+ if (NULL == (path = (char *)H5MM_calloc(len)))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for path")
+
+ HDsnprintf(path, len, "%s\\%s", dir, fdFile.cFileName);
+
+ /* Ignore directories */
+ if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ continue;
+
+ /* attempt to open the dynamic library as a filter library */
+ if (H5PL__open(path, search_params->type, search_params->id, found, plugin_info) < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "search in directory failed")
+ if (*found)
+ HGOTO_DONE(SUCCEED)
+
+ path = (char *)H5MM_xfree(path);
+ }
+ } while (FindNextFileA(hFind, &fdFile));
+
+done:
+ if (hFind != INVALID_HANDLE_VALUE)
+ FindClose(hFind);
+ if (path)
+ path = (char *)H5MM_xfree(path);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__find_plugin_in_path() */
+#endif /* H5_HAVE_WIN32_API */
+
diff --git a/src/H5PLpkg.h b/src/H5PLpkg.h
index e356893..0d1c271 100644
--- a/src/H5PLpkg.h
+++ b/src/H5PLpkg.h
@@ -11,6 +11,12 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/*
+ * Purpose: This file contains declarations which are visible only within
+ * the H5PL package. Source files outside the H5PL package should
+ * include H5PLprivate.h instead.
+ */
+
#if !(defined H5PL_FRIEND || defined H5PL_MODULE)
#error "Do not include this file outside the H5PL package!"
#endif
@@ -27,13 +33,92 @@
/* Package Private Macros */
/**************************/
-#define H5PL_MAX_PATH_NUM 16
+/* Whether to pre-load pathnames for plugin libraries */
+#define H5PL_DEFAULT_PATH H5_DEFAULT_PLUGINDIR
+
+
+/****************************/
+/* Macros for supporting */
+/* both Windows and POSIX */
+/****************************/
+
+/*******************/
+/* Windows support */
+/*******************/
+/*
+ * SPECIAL WINDOWS NOTE
+ *
+ * Some of the Win32 API functions expand to fooA or fooW depending on
+ * whether UNICODE or _UNICODE are defined. You MUST explicitly use
+ * the A version of the functions to force char * behavior until we
+ * work out a scheme for proper Windows Unicode support.
+ *
+ * If you do not do this, people will be unable to incorporate our
+ * source code into their own CMake builds if they define UNICODE.
+ */
+#ifdef H5_HAVE_WIN32_API
+
+ /* The path separator on this platform */
+# define H5PL_PATH_SEPARATOR ";"
+
+ /* Handle for dynamic library */
+# define H5PL_HANDLE HINSTANCE
+
+ /* Get a handle to a plugin library. Windows: TEXT macro handles Unicode strings */
+# define H5PL_OPEN_DLIB(S) LoadLibraryExA(S, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)
+
+ /* Get the address of a symbol in dynamic library */
+# define H5PL_GET_LIB_FUNC(H,N) GetProcAddress(H,N)
+
+ /* Close dynamic library */
+# define H5PL_CLOSE_LIB(H) FreeLibrary(H)
+
+ /* Clear error - nothing to do */
+# define H5PL_CLR_ERROR
+
+ /* maximum size for expanding env vars */
+# define H5PL_EXPAND_BUFFER_SIZE 32767
+
+ typedef const void *(__cdecl *H5PL_get_plugin_info_t)(void);
+
+#else /* H5_HAVE_WIN32_API */
+
+ /*****************/
+ /* POSIX support */
+ /*****************/
+
+ /* The path separator on this platform */
+# define H5PL_PATH_SEPARATOR ":"
+
+ /* Handle for dynamic library */
+# define H5PL_HANDLE void *
+
+ /* Get a handle to a plugin library. Windows: TEXT macro handles Unicode strings */
+# define H5PL_OPEN_DLIB(S) dlopen(S, RTLD_LAZY)
+
+ /* Get the address of a symbol in dynamic library */
+# define H5PL_GET_LIB_FUNC(H,N) dlsym(H,N)
+
+ /* Close dynamic library */
+# define H5PL_CLOSE_LIB(H) dlclose(H)
+
+ /* Clear error */
+# define H5PL_CLR_ERROR HERROR(H5E_PLUGIN, H5E_CANTGET, "can't dlopen:%s", dlerror())
+
+ typedef const void *(*H5PL_get_plugin_info_t)(void);
+#endif /* H5_HAVE_WIN32_API */
/****************************/
/* Package Private Typedefs */
/****************************/
+/* Data used to search for plugins */
+typedef struct H5PL_search_params_t {
+ H5PL_type_t type;
+ int id;
+} H5PL_search_params_t;
+
/*****************************/
/* Package Private Variables */
@@ -44,5 +129,31 @@
/* Package Private Prototypes */
/******************************/
+/* Accessors to global variables and flags */
+H5_DLL herr_t H5PL__get_plugin_control_mask(unsigned int *mask /*out*/);
+H5_DLL herr_t H5PL__set_plugin_control_mask(unsigned int mask);
+
+/* Plugin search and manipulation */
+H5_DLL herr_t H5PL__open(const char *libname, H5PL_type_t type, int id, hbool_t *success /*out*/, const void **plugin_info /*out*/);
+H5_DLL herr_t H5PL__close(H5PL_HANDLE handle);
+
+/* Plugin cache calls */
+H5_DLL herr_t H5PL__create_plugin_cache(void);
+H5_DLL herr_t H5PL__close_plugin_cache(hbool_t *already_closed /*out*/);
+H5_DLL herr_t H5PL__add_plugin(H5PL_type_t type, int id, H5PL_HANDLE handle);
+H5_DLL herr_t H5PL__find_plugin_in_cache(const H5PL_search_params_t *search_params, hbool_t *found /*out*/, const void **plugin_info /*out*/);
+
+/* Plugin search path calls */
+H5_DLL herr_t H5PL__create_path_table(void);
+H5_DLL herr_t H5PL__close_path_table(void);
+H5_DLL unsigned H5PL__get_num_paths(void);
+H5_DLL herr_t H5PL__append_path(const char *path);
+H5_DLL herr_t H5PL__prepend_path(const char *path);
+H5_DLL herr_t H5PL__replace_path(const char *path, unsigned int index);
+H5_DLL herr_t H5PL__insert_path(const char *path, unsigned int index);
+H5_DLL herr_t H5PL__remove_path(unsigned int index);
+H5_DLL const char *H5PL__get_path(unsigned int index);
+H5_DLL herr_t H5PL__find_plugin_in_path_table(const H5PL_search_params_t *search_params, hbool_t *found /*out*/, const void **plugin_info /*out*/);
+
#endif /* _H5PLpkg_H */
diff --git a/src/H5PLplugin_cache.c b/src/H5PLplugin_cache.c
new file mode 100644
index 0000000..d826ba0
--- /dev/null
+++ b/src/H5PLplugin_cache.c
@@ -0,0 +1,307 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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 COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: Code to implement a plugin cache which stores information
+ * about plugins which have already been loaded.
+ *
+ * The plugin cache is implemented as a dynamic, global array which
+ * will grow as new plugins are added. The capacity of the cache
+ * never shrinks since plugins stay in memory once loaded.
+ *
+ * Note that this functionality has absolutely nothing to do with
+ * the metadata or chunk caches.
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5PLmodule.h" /* This source code file is part of the H5PL module */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5PLpkg.h" /* Plugin */
+#include "H5Zprivate.h" /* Filter pipeline */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Initial capacity of the plugin cache */
+#define H5PL_INITIAL_CACHE_CAPACITY 16
+
+/* The amount to add to the capacity when the cache is full */
+#define H5PL_CACHE_CAPACITY_ADD 16
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/* Type for the list of info for opened plugin libraries */
+typedef struct H5PL_plugin_t {
+ H5PL_type_t type; /* Plugin type */
+ int id; /* ID for the plugin */
+ H5PL_HANDLE handle; /* Plugin handle */
+} H5PL_plugin_t;
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+static herr_t H5PL__expand_cache(void);
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Cache for storing opened plugin libraries */
+static H5PL_plugin_t *H5PL_cache_g = NULL;
+
+/* The number of stored plugins */
+static unsigned int H5PL_num_plugins_g = 0;
+
+/* The capacity of the plugin cache */
+static unsigned int H5PL_cache_capacity_g = 0;
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__create_plugin_cache
+ *
+ * Purpose: Create the cache that will store plugins that have already
+ * been loaded.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__create_plugin_cache(void)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ /* Allocate memory for the plugin cache */
+ H5PL_num_plugins_g = 0;
+
+ H5PL_cache_capacity_g = H5PL_INITIAL_CACHE_CAPACITY;
+
+ if (NULL == (H5PL_cache_g = (H5PL_plugin_t *)H5MM_calloc((size_t)H5PL_cache_capacity_g * sizeof(H5PL_plugin_t))))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for plugin cache")
+
+done:
+ /* Try to clean up on errors */
+ if (FAIL == ret_value) {
+ if (H5PL_cache_g)
+ H5PL_cache_g = (H5PL_plugin_t *)H5MM_xfree(H5PL_cache_g);
+ H5PL_cache_capacity_g = 0;
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__create_plugin_cache() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__close_plugin_cache
+ *
+ * Purpose: Close the cache of plugins that have already been loaded,
+ * closing all the plugins contained inside.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__close_plugin_cache(hbool_t *already_closed /*out*/)
+{
+ unsigned int u; /* iterator */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Close opened dynamic libraries */
+ if (H5PL_cache_g) {
+
+ /* Close any cached plugins */
+ for (u = 0; u < H5PL_num_plugins_g; u++)
+ H5PL__close((H5PL_cache_g[u]).handle);
+
+ /* Free the cache array */
+ H5PL_cache_g = (H5PL_plugin_t *)H5MM_xfree(H5PL_cache_g);
+ H5PL_num_plugins_g = 0;
+ H5PL_cache_capacity_g = 0;
+
+ /* Note that actually closed the table (needed by package close call) */
+ *already_closed = FALSE;
+ }
+ else
+ *already_closed = TRUE;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__close_plugin_cache() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__expand_cache
+ *
+ * Purpose: Expand the plugin cache when it's full.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5PL__expand_cache(void)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ /* Update the capacity */
+ H5PL_cache_capacity_g += H5PL_CACHE_CAPACITY_ADD;
+
+ /* Resize the array */
+ if(NULL == (H5PL_cache_g = (H5PL_plugin_t *)H5MM_realloc(H5PL_cache_g, (size_t)H5PL_cache_capacity_g * sizeof(H5PL_plugin_t))))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "allocating additional memory for plugin cache failed")
+
+ /* Initialize the new memory */
+ HDmemset(H5PL_cache_g + H5PL_num_plugins_g, 0, (size_t)H5PL_CACHE_CAPACITY_ADD * sizeof(H5PL_plugin_t));
+
+done:
+ /* Set the cache capacity back if there were problems */
+ if (FAIL == ret_value)
+ H5PL_cache_capacity_g -= H5PL_CACHE_CAPACITY_ADD;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__expand_cache() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__add_plugin
+ *
+ * Purpose: Add a plugin to the plugin cached.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5PL__add_plugin(H5PL_type_t type, int id, H5PL_HANDLE handle)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ /* Expand the cache if it is too small */
+ if (H5PL_num_plugins_g >= H5PL_cache_capacity_g)
+ if (H5PL__expand_cache() < 0)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't expand plugin cache")
+
+ /* Store the plugin info and bump the # of plugins */
+ H5PL_cache_g[H5PL_num_plugins_g].type = type;
+ H5PL_cache_g[H5PL_num_plugins_g].id = id;
+ H5PL_cache_g[H5PL_num_plugins_g].handle = handle;
+
+ H5PL_num_plugins_g++;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__add_plugin() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5PL__find_plugin_in_cache
+ *
+ * Purpose: Attempts to find a matching plugin from the cache.
+ *
+ * The 'found' parameter will be set appropriately.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+/* See the other use of H5PL_GET_LIB_FUNC() for an explanation
+ * for why we disable -Wpedantic here.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+herr_t
+H5PL__find_plugin_in_cache(const H5PL_search_params_t *search_params, hbool_t *found, const void **plugin_info)
+{
+ unsigned int u; /* iterator */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check args - Just assert on package functions */
+ HDassert(search_params);
+ HDassert(found);
+ HDassert(plugin_info);
+
+ /* Initialize output parameters */
+ *found = FALSE;
+ *plugin_info = NULL;
+
+ /* Loop over all the plugins, looking for one that matches */
+ for (u = 0; u < H5PL_num_plugins_g; u++) {
+
+ /* If the plugin type (filter, etc.) and ID match, query the plugin for its info */
+ if ((search_params->type == (H5PL_cache_g[u]).type) && (search_params->id == (H5PL_cache_g[u]).id)) {
+
+ H5PL_get_plugin_info_t get_plugin_info_function;
+ const H5Z_class2_t *filter_info;
+
+ /* Get the "get plugin info" function from the plugin. */
+ if (NULL == (get_plugin_info_function = (H5PL_get_plugin_info_t)H5PL_GET_LIB_FUNC((H5PL_cache_g[u]).handle, "H5PLget_plugin_info")))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info")
+
+ /* Call the "get plugin info" function */
+ if (NULL == (filter_info = (const H5Z_class2_t *)(*get_plugin_info_function)()))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get plugin info")
+
+ /* Set output parameters */
+ *found = TRUE;
+ *plugin_info = filter_info;
+
+ /* No need to continue processing */
+ break;
+
+ } /* end if */
+
+ } /* end for */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5PL__find_plugin_in_cache() */
+#pragma GCC diagnostic pop
+
diff --git a/src/H5PLprivate.h b/src/H5PLprivate.h
index 0ab8f8c..bc12e64 100644
--- a/src/H5PLprivate.h
+++ b/src/H5PLprivate.h
@@ -10,8 +10,8 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-/* Programmer: Raymond Lu <songyulu@hdfgroup.org>
- * 13 February 2013
+/*
+ * This file contains private information about the H5PL module
*/
#ifndef _H5PLprivate_H
diff --git a/src/H5PLpublic.h b/src/H5PLpublic.h
index 9ce1fca..3b36ccd 100644
--- a/src/H5PLpublic.h
+++ b/src/H5PLpublic.h
@@ -10,8 +10,8 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-/* Programmer: Raymond Lu <songyulu@hdfgroup.org>
- * 13 February 2013
+/*
+ * This file contains public declarations for the H5PL module.
*/
#ifndef _H5PLpublic_H
@@ -24,31 +24,35 @@
/* Public Typedefs */
/*******************/
+/* Special string to indicate no plugin loading.
+ */
+#define H5PL_NO_PLUGIN "::"
+
/* Plugin type used by the plugin library */
typedef enum H5PL_type_t {
- H5PL_TYPE_ERROR = -1, /*error */
- H5PL_TYPE_FILTER = 0, /*filter */
- H5PL_TYPE_NONE = 1 /*this must be last! */
+ H5PL_TYPE_ERROR = -1, /* Error */
+ H5PL_TYPE_FILTER = 0, /* Filter */
+ H5PL_TYPE_NONE = 1 /* This must be last! */
} H5PL_type_t;
/* Common dynamic plugin type flags used by the set/get_loading_state functions */
-#define H5PL_FILTER_PLUGIN 0x0001
-#define H5PL_ALL_PLUGIN 0xFFFF
+#define H5PL_FILTER_PLUGIN 0x0001
+#define H5PL_ALL_PLUGIN 0xFFFF
#ifdef __cplusplus
extern "C" {
#endif
/* plugin state */
-H5_DLL herr_t H5PLset_loading_state(unsigned int plugin_type);
-H5_DLL herr_t H5PLget_loading_state(unsigned int *plugin_type/*out*/);
-H5_DLL herr_t H5PLappend(const char *plugin_path);
-H5_DLL herr_t H5PLprepend(const char *plugin_path);
-H5_DLL herr_t H5PLreplace(const char *plugin_path, unsigned int index);
-H5_DLL herr_t H5PLinsert(const char *plugin_path, unsigned int index);
+H5_DLL herr_t H5PLset_loading_state(unsigned int plugin_control_mask);
+H5_DLL herr_t H5PLget_loading_state(unsigned int *plugin_control_mask /*out*/);
+H5_DLL herr_t H5PLappend(const char *search_path);
+H5_DLL herr_t H5PLprepend(const char *search_path);
+H5_DLL herr_t H5PLreplace(const char *search_path, unsigned int index);
+H5_DLL herr_t H5PLinsert(const char *search_path, unsigned int index);
H5_DLL herr_t H5PLremove(unsigned int index);
-H5_DLL ssize_t H5PLget(unsigned int index, char *pathname/*out*/, size_t size);
-H5_DLL herr_t H5PLsize(unsigned int *listsize/*out*/);
+H5_DLL ssize_t H5PLget(unsigned int index, char *path_buf /*out*/, size_t buf_size);
+H5_DLL herr_t H5PLsize(unsigned int *num_paths /*out*/);
#ifdef __cplusplus
}
diff --git a/src/H5Pfcpl.c b/src/H5Pfcpl.c
index 5383aae..6b0d2c0 100644
--- a/src/H5Pfcpl.c
+++ b/src/H5Pfcpl.c
@@ -1472,6 +1472,9 @@ H5Pset_file_space_page_size(hid_t plist_id, hsize_t fsp_size)
if(fsp_size < H5F_FILE_SPACE_PAGE_SIZE_MIN)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "cannot set file space page size to less than 512")
+ if(fsp_size > H5F_FILE_SPACE_PAGE_SIZE_MAX)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "cannot set file space page size to more than 1GB")
+
/* Set the value*/
if(H5P_set(plist, H5F_CRT_FILE_SPACE_PAGE_SIZE_NAME, &fsp_size) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set file space page size")
diff --git a/src/H5Smpio.c b/src/H5Smpio.c
index c24c455..46f7a59 100644
--- a/src/H5Smpio.c
+++ b/src/H5Smpio.c
@@ -33,7 +33,7 @@
#include "H5Oprivate.h" /* Object headers */
#include "H5Pprivate.h" /* Property lists */
#include "H5Spkg.h" /* Dataspaces */
-#include "H5VMprivate.h" /* Vector and array functions */
+#include "H5VMprivate.h" /* Vector and array functions */
#ifdef H5_HAVE_PARALLEL
@@ -55,9 +55,42 @@ static herr_t H5S_mpio_span_hyper_type(const H5S_t *space, size_t elmt_size,
MPI_Datatype *new_type, int *count, hbool_t *is_derived_type);
static herr_t H5S_obtain_datatype(const hsize_t down[], H5S_hyper_span_t* span,
const MPI_Datatype *elmt_type, MPI_Datatype *span_type, size_t elmt_size);
+static herr_t H5S_mpio_create_large_type (hsize_t, MPI_Aint, MPI_Datatype , MPI_Datatype *);
+
#define H5S_MPIO_INITIAL_ALLOC_COUNT 256
+#define TWO_GIG_LIMIT 2147483648
+
+#ifndef H5S_MAX_MPI_COUNT
+#define H5S_MAX_MPI_COUNT 536870911 /* (2^29)-1 */
+#endif
+
+static hsize_t bigio_count = H5S_MAX_MPI_COUNT;
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_mpio_set_bigio_count
+ *
+ * Purpose: Allow us to programatically change the switch point
+ * when we utilize derived datatypes. This is of
+ * particular interest for allowing nightly testing
+ *
+ * Return: the current/previous value of bigio_count.
+ *
+ * Programmer: Richard Warren, March 10, 2017
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t
+H5S_mpio_set_bigio_count(hsize_t new_count)
+{
+ hsize_t orig_count = bigio_count;
+ if ((new_count > 0) && (new_count < TWO_GIG_LIMIT)) {
+ bigio_count = new_count;
+ }
+ return orig_count;
+}
+
/*-------------------------------------------------------------------------
* Function: H5S_mpio_all_type
@@ -72,6 +105,11 @@ static herr_t H5S_obtain_datatype(const hsize_t down[], H5S_hyper_span_t* span,
* *is_derived_type 0 if MPI primitive type, 1 if derived
*
* Programmer: rky 980813
+ * Modifications:
+ * Mohamad Chaarawi
+ * Adding support for large datatypes (beyond the limit of a
+ * 32 bit integer.
+ *
*
*-------------------------------------------------------------------------
*/
@@ -95,11 +133,22 @@ H5S_mpio_all_type(const H5S_t *space, size_t elmt_size,
H5_CHECKED_ASSIGN(nelmts, hsize_t, snelmts, hssize_t);
total_bytes = (hsize_t)elmt_size * nelmts;
-
- /* fill in the return values */
- *new_type = MPI_BYTE;
- H5_CHECKED_ASSIGN(*count, int, total_bytes, hsize_t);
- *is_derived_type = FALSE;
+ /* Verify that the size can be expressed as a 32 bit integer */
+ if(bigio_count >= total_bytes) {
+ /* fill in the return values */
+ *new_type = MPI_BYTE;
+ H5_CHECKED_ASSIGN(*count, int, total_bytes, hsize_t);
+ *is_derived_type = FALSE;
+ }
+ else {
+ /* Create a LARGE derived datatype for this transfer */
+ if (H5S_mpio_create_large_type (total_bytes, 0, MPI_BYTE, new_type) < 0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,
+ "couldn't create a large datatype from the all selection")
+ }
+ *count = 1;
+ *is_derived_type = TRUE;
+ }
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -167,27 +216,103 @@ H5S_mpio_create_point_datatype (size_t elmt_size, hsize_t num_points,
HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
elmt_type_created = TRUE;
+ /* Check whether standard or BIGIO processing will be employeed */
+ if(bigio_count >= num_points) {
#if MPI_VERSION >= 3
- /* Create an MPI datatype for the whole point selection */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed_block((int)num_points, 1, disp, elmt_type, new_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_indexed_block failed", mpi_code)
+ /* Create an MPI datatype for the whole point selection */
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed_block((int)num_points, 1, disp, elmt_type, new_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_indexed_block failed", mpi_code)
#else
- /* Allocate block sizes for MPI datatype call */
- if(NULL == (blocks = (int *)H5MM_malloc(sizeof(int) * num_points)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks")
+ /* Allocate block sizes for MPI datatype call */
+ if(NULL == (blocks = (int *)H5MM_malloc(sizeof(int) * num_points)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks")
- for(u = 0; u < num_points; u++)
- blocks[u] = 1;
+ for(u = 0; u < num_points; u++)
+ blocks[u] = 1;
- /* Create an MPI datatype for the whole point selection */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)num_points, blocks, disp, elmt_type, new_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_indexed_block failed", mpi_code)
+ /* Create an MPI datatype for the whole point selection */
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)num_points, blocks, disp, elmt_type, new_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code)
#endif
- /* Commit MPI datatype for later use */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+ /* Commit MPI datatype for later use */
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+ }
+ else {
+ /* use LARGE_DATATYPE::
+ * We'll create an hindexed_block type for every 2G point count and then combine
+ * those and any remaining points into a single large datatype.
+ */
+ int total_types, i;
+ int remaining_points;
+ int num_big_types;
+ hsize_t leftover;
+
+ int *inner_blocks;
+ MPI_Aint *inner_disps;
+ MPI_Datatype *inner_types = NULL;
+
+ /* Calculate how many Big MPI datatypes are needed to represent the buffer */
+ num_big_types = (int)(num_points/bigio_count);
+
+ leftover = (hsize_t)num_points - (hsize_t)num_big_types * (hsize_t)bigio_count;
+ H5_CHECKED_ASSIGN(remaining_points, int, leftover, hsize_t);
+
+ total_types = (int)(remaining_points) ? (num_big_types + 1) : num_big_types;
+
+ /* Allocate array if MPI derived types needed */
+ if(NULL == (inner_types = (MPI_Datatype *)H5MM_malloc((sizeof(MPI_Datatype) * (size_t)total_types))))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks")
+
+ if(NULL == (inner_blocks = (int *)H5MM_malloc(sizeof(int) * (size_t)total_types)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks")
+
+ if(NULL == (inner_disps = (MPI_Aint *)H5MM_malloc(sizeof(MPI_Aint) * (size_t)total_types)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate array of blocks")
+
+ for(i=0 ; i<num_big_types ; i++) {
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed_block(bigio_count,
+ 1,
+ &disp[i*bigio_count],
+ elmt_type,
+ &inner_types[i]))) {
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed_block failed", mpi_code);
+ }
+ inner_blocks[i] = 1;
+ inner_disps[i] = 0;
+ }
+
+ if(remaining_points) {
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed_block(remaining_points,
+ 1,
+ &disp[num_big_types*bigio_count],
+ elmt_type,
+ &inner_types[num_big_types]))) {
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed_block failed", mpi_code);
+ }
+ inner_blocks[num_big_types] = 1;
+ inner_disps[num_big_types] = 0;
+ }
+
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_create_struct(total_types,
+ inner_blocks,
+ inner_disps,
+ inner_types,
+ new_type))) {
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct", mpi_code);
+ }
+ for(i=0 ; i<total_types ; i++)
+ MPI_Type_free(&inner_types[i]);
+
+ H5MM_free(inner_types);
+ H5MM_free(inner_blocks);
+ H5MM_free(inner_disps);
+ /* Commit MPI datatype for later use */
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+ }
done:
if(elmt_type_created)
MPI_Type_free(&elmt_type);
@@ -481,7 +606,10 @@ done:
* *is_derived_type 0 if MPI primitive type, 1 if derived
*
* Programmer: rky 980813
- *
+ * Modifications:
+ * Mohamad Chaarawi
+ * Adding support for large datatypes (beyond the limit of a
+ * 32 bit integer.
*-------------------------------------------------------------------------
*/
static herr_t
@@ -636,8 +764,25 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size,
HDfprintf(H5DEBUG(S), "d[%d].xtent=%Hu \n", i, d[i].xtent);
}
#endif
- if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &inner_type)))
+
+ /* LARGE_DATATYPE::
+ * Check if the number of elements to form the inner type fits into a 32 bit integer.
+ * If yes then just create the innertype with MPI_Type_contiguous.
+ * Otherwise create a compound datatype by iterating as many times as needed
+ * for the innertype to be created.
+ */
+ if(bigio_count >= elmt_size) {
+ /* Use a single MPI datatype that has a 32 bit size */
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &inner_type)))
HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
+ }
+ else {
+ /* Create the compound datatype for this operation (> 2GB) */
+ if (H5S_mpio_create_large_type (elmt_size, 0, MPI_BYTE, &inner_type) < 0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,
+ "couldn't ccreate a large inner datatype in hyper selection")
+ }
+ }
/*******************************************************
* Construct the type by walking the hyperslab dims
@@ -645,30 +790,93 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size,
*******************************************************/
for(i = ((int)rank) - 1; i >= 0; --i) {
#ifdef H5S_DEBUG
- if(H5DEBUG(S))
- HDfprintf(H5DEBUG(S), "%s: Dimension i=%d \n"
- "start=%Hd count=%Hu block=%Hu stride=%Hu, xtent=%Hu max_xtent=%d\n",
- FUNC, i, d[i].start, d[i].count, d[i].block, d[i].strid, d[i].xtent, max_xtent[i]);
+ if(H5DEBUG(S))
+ HDfprintf(H5DEBUG(S), "%s: Dimension i=%d \n"
+ "start=%Hd count=%Hu block=%Hu stride=%Hu, xtent=%Hu max_xtent=%d\n",
+ FUNC, i, d[i].start, d[i].count, d[i].block, d[i].strid, d[i].xtent, max_xtent[i]);
#endif
#ifdef H5S_DEBUG
- if(H5DEBUG(S))
- HDfprintf(H5DEBUG(S), "%s: i=%d Making vector-type \n", FUNC,i);
+ if(H5DEBUG(S))
+ HDfprintf(H5DEBUG(S), "%s: i=%d Making vector-type \n", FUNC,i);
#endif
/****************************************
* Build vector type of the selection.
****************************************/
- mpi_code = MPI_Type_vector((int)(d[i].count), /* count */
- (int)(d[i].block), /* blocklength */
- (int)(d[i].strid), /* stride */
- inner_type, /* old type */
- &outer_type); /* new type */
+ if (bigio_count >= d[i].count &&
+ bigio_count >= d[i].block &&
+ bigio_count >= d[i].strid) {
+
+ /* All the parameters fit into 32 bit integers so create the vector type normally */
+ mpi_code = MPI_Type_vector((int)(d[i].count), /* count */
+ (int)(d[i].block), /* blocklength */
+ (int)(d[i].strid), /* stride */
+ inner_type, /* old type */
+ &outer_type); /* new type */
+
+ MPI_Type_free(&inner_type);
+ if(mpi_code != MPI_SUCCESS)
+ HMPI_GOTO_ERROR(FAIL, "couldn't create MPI vector type", mpi_code)
+ }
+ else {
+ /* Things get a bit more complicated and require LARGE_DATATYPE processing
+ * There are two MPI datatypes that need to be created:
+ * 1) an internal contiguous block; and
+ * 2) a collection of elements where an element is a contiguous block(1).
+ * Remember that the input arguments to the MPI-IO functions use integer
+ * values to represent element counts. We ARE allowed however, in the
+ * more recent MPI implementations to use constructed datatypes whereby
+ * the total number of bytes in a transfer could be :
+ * (2GB-1)number_of_blocks * the_datatype_extent.
+ */
+
+ MPI_Aint stride_in_bytes, inner_extent;
+ MPI_Datatype block_type;
+
+ /* create a contiguous datatype inner_type x number of BLOCKS.
+ * Again we need to check that the number of BLOCKS can fit into
+ * a 32 bit integer */
+ if (bigio_count < d[i].block) {
+ if (H5S_mpio_create_large_type(d[i].block, 0, inner_type,
+ &block_type) < 0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,
+ "couldn't ccreate a large block datatype in hyper selection")
+ }
+ }
+ else {
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)d[i].block,
+ inner_type,
+ &block_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
+ }
- MPI_Type_free(&inner_type);
- if(mpi_code != MPI_SUCCESS)
- HMPI_GOTO_ERROR(FAIL, "couldn't create MPI vector type", mpi_code)
+ MPI_Type_extent (inner_type, &inner_extent);
+ stride_in_bytes = inner_extent * (MPI_Aint)d[i].strid;
- /****************************************
+ /* If the element count is larger than what a 32 bit integer can hold,
+ * we call the large type creation function to handle that
+ */
+ if (bigio_count < d[i].count) {
+ if (H5S_mpio_create_large_type (d[i].count, stride_in_bytes, block_type,
+ &outer_type) < 0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,
+ "couldn't create a large outer datatype in hyper selection")
+ }
+ }
+ /* otherwise a regular create_hvector will do */
+ else {
+ mpi_code = MPI_Type_create_hvector((int)d[i].count, /* count */
+ 1, /* blocklength */
+ stride_in_bytes, /* stride in bytes*/
+ block_type, /* old type */
+ &outer_type); /* new type */
+ if(MPI_SUCCESS != mpi_code)
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code)
+ }
+ MPI_Type_free(&block_type);
+ MPI_Type_free(&inner_type);
+ }
+ /****************************************
* Then build the dimension type as (start, vector type, xtent).
****************************************/
/* calculate start and extent values of this dimension */
@@ -752,6 +960,10 @@ done:
*
* Programmer: kyang
*
+ * Modifications:
+ * Mohamad Chaarawi
+ * Adding support for large datatypes (beyond the limit of a
+ * 32 bit integer.
*-------------------------------------------------------------------------
*/
static herr_t
@@ -774,8 +986,17 @@ H5S_mpio_span_hyper_type(const H5S_t *space, size_t elmt_size,
HDassert(space->select.sel_info.hslab->span_lst->head);
/* Create the base type for an element */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &elmt_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
+ if (bigio_count >= elmt_size) {
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)elmt_size, MPI_BYTE, &elmt_type))) {
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
+ }
+ }
+ else {
+ if (H5S_mpio_create_large_type (elmt_size, 0, MPI_BYTE, &elmt_type) < 0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,
+ "couldn't create a large element datatype in span_hyper selection")
+ }
+ }
elmt_type_is_derived = TRUE;
/* Compute 'down' sizes for each dimension */
@@ -821,14 +1042,15 @@ static herr_t
H5S_obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span,
const MPI_Datatype *elmt_type, MPI_Datatype *span_type, size_t elmt_size)
{
- size_t alloc_count; /* Number of span tree nodes allocated at this level */
- size_t outercount; /* Number of span tree nodes at this level */
+ size_t alloc_count = 0; /* Number of span tree nodes allocated at this level */
+ size_t outercount = 0; /* Number of span tree nodes at this level */
MPI_Datatype *inner_type = NULL;
hbool_t inner_types_freed = FALSE; /* Whether the inner_type MPI datatypes have been freed */
hbool_t span_type_valid = FALSE; /* Whether the span_type MPI datatypes is valid */
+ hbool_t large_block = FALSE; /* Wether the block length is larger than 32 bit integer */
int *blocklen = NULL;
MPI_Aint *disp = NULL;
- H5S_hyper_span_t *tspan; /* Temporary pointer to span tree node */
+ H5S_hyper_span_t *tspan = NULL; /* Temporary pointer to span tree node */
int mpi_code; /* MPI return status code */
herr_t ret_value = SUCCEED; /* Return value */
@@ -870,14 +1092,70 @@ H5S_obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span,
disp[outercount] = (MPI_Aint)elmt_size * tspan->low;
H5_CHECK_OVERFLOW(tspan->nelem, hsize_t, int)
blocklen[outercount] = (int)tspan->nelem;
-
tspan = tspan->next;
+
+ if (bigio_count < blocklen[outercount]) {
+ large_block = TRUE; /* at least one block type is large, so set this flag to true */
+ }
+
outercount++;
} /* end while */
- if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)outercount, blocklen, disp, *elmt_type, span_type)))
- HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code)
- span_type_valid = TRUE;
+ /* Everything fits into integers, so cast them and use hindexed */
+ if (bigio_count >= outercount && large_block == FALSE) {
+
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hindexed((int)outercount, blocklen, disp, *elmt_type, span_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hindexed failed", mpi_code)
+ span_type_valid = TRUE;
+ }
+ else { /* LARGE_DATATYPE:: Something doesn't fit into a 32 bit integer */
+ size_t i;
+
+ for (i=0 ; i<outercount ; i++) {
+ MPI_Datatype temp_type = MPI_DATATYPE_NULL, outer_type = MPI_DATATYPE_NULL;
+ /* create the block type from elmt_type while checking the 32 bit int limit */
+ if (blocklen[i] > bigio_count) {
+ if (H5S_mpio_create_large_type (blocklen[i], 0, *elmt_type, &temp_type) < 0) {
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,
+ "couldn't create a large element datatype in span_hyper selection")
+ }
+ }
+ else {
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous((int)blocklen[i],
+ *elmt_type,
+ &temp_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
+ }
+
+ /* combine the current datatype that is created with this current block type */
+ if (0 == i) { /* first iteration, there is no combined datatype yet */
+ *span_type = temp_type;
+ }
+ else {
+ int bl[2] = {1,1};
+ MPI_Aint ds[2] = {disp[i-1],disp[i]};
+ MPI_Datatype dt[2] = {*span_type, temp_type};
+
+ if (MPI_SUCCESS != (mpi_code = MPI_Type_create_struct (2, /* count */
+ bl, /* blocklength */
+ ds, /* stride in bytes*/
+ dt, /* old type */
+ &outer_type))){ /* new type */
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code)
+ }
+ *span_type = outer_type;
+ }
+
+ if (outer_type != MPI_DATATYPE_NULL)
+ MPI_Type_free(&outer_type);
+ /* temp_type shouldn't be freed here...
+ * Note that we have simply copied it above (not MPI_Type_dup)
+ * into the 'span_type' argument of the caller.
+ * The caller needs to deal with it there!
+ */
+ }
+ } /* end (LARGE_DATATYPE::) */
+
} /* end if */
else {
size_t u; /* Local index variable */
@@ -1091,5 +1369,139 @@ H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, MPI_Datatype *new_type
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_mpio_space_type() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_mpio_create_large_type
+ *
+ * Purpose: Create a large datatype of size larger than what a 32 bit integer
+ * can hold.
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * *new_type the new datatype created
+ *
+ * Programmer: Mohamad Chaarawi
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t H5S_mpio_create_large_type (hsize_t num_elements,
+ MPI_Aint stride_bytes,
+ MPI_Datatype old_type,
+ MPI_Datatype *new_type)
+{
+ int num_big_types; /* num times the 2G datatype will be repeated */
+ int remaining_bytes; /* the number of bytes left that can be held in an int value */
+ hsize_t leftover;
+ int block_len[2];
+ int mpi_code; /* MPI return code */
+ MPI_Datatype inner_type, outer_type, leftover_type, type[2];
+ MPI_Aint disp[2], old_extent;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Calculate how many Big MPI datatypes are needed to represent the buffer */
+ num_big_types = (int)(num_elements/bigio_count);
+ leftover = num_elements - num_big_types * (hsize_t)bigio_count;
+ H5_CHECKED_ASSIGN(remaining_bytes, int, leftover, hsize_t);
+
+ /* Create a contiguous datatype of size equal to the largest
+ * number that a 32 bit integer can hold x size of old type.
+ * If the displacement is 0, then the type is contiguous, otherwise
+ * use type_hvector to create the type with the displacement provided
+ */
+ if (0 == stride_bytes) {
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(bigio_count,
+ old_type,
+ &inner_type))) {
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
+ }
+ }
+ else {
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector (bigio_count,
+ 1,
+ stride_bytes,
+ old_type,
+ &inner_type))) {
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code)
+ }
+ }
+
+ /* Create a contiguous datatype of the buffer (minus the remaining < 2GB part)
+ * If a stride is present, use hvector type
+ */
+ if (0 == stride_bytes) {
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(num_big_types,
+ inner_type,
+ &outer_type))) {
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
+ }
+ }
+ else {
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector (num_big_types,
+ 1,
+ stride_bytes,
+ inner_type,
+ &outer_type))) {
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code)
+ }
+ }
+
+ MPI_Type_free(&inner_type);
+
+ /* If there is a remaining part create a contiguous/vector datatype and then
+ * use a struct datatype to encapsulate everything.
+ */
+ if(remaining_bytes) {
+ if (stride_bytes == 0) {
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_contiguous (remaining_bytes,
+ old_type,
+ &leftover_type))) {
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_contiguous failed", mpi_code)
+ }
+ }
+ else {
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_create_hvector
+ ((int)(num_elements - (hsize_t)num_big_types*bigio_count),
+ 1,
+ stride_bytes,
+ old_type,
+ &leftover_type))) {
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_hvector failed", mpi_code)
+ }
+ }
+
+ MPI_Type_extent (old_type, &old_extent);
+
+ /* Set up the arguments for MPI_Type_struct constructor */
+ type[0] = outer_type;
+ type[1] = leftover_type;
+ block_len[0] = 1;
+ block_len[1] = 1;
+ disp[0] = 0;
+ disp[1] = (old_extent+stride_bytes)*num_big_types*(MPI_Aint)bigio_count;
+
+ if(MPI_SUCCESS != (mpi_code =
+ MPI_Type_create_struct(2, block_len, disp, type, new_type))) {
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_create_struct failed", mpi_code)
+ }
+
+ MPI_Type_free(&outer_type);
+ MPI_Type_free(&leftover_type);
+ }
+ else {
+ /* There are no remaining bytes so just set the new type to
+ * the outer type created */
+ *new_type = outer_type;
+ }
+
+ if(MPI_SUCCESS != (mpi_code = MPI_Type_commit(new_type)))
+ HMPI_GOTO_ERROR(FAIL, "MPI_Type_commit failed", mpi_code)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_mpio_create_large_type */
+
#endif /* H5_HAVE_PARALLEL */
diff --git a/src/H5VMprivate.h b/src/H5VMprivate.h
index 4d71b29..decac7e 100644
--- a/src/H5VMprivate.h
+++ b/src/H5VMprivate.h
@@ -460,7 +460,11 @@ H5VM_power2up(hsize_t n)
{
hsize_t ret_value = 1; /* Return value */
- while(ret_value < n)
+ /* Returns 0 when n exceeds 2^63 */
+ if(n >= (hsize_t)1 << ((sizeof(hsize_t) * CHAR_BIT) - 1))
+ ret_value = 0;
+
+ while(ret_value && ret_value < n)
ret_value <<= 1;
return(ret_value);
diff --git a/src/H5system.c b/src/H5system.c
index 7e25540..a1cdf19 100644
--- a/src/H5system.c
+++ b/src/H5system.c
@@ -1237,3 +1237,49 @@ H5_get_time(void)
} /* end H5_get_time() */
+#ifdef H5_HAVE_WIN32_API
+
+#define H5_WIN32_ENV_VAR_BUFFER_SIZE 32767
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5_expand_windows_env_vars()
+ *
+ * Purpose: Replaces windows environment variables of the form %foo%
+ * with user-specific values.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5_expand_windows_env_vars(char **env_var)
+{
+ long n_chars = 0;
+ char *temp_buf = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Allocate buffer for expanded environment variable string */
+ if (NULL == (temp_buf = (char *)H5MM_calloc((size_t)H5_WIN32_ENV_VAR_BUFFER_SIZE)))
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTALLOC, FAIL, "can't allocate memory for expanded path")
+
+ /* Expand the environment variable string */
+ if ((n_chars = ExpandEnvironmentStringsA(*env_var, temp_buf, H5_WIN32_ENV_VAR_BUFFER_SIZE)) > H5_WIN32_ENV_VAR_BUFFER_SIZE)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_NOSPACE, FAIL, "expanded path is too long")
+
+ if (0 == n_chars)
+ HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "failed to expand path")
+
+ *env_var = (char *)H5MM_xfree(*env_var);
+ *env_var = temp_buf;
+
+done:
+ if (FAIL == ret_value && temp_buf)
+ temp_buf = (char *)H5MM_xfree(temp_buf);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5_expand_windows_env_vars() */
+#endif /* H5_HAVE_WIN32_API */
+
diff --git a/src/H5win32defs.h b/src/H5win32defs.h
index 97f7179..4522228 100644
--- a/src/H5win32defs.h
+++ b/src/H5win32defs.h
@@ -119,6 +119,7 @@ extern "C" {
H5_DLL int c99_snprintf(char* str, size_t size, const char* format, ...);
H5_DLL int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap);
H5_DLL int Wnanosleep(const struct timespec *req, struct timespec *rem);
+ H5_DLL herr_t H5_expand_windows_env_vars(char **env_var);
/* Round functions only needed for VS2012 and earlier.
* They are always built to ensure they don't go stale and
diff --git a/src/Makefile.am b/src/Makefile.am
index 0b664a7..9a64717 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -97,7 +97,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Pgcpl.c H5Pint.c \
H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \
H5PB.c \
- H5PL.c \
+ H5PL.c H5PLint.c H5PLpath.c H5PLplugin_cache.c \
H5R.c H5Rdeprec.c \
H5UC.c \
H5RS.c \
diff --git a/test/dsets.c b/test/dsets.c
index c29d18e..0ca08e4 100644
--- a/test/dsets.c
+++ b/test/dsets.c
@@ -51,14 +51,15 @@ const char *FILENAME[] = {
"copy_dcpl_newfile",/* 13 */
"partial_chunks", /* 14 */
"layout_extend", /* 15 */
- "zero_chunk", /* 16 */
+ "zero_chunk", /* 16 */
"chunk_single", /* 17 */
"swmr_non_latest", /* 18 */
"earray_hdr_fd", /* 19 */
"farray_hdr_fd", /* 20 */
"bt2_hdr_fd", /* 21 */
- "storage_size", /* 22 */
+ "storage_size", /* 22 */
"dls_01_strings", /* 23 */
+ "power2up", /* 24 */
NULL
};
#define FILENAME_BUF_SIZE 1024
@@ -11345,6 +11346,97 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_power2up
+ *
+ * Purpose: Tests that the H5VM_power2up(n) function does not result in an
+ * infinite loop when input n exceeds 2^63. (HDFFV-10217)
+ * H5VM_power2up() is used to calculate the next power of 2 for
+ * a dataset's scaled dimension sizes.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Vailin Choi; June 2017
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_power2up(hid_t fapl)
+{
+ char filename[FILENAME_BUF_SIZE];
+ hid_t fid = -1; /* File ID */
+ hid_t dcpl = -1; /* Dataset creation property list */
+ hid_t sid = -1; /* Dataspace ID */
+ hid_t did = -1; /* Dataset ID */
+ hsize_t dims[2]; /* Dataset dimension sizes */
+ hsize_t max_dims[2]; /* Maximum dimension sizes */
+ hsize_t chunk_dims[2]; /* Chunk dimensions */
+ hsize_t ext_dims[2]; /* Extended dimension sizes */
+ herr_t status; /* Error status */
+
+ TESTING("the next power of 2");
+
+ h5_fixname(FILENAME[24], fapl, filename, sizeof filename);
+
+ /* Create file */
+ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR
+
+ /* Set dims[1] to ((2^63) -1) */
+ dims[0] = 0;
+ dims[1] = ((hsize_t)1 << ((sizeof(hsize_t) * CHAR_BIT) -1)) - 1;
+ max_dims[0] = max_dims[1] = H5S_UNLIMITED;
+ sid = H5Screate_simple(2, dims, max_dims);
+
+ /* Create dataset creation property list */
+ if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0)
+ TEST_ERROR
+
+ /* Set chunk size */
+ chunk_dims[0] = chunk_dims[1] = 1;
+ if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0)
+ TEST_ERROR
+
+ /* Create chunked dataset */
+ if((did = H5Dcreate2(fid, "dset", H5T_NATIVE_INT64, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
+ TEST_ERROR
+
+ ext_dims[0] = 1;
+ ext_dims[1] = dims[1] + 5;
+
+ /* Extend to (2^63)+ */
+ H5E_BEGIN_TRY {
+ status = H5Dset_extent(did, ext_dims);
+ } H5E_END_TRY;
+ if(status >= 0)
+ TEST_ERROR
+
+ /* Closing */
+ if(H5Dclose(did) < 0)
+ TEST_ERROR
+ if(H5Sclose(sid) < 0)
+ TEST_ERROR
+ if(H5Pclose(dcpl) < 0)
+ TEST_ERROR
+ if(H5Fclose(fid) < 0)
+ TEST_ERROR
+
+ PASSED();
+
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Pclose(dcpl);
+ H5Dclose(did);
+ H5Sclose(sid);
+ H5Pclose(dcpl);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ return -1;
+} /* end test_power2up() */
+
+
+/*-------------------------------------------------------------------------
* Function: test_scatter
*
* Purpose: Tests H5Dscatter with a variety of different selections
@@ -12928,6 +13020,7 @@ main(void)
nerrors += (test_large_chunk_shrink(my_fapl) < 0 ? 1 : 0);
nerrors += (test_zero_dim_dset(my_fapl) < 0 ? 1 : 0);
nerrors += (test_storage_size(my_fapl) < 0 ? 1 : 0);
+ nerrors += (test_power2up(my_fapl) < 0 ? 1 : 0);
nerrors += (test_swmr_non_latest(envval, my_fapl) < 0 ? 1 : 0);
nerrors += (test_earray_hdr_fd(envval, my_fapl) < 0 ? 1 : 0);
diff --git a/test/fheap.c b/test/fheap.c
index 4be6cb9..6c3a8ac 100644
--- a/test/fheap.c
+++ b/test/fheap.c
@@ -16377,6 +16377,16 @@ main(void)
unsigned nerrors = 0; /* Cumulative error count */
unsigned num_pb_fs = 1; /* The number of settings to test for page buffering and file space handling */
int ExpressMode; /* Express testing level */
+ const char *envval; /* Environment variable */
+ hbool_t contig_addr_vfd; /* Whether VFD used has a contigous address space */
+
+ /* Don't run this test using certain file drivers */
+ envval = HDgetenv("HDF5_DRIVER");
+ if(envval == NULL)
+ envval = "nomatch";
+
+ /* Current VFD that does not support contigous address space */
+ contig_addr_vfd = (hbool_t)(HDstrcmp(envval, "split") && HDstrcmp(envval, "multi"));
/* Reset library */
h5_reset();
@@ -16428,6 +16438,12 @@ main(void)
shared_wobj_g[u] = (unsigned char)u;
for(v = 0; v < num_pb_fs; v++) {
+ /* Skip test when:
+ a) multi/split drivers and
+ b) persisting free-space or using paged aggregation strategy
+ because the library will fail file creation (temporary) for the above conditions */
+ if(!contig_addr_vfd && v)
+ break;
if((fcpl = H5Pcopy(def_fcpl)) < 0)
TEST_ERROR
diff --git a/test/plugin.c b/test/plugin.c
index 1254e9a..ea199f6 100644
--- a/test/plugin.c
+++ b/test/plugin.c
@@ -10,9 +10,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * Programmer: Raymond Lu
- * 13 February 2013
- *
* Purpose: Tests the plugin module (H5PL)
*/
@@ -660,13 +657,10 @@ error:
/*-------------------------------------------------------------------------
* Function: test_groups_with_filters
*
- * Purpose: Tests opening group with dynamically loaded filters
- *
- * Return: Success: 0
- * Failure: -1
+ * Purpose: Tests opening group with dynamically loaded filters
*
- * Programmer: Raymond Lu
- * 1 April 2013
+ * Return: Success: 0
+ * Failure: -1
*
*-------------------------------------------------------------------------
*/
@@ -710,261 +704,388 @@ error:
/*-------------------------------------------------------------------------
- * Function: test_filter_path_apis
+ * Function: test_path_api_calls
*
- * Purpose: Tests accessing the path table for dynamically loaded filters
+ * Purpose: Tests the H5PL API calls that manipulate the plugin search
+ * paths.
*
- * Return: Success: 0
- * Failure: -1
+ * Return: SUCCEED/FAIL
+ *
*-------------------------------------------------------------------------
*/
static herr_t
-test_filter_path_apis(void)
+test_path_api_calls(void)
{
- herr_t ret_value = -1;
- unsigned int i;
- unsigned int ndx;
+ unsigned int n_starting_paths;
+ unsigned int u;
+ unsigned int n_paths;
herr_t ret;
- ssize_t pathlen = -1;
- char pathname[256];
- char tempname[256];
+ ssize_t path_len = -1;
+ char path[256];
+ char temp_name[256];
HDputs("Testing access to the filter path table");
- if(H5Zfilter_avail(H5Z_FILTER_DYNLIB1) != TRUE) TEST_ERROR
+ if(H5Zfilter_avail(H5Z_FILTER_DYNLIB1) != TRUE)
+ TEST_ERROR
+
+ /* Set the number of paths to create for this test.
+ *
+ * This should be set high enough to ensure that at least one array
+ * expansion will take place. See H5PLpath.c for details.
+ */
+ n_starting_paths = 42;
+
+ /* Check that initialization is correct */
+ TESTING(" initialize");
- H5PLsize(&ndx);
+ if(H5PLsize(&n_paths) < 0)
+ TEST_ERROR
+ if(n_paths != 2)
+ TEST_ERROR
+
+ PASSED();
+ /****************/
+ /* H5PLremove() */
+ /****************/
+
+ /* Remove all the current paths */
TESTING(" remove");
- /* Remove all existing paths*/
- for(i=ndx; i > 0; i--)
- if(H5PLremove(i-1) < 0) {
- HDfprintf(stderr," at %d: %s\n", i, pathname);
+
+ /* Get the current size */
+ if(H5PLsize(&n_paths) < 0)
+ TEST_ERROR
+
+ /* Remove all existing paths */
+ for(u = n_paths; u > 0; u--)
+ if(H5PLremove(u-1) < 0) {
+ HDfprintf(stderr," at %u: %s\n", u, path);
TEST_ERROR
- } /* end if */
+ }
+
/* Verify the table is empty */
- H5PLsize(&ndx);
- if(ndx > 0) TEST_ERROR
+ if(H5PLsize(&n_paths) < 0)
+ TEST_ERROR
+ if(n_paths > 0)
+ TEST_ERROR
+
PASSED();
- TESTING(" remove (exceed min)");
- /* Exceed the min path removal */
+
+ TESTING(" remove (index 0 in empty table)");
+
+ /* Try to remove index zero in an empty list (SHOULD FAIL) */
H5E_BEGIN_TRY {
ret = H5PLremove(0);
} H5E_END_TRY
- if(ret >= 0) TEST_ERROR
+ if(ret >= 0)
+ TEST_ERROR
+
PASSED();
+
+ /****************/
+ /* H5PLappend() */
+ /****************/
+
TESTING(" append");
- /* Create multiple paths to fill table */
- for(i=0; i < H5PL_MAX_PATH_NUM; i++) {
- HDsprintf(pathname, "a_path_%d", i);
- if(H5PLappend(pathname) < 0) {
- HDfprintf(stderr," at %d: %s\n", i, pathname);
+
+ /* Add a bunch of paths to the path table */
+ for(u = 0; u < n_starting_paths; u++) {
+ HDsprintf(path, "a_path_%u", u);
+ if(H5PLappend(path) < 0) {
+ HDfprintf(stderr," at %u: %s\n", u, path);
TEST_ERROR
}
}
- /* Verify the table is full */
- H5PLsize(&ndx);
- if(ndx != H5PL_MAX_PATH_NUM) TEST_ERROR
- PASSED();
- TESTING(" append (exceed)");
- /* Exceed the max path append */
- H5E_BEGIN_TRY {
- HDsprintf(pathname, "a_path_%d", H5PL_MAX_PATH_NUM);
- ret = H5PLappend(pathname);
- } H5E_END_TRY
- if(ret >= 0) TEST_ERROR
PASSED();
- TESTING(" remove (exceed max)");
- /* Exceed the max path removal */
+
+ /**********************/
+ /* H5PLremove() again */
+ /**********************/
+
+ TESTING(" remove (index too high)");
+
+ /* Try to remove a path where the index is beyond the table capacity (SHOULD FAIL) */
H5E_BEGIN_TRY {
- ret = H5PLremove(H5PL_MAX_PATH_NUM);
+ ret = H5PLremove(n_starting_paths);
} H5E_END_TRY
- if(ret >= 0) TEST_ERROR
+
+ if(ret >= 0)
+ TEST_ERROR
+
PASSED();
+
+ /*************/
+ /* H5PLget() */
+ /*************/
+
TESTING(" get (path name)");
- if((pathlen = H5PLget(0, NULL, 0)) <= 0) {
+
+ /* Get the path length by passing in NULL */
+ if((path_len = H5PLget(0, NULL, 0)) <= 0) {
HDfprintf(stderr," get path 0 length failed\n");
TEST_ERROR
}
- if(pathlen != 8) TEST_ERROR
+ if(path_len != 8)
+ TEST_ERROR
- if((pathlen = H5PLget(0, pathname, 256)) <= 0) {
- HDfprintf(stderr," get 0 len: %d : %s\n", pathlen, pathname);
+ /* Get the path */
+ if((path_len = H5PLget(0, path, 256)) <= 0) {
+ HDfprintf(stderr," get 0 len: %u : %s\n", path_len, path);
TEST_ERROR
}
- if(HDstrcmp(pathname, "a_path_0") != 0) {
- HDfprintf(stderr," get 0: %s\n", pathname);
+ if(HDstrcmp(path, "a_path_0") != 0) {
+ HDfprintf(stderr," get 0: %s\n", path);
TEST_ERROR
}
+
PASSED();
- TESTING(" get (bounds)");
- if((pathlen = H5PLget(1, pathname, 256)) <= 0) TEST_ERROR
- if(HDstrcmp(pathname, "a_path_1") != 0) {
- HDfprintf(stderr," get 1: %s\n", pathname);
+
+ TESTING(" get (high and low indices)");
+
+ /* Get path at index 1 */
+ if((path_len = H5PLget(1, path, 256)) <= 0)
+ TEST_ERROR
+ if(HDstrcmp(path, "a_path_1") != 0) {
+ HDfprintf(stderr," get 1: %s\n", path);
TEST_ERROR
}
- if((pathlen = H5PLget(H5PL_MAX_PATH_NUM - 1, pathname, 256)) <= 0) TEST_ERROR
- HDsprintf(tempname, "a_path_%d", H5PL_MAX_PATH_NUM - 1);
- if(HDstrcmp(pathname, tempname) != 0) {
- HDfprintf(stderr," get %d: %s\n", H5PL_MAX_PATH_NUM - 1, pathname);
+
+ /* Get path at the last index */
+ if((path_len = H5PLget(n_starting_paths - 1, path, 256)) <= 0)
+ TEST_ERROR
+ HDsprintf(temp_name, "a_path_%u", n_starting_paths - 1);
+ if(HDstrcmp(path, temp_name) != 0) {
+ HDfprintf(stderr," get %u: %s\n", n_starting_paths - 1, path);
TEST_ERROR
}
+
PASSED();
- TESTING(" get (bounds exceed)");
+
+ TESTING(" get (index too high)");
+
+ /* Get path at the last + 1 index (SHOULD FAIL) */
H5E_BEGIN_TRY {
- pathlen = H5PLget(H5PL_MAX_PATH_NUM, NULL, 0);
+ path_len = H5PLget(n_starting_paths, NULL, 0);
} H5E_END_TRY
- if(pathlen > 0) TEST_ERROR
+ if(path_len > 0)
+ TEST_ERROR
+
PASSED();
- TESTING(" remove (verify for prepend)");
- /* Remove one path*/
- if(H5PLremove(8) < 0) TEST_ERROR
+
+ /*****************/
+ /* H5PLprepend() */
+ /*****************/
+
+ /* We'll remove a path at an arbitrary index and then
+ * prepend a new path.
+ */
+
+ TESTING(" remove (arbitrary index 1)");
+
+ /* Remove one path */
+ if(H5PLremove(8) < 0)
+ TEST_ERROR
/* Verify that the entries were moved */
- if((pathlen = H5PLget(8, pathname, 256)) <= 0) TEST_ERROR
- if(HDstrcmp(pathname, "a_path_9") != 0) {
- HDfprintf(stderr," get 8: %s\n", pathname);
+ if((path_len = H5PLget(8, path, 256)) <= 0)
+ TEST_ERROR
+ if(HDstrcmp(path, "a_path_9") != 0) {
+ HDfprintf(stderr," get 8: %s\n", path);
TEST_ERROR
}
+
+ /* Verify the table shrank */
+ if(H5PLsize(&n_paths) < 0)
+ TEST_ERROR
+ if(n_paths != n_starting_paths - 1)
+ TEST_ERROR
+
PASSED();
- /* Verify the table is not full */
- H5PLsize(&ndx);
- if (ndx != H5PL_MAX_PATH_NUM - 1) TEST_ERROR
TESTING(" prepend");
- /* Prepend one path*/
- HDsprintf(pathname, "a_path_%d", H5PL_MAX_PATH_NUM + 1);
- if(H5PLprepend(pathname) < 0) {
- HDfprintf(stderr," prepend %d: %s\n", H5PL_MAX_PATH_NUM + 1, pathname);
+
+ /* Prepend one path */
+ HDsprintf(path, "a_path_%d", n_starting_paths + 1);
+ if(H5PLprepend(path) < 0) {
+ HDfprintf(stderr," prepend %u: %s\n", n_starting_paths + 1, path);
TEST_ERROR
}
- /* Verify the table is full */
- H5PLsize(&ndx);
- if(ndx != H5PL_MAX_PATH_NUM) TEST_ERROR
+ /* Verify the table increased */
+ if(H5PLsize(&n_paths) < 0)
+ TEST_ERROR
+ if(n_paths != n_starting_paths)
+ TEST_ERROR
/* Verify that the entries were moved */
- if(H5PLget(8, pathname, 256) <= 0) TEST_ERROR
- if(HDstrcmp(pathname, "a_path_7") != 0) {
- HDfprintf(stderr," get 8: %s\n", pathname);
+ if(H5PLget(8, path, 256) <= 0)
+ TEST_ERROR
+ if(HDstrcmp(path, "a_path_7") != 0) {
+ HDfprintf(stderr," get 8: %s\n", path);
TEST_ERROR
}
- if(H5PLget(0, pathname, 256) <= 0) TEST_ERROR
- HDsprintf(tempname, "a_path_%d", H5PL_MAX_PATH_NUM + 1);
- if(HDstrcmp(pathname, tempname) != 0) {
- HDfprintf(stderr," get 0: %s\n", pathname);
+
+ /* Verify that the path was inserted at index zero */
+ if(H5PLget(0, path, 256) <= 0)
+ TEST_ERROR
+ HDsprintf(temp_name, "a_path_%d", n_starting_paths + 1);
+ if(HDstrcmp(path, temp_name) != 0) {
+ HDfprintf(stderr," get 0: %s\n", path);
TEST_ERROR
}
- PASSED();
- TESTING(" prepend (exceed)");
- /* Exceed the max path prepend */
- H5E_BEGIN_TRY {
- HDsprintf(pathname, "a_path_%d", H5PL_MAX_PATH_NUM + 2);
- ret = H5PLprepend(pathname);
- } H5E_END_TRY
- if(ret >= 0) TEST_ERROR
PASSED();
+
+ /*****************/
+ /* H5PLreplace() */
+ /*****************/
+
TESTING(" replace");
- /* Replace one path*/
- HDsprintf(pathname, "a_path_%d", H5PL_MAX_PATH_NUM + 4);
- if(H5PLreplace(pathname, 1) < 0) {
- HDfprintf(stderr," replace 1: %s\n", pathname);
+
+ /* Replace one path at index 1 */
+ HDsprintf(path, "a_path_%u", n_starting_paths + 4);
+ if(H5PLreplace(path, 1) < 0) {
+ HDfprintf(stderr," replace 1: %s\n", path);
TEST_ERROR
}
- /* Verify the table is full */
- H5PLsize(&ndx);
- if(ndx != H5PL_MAX_PATH_NUM) TEST_ERROR
+ /* Verify the table size remained the same */
+ if(H5PLsize(&n_paths) < 0)
+ TEST_ERROR
+ if(n_paths != n_starting_paths)
+ TEST_ERROR
+
+ /* Verify that the entries were not moved by
+ * inspecting the paths at indices +/- 1.
+ */
- /* Verify that the entries were not moved */
- if(H5PLget(0, pathname, 256) <= 0) TEST_ERROR
- HDsprintf(tempname, "a_path_%d", H5PL_MAX_PATH_NUM + 1);
- if(HDstrcmp(pathname, tempname) != 0) {
- HDfprintf(stderr," get 0: %s\n", pathname);
+ /* Check path at index 0 */
+ if(H5PLget(0, path, 256) <= 0)
+ TEST_ERROR
+ HDsprintf(temp_name, "a_path_%u", n_starting_paths + 1);
+ if(HDstrcmp(path, temp_name) != 0) {
+ HDfprintf(stderr," get 0: %s\n", path);
TEST_ERROR
}
- if(H5PLget(2, pathname, 256) <= 0) TEST_ERROR
- if(HDstrcmp(pathname, "a_path_1") != 0) {
- HDfprintf(stderr," get 2: %s\n", pathname);
+
+ /* Check path at index 2 */
+ if(H5PLget(2, path, 256) <= 0)
+ TEST_ERROR
+ if(HDstrcmp(path, "a_path_1") != 0) {
+ HDfprintf(stderr," get 2: %s\n", path);
TEST_ERROR
}
+
PASSED();
- TESTING(" remove (verify for insert)");
- /* Remove one path*/
- if(H5PLremove(4) < 0) TEST_ERROR
+
+ /****************/
+ /* H5PLinsert() */
+ /****************/
+
+ /* We'll remove a path at an arbitrary index and then
+ * insert a new path.
+ */
+
+ TESTING(" remove (arbitrary index 2)");
+
+ /* Remove one path */
+ if(H5PLremove(4) < 0)
+ TEST_ERROR
/* Verify that the entries were moved */
- if(H5PLget(4, pathname, 256) <= 0) TEST_ERROR
- if(HDstrcmp(pathname, "a_path_4") != 0) {
- HDfprintf(stderr," get 4: %s\n", pathname);
+ if(H5PLget(4, path, 256) <= 0)
+ TEST_ERROR
+ if(HDstrcmp(path, "a_path_4") != 0) {
+ HDfprintf(stderr," get 4: %s\n", path);
TEST_ERROR
}
+
+ /* Verify the table size */
+ if(H5PLsize(&n_paths) < 0)
+ TEST_ERROR
+ if(n_paths != n_starting_paths - 1)
+ TEST_ERROR
PASSED();
- /* Verify the table is not full */
- H5PLsize(&ndx);
- if(ndx != 15) TEST_ERROR
TESTING(" insert");
- /* Insert one path*/
- HDsprintf(pathname, "a_path_%d", H5PL_MAX_PATH_NUM + 5);
- if(H5PLinsert(pathname, 3) < 0) {
- HDfprintf(stderr," insert 3: %s\n", pathname);
+
+ /* Insert one path at index 3*/
+ HDsprintf(path, "a_path_%d", n_starting_paths + 5);
+ if(H5PLinsert(path, 3) < 0) {
+ HDfprintf(stderr," insert 3: %s\n", path);
TEST_ERROR
}
/* Verify that the entries were moved */
- if(H5PLget(4, pathname, 256) <= 0) TEST_ERROR
- if(HDstrcmp(pathname, "a_path_2") != 0) {
- HDfprintf(stderr," get 4: %s\n", pathname);
+ if(H5PLget(4, path, 256) <= 0)
+ TEST_ERROR
+ if(HDstrcmp(path, "a_path_2") != 0) {
+ HDfprintf(stderr," get 4: %s\n", path);
TEST_ERROR
}
+
+ /* Verify the table size increased */
+ if(H5PLsize(&n_paths) < 0)
+ TEST_ERROR
+ if(n_paths != n_starting_paths)
+ TEST_ERROR
+
PASSED();
- /* Verify the table is full */
- H5PLsize(&ndx);
- if(ndx != H5PL_MAX_PATH_NUM) TEST_ERROR
- TESTING(" insert (exceed)");
- /* Exceed the max path insert */
- H5E_BEGIN_TRY {
- HDsprintf(pathname, "a_path_%d", H5PL_MAX_PATH_NUM + 6);
- ret = H5PLinsert(pathname, 12);
- } H5E_END_TRY
- if(ret >= 0) TEST_ERROR
+ /****************/
+ /* H5PLremove() */
+ /****************/
+
+ /* Remove all the current paths */
+ TESTING(" remove (all)");
+
+ /* Get the current size */
+ if(H5PLsize(&n_paths) < 0)
+ TEST_ERROR
+
+ /* Remove all existing paths */
+ for(u = n_paths; u > 0; u--)
+ if(H5PLremove(u-1) < 0) {
+ HDfprintf(stderr," at %u: %s\n", u, path);
+ TEST_ERROR
+ }
+
+ /* Verify the table is empty */
+ if(H5PLsize(&n_paths) < 0)
+ TEST_ERROR
+ if(n_paths > 0)
+ TEST_ERROR
PASSED();
- ret_value = 0;
+
+ return SUCCEED;
error:
- return ret_value;
-}
+ return FAIL;
+} /* end test_path_api_calls() */
/*-------------------------------------------------------------------------
* Function: main
*
- * Purpose: Tests the plugin module (H5PL)
+ * Purpose: Tests the plugin module (H5PL)
*
- * Return: Success: exit(EXIT_SUCCESS)
- *
- * Failure: exit(EXIT_FAILURE)
- *
- * Programmer: Raymond Lu
- * 14 March 2013
+ * Return: EXIT_SUCCESS/EXIT_FAILURE
*
*-------------------------------------------------------------------------
*/
@@ -984,37 +1105,44 @@ main(void)
/* Testing setup */
h5_reset();
- fapl = h5_fileaccess();
+
+ if ((fapl = h5_fileaccess()) < 0)
+ TEST_ERROR
/* Turn off the chunk cache, so all the chunks are immediately written to disk */
- if(H5Pget_cache(fapl, &mdc_nelmts, &rdcc_nelmts, &rdcc_nbytes, &rdcc_w0) < 0) TEST_ERROR
+ if (H5Pget_cache(fapl, &mdc_nelmts, &rdcc_nelmts, &rdcc_nbytes, &rdcc_w0) < 0)
+ TEST_ERROR
rdcc_nbytes = 0;
- if(H5Pset_cache(fapl, mdc_nelmts, rdcc_nelmts, rdcc_nbytes, rdcc_w0) < 0) TEST_ERROR
+ if (H5Pset_cache(fapl, mdc_nelmts, rdcc_nelmts, rdcc_nbytes, rdcc_w0) < 0)
+ TEST_ERROR
/* Copy the file access property list */
- if((fapl2 = H5Pcopy(fapl)) < 0) TEST_ERROR
+ if ((fapl2 = H5Pcopy(fapl)) < 0)
+ TEST_ERROR
/* Set the "use the latest version of the format" bounds for creating objects in the file */
- if(H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) TEST_ERROR
+ if (H5Pset_libver_bounds(fapl2, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
+ TEST_ERROR
- h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Test with old & new format groups */
- for(new_format = FALSE; new_format <= TRUE; new_format++) {
+ for (new_format = FALSE; new_format <= TRUE; new_format++) {
hid_t my_fapl;
/* Set the FAPL for the type of format */
- if(new_format) {
+ if (new_format) {
HDputs("\nTesting with new file format:");
my_fapl = fapl2;
- } /* end if */
+ }
else {
HDputs("Testing with old file format:");
my_fapl = fapl;
- } /* end else */
+ }
/* Create the file for this test */
- if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0) TEST_ERROR
+ if ((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
+ TEST_ERROR
/* Test dynamically loaded filters for chunked dataset */
nerrors += (test_filters_for_datasets(file) < 0 ? 1 : 0);
@@ -1022,12 +1150,15 @@ main(void)
/* Test dynamically loaded filters for groups */
nerrors += (test_filters_for_groups(file) < 0 ? 1 : 0);
- if(H5Fclose(file) < 0) TEST_ERROR
+ if (H5Fclose(file) < 0)
+ TEST_ERROR
} /* end for */
/* Close FAPL */
- if(H5Pclose(fapl2) < 0) TEST_ERROR
- if(H5Pclose(fapl) < 0) TEST_ERROR
+ if (H5Pclose(fapl2) < 0)
+ TEST_ERROR
+ if (H5Pclose(fapl) < 0)
+ TEST_ERROR
/* Restore the default error handler (set in h5_reset()) */
h5_restore_err();
@@ -1036,10 +1167,12 @@ main(void)
/* Close the library so that all loaded plugin libraries are unloaded */
h5_reset();
- fapl = h5_fileaccess();
+ if ((fapl = h5_fileaccess()) < 0)
+ TEST_ERROR
/* Reopen the file for testing data reading */
- if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+ if ((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
+ TEST_ERROR
/* Read the data with filters */
nerrors += (test_read_with_filters(file) < 0 ? 1 : 0);
@@ -1052,29 +1185,33 @@ main(void)
/* Close the library so that all loaded plugin libraries are unloaded */
h5_reset();
- fapl = h5_fileaccess();
+ if ((fapl = h5_fileaccess()) < 0)
+ TEST_ERROR
/* Reopen the file for testing data reading */
- if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+ if ((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
+ TEST_ERROR
/* Read the data with disabled filters */
nerrors += (test_noread_with_filters(file) < 0 ? 1 : 0);
- if(H5Fclose(file) < 0) TEST_ERROR
+ if (H5Fclose(file) < 0)
+ TEST_ERROR
/* Test the APIs for access to the filter plugin path table */
- nerrors += (test_filter_path_apis() < 0 ? 1 : 0);
+ nerrors += (test_path_api_calls() < 0 ? 1 : 0);
- if(nerrors) TEST_ERROR
+ if (nerrors)
+ TEST_ERROR
HDprintf("All plugin tests passed.\n");
h5_cleanup(FILENAME, fapl);
- return 0;
+ HDexit(EXIT_SUCCESS);
error:
nerrors = MAX(1, nerrors);
HDprintf("***** %d PLUGIN TEST%s FAILED! *****\n", nerrors, 1 == nerrors ? "" : "S");
- return 1;
-}
+ HDexit(EXIT_FAILURE);
+} /* end main() */
diff --git a/test/tfile.c b/test/tfile.c
index 533bb24..027ad62 100644
--- a/test/tfile.c
+++ b/test/tfile.c
@@ -109,6 +109,7 @@
#define TEST_THRESHOLD10 10 /* Free space section threshold */
#define FSP_SIZE_DEF 4096 /* File space page size default */
#define FSP_SIZE512 512 /* File space page size */
+#define FSP_SIZE1G 1024*1024*1024 /* File space page size */
/* Declaration for test_libver_macros2() */
#define FILE6 "tfile6.h5" /* Test file */
@@ -3581,6 +3582,9 @@ test_filespace_info(const char *env_h5_drvr)
* Setting value less than 512 will return an error;
* --setting file space page size to 0
* --setting file space page size to 511
+ *
+ * File space page size has a maximum size of 1 gigabyte.
+ * Setting value greater than 1 gigabyte will return an error.
*/
/* Create file creation property list template */
fcpl = H5Pcreate(H5P_FILE_CREATE);
@@ -3598,6 +3602,12 @@ test_filespace_info(const char *env_h5_drvr)
} H5E_END_TRY;
VERIFY(ret, FAIL, "H5Pset_file_space_page_size");
+ /* Setting to 1GB+1: should fail */
+ H5E_BEGIN_TRY {
+ ret = H5Pset_file_space_page_size(fcpl, FSP_SIZE1G+1);
+ } H5E_END_TRY;
+ VERIFY(ret, FAIL, "H5Pset_file_space_page_size");
+
/* Setting to 512: should succeed */
ret = H5Pset_file_space_page_size(fcpl, FSP_SIZE512);
CHECK(ret, FAIL, "H5Pset_file_space_page_size");
@@ -3605,6 +3615,13 @@ test_filespace_info(const char *env_h5_drvr)
CHECK(ret, FAIL, "H5Pget_file_space_page_size");
VERIFY(fsp_size, FSP_SIZE512, "H5Pget_file_space_page_size");
+ /* Setting to 1GB: should succeed */
+ ret = H5Pset_file_space_page_size(fcpl, FSP_SIZE1G);
+ CHECK(ret, FAIL, "H5Pset_file_space_page_size");
+ ret = H5Pget_file_space_page_size(fcpl, &fsp_size);
+ CHECK(ret, FAIL, "H5Pget_file_space_page_size");
+ VERIFY(fsp_size, FSP_SIZE1G, "H5Pget_file_space_page_size");
+
/* Close property list */
H5Pclose(fcpl);
diff --git a/test/tmisc.c b/test/tmisc.c
index 22ae558..708ca9b 100644
--- a/test/tmisc.c
+++ b/test/tmisc.c
@@ -30,7 +30,6 @@
#include "testhdf5.h"
#include "H5srcdir.h"
#include "H5Dpkg.h" /* Datasets */
-#include "H5Iprivate.h" /* IDs, can be removed when H5I_REFERENCE is gone */
/* Definitions for misc. test #1 */
#define MISC1_FILE "tmisc1.h5"
@@ -179,17 +178,12 @@ typedef struct
#define MISC13_GROUP1_NAME "Group1"
#define MISC13_GROUP2_NAME "Group2"
#define MISC13_DTYPE_NAME "Datatype"
-#define MISC13_RANK 2
-#define MISC13_DIM1 20
-#define MISC13_DIM2 30
+#define MISC13_RANK 1
+#define MISC13_DIM1 600
#define MISC13_CHUNK_DIM1 10
-#define MISC13_CHUNK_DIM2 15
#define MISC13_USERBLOCK_SIZE 512
#define MISC13_COPY_BUF_SIZE 4096
-unsigned m13_data[MISC13_DIM1][MISC13_DIM2]; /* Data to write to dataset */
-unsigned m13_rdata[MISC13_DIM1][MISC13_DIM2]; /* Data read from dataset */
-
/* Definitions for misc. test #14 */
#define MISC14_FILE "tmisc14.h5"
#define MISC14_DSET1_NAME "Dataset1"
@@ -2084,38 +2078,36 @@ test_misc12(void)
/* Various routines for misc. 13 test */
static void
-init_data(void)
+misc13_init_data(unsigned *original_data)
{
- unsigned u,v; /* Local index variables */
+ unsigned u;
- for(u=0; u<MISC13_DIM1; u++)
- for(v=0; v<MISC13_DIM2; v++)
- m13_data[u][v]=(u*MISC13_DIM2)+v;
+ for(u = 0; u < MISC13_DIM1; u++)
+ original_data[u] = u;
}
-static int
-verify_data(void)
+static hbool_t
+misc13_verify_data_match(const unsigned *original_data, const unsigned *read_data)
{
- unsigned u,v; /* Local index variables */
+ unsigned u;
- for(u=0; u<MISC13_DIM1; u++)
- for(v=0; v<MISC13_DIM2; v++)
- if(m13_data[u][v]!=m13_rdata[u][v])
- return(-1);
- return(0);
+ for(u = 0; u < MISC13_DIM1; u++)
+ if(original_data[u] != read_data[u])
+ return FALSE;
+
+ return TRUE;
}
static void
-create_dataset(hid_t loc_id, const char *name, hid_t dcpl)
+misc13_create_dataset(hid_t loc_id, const char *name, hid_t dcpl, const unsigned *data)
{
- hid_t dsid; /* Dataset ID */
- hid_t sid; /* Dataspace ID */
- hsize_t dims[MISC13_RANK]; /* Dataset dimensions */
- herr_t ret; /* Generic return value */
+ hid_t dsid = -1; /* Dataset ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hsize_t dims[MISC13_RANK]; /* Dataset dimensions */
+ herr_t ret; /* Generic return value */
/* Create dataspace for use with dataset */
dims[0] = MISC13_DIM1;
- dims[1] = MISC13_DIM2;
sid = H5Screate_simple(MISC13_RANK, dims, NULL);
CHECK(sid, FAIL, "H5Screate_simple");
@@ -2124,7 +2116,7 @@ create_dataset(hid_t loc_id, const char *name, hid_t dcpl)
CHECK(dsid, FAIL, "H5Dcreate2");
/* Write some data to dataset */
- ret = H5Dwrite(dsid, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, m13_data);
+ ret = H5Dwrite(dsid, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
CHECK(ret, FAIL, "H5Dwrite");
/* Close the contiguous dataset */
@@ -2134,64 +2126,74 @@ create_dataset(hid_t loc_id, const char *name, hid_t dcpl)
/* Close the dataspace */
ret = H5Sclose(sid);
CHECK(ret, FAIL, "H5Sclose");
-}
+
+} /* end misc13_create_dataset() */
static void
-verify_dataset(hid_t loc_id, const char *name)
+misc13_verify_dataset(hid_t loc_id, const char *name, const unsigned *data)
{
- hid_t dsid; /* Dataset ID */
- herr_t ret; /* Generic return value */
+ unsigned *read_data = NULL; /* Data to write to dataset */
+ hid_t dsid = -1; /* Dataset ID */
+ herr_t ret; /* Generic return value */
+
+ /* Create a data buffer for the dataset read */
+ read_data = (unsigned *)HDcalloc(MISC13_DIM1, sizeof(unsigned));
+ CHECK(read_data, NULL, "HDcalloc");
/* Open the contiguous dataset in the root group */
dsid = H5Dopen2(loc_id, name, H5P_DEFAULT);
CHECK(dsid, FAIL, "H5Dopen2");
/* Read the data */
- ret = H5Dread(dsid, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, m13_rdata);
+ ret = H5Dread(dsid, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, H5P_DEFAULT, read_data);
CHECK(ret, FAIL, "H5Dread");
- /* Verify that the data is correct */
- ret=verify_data();
- CHECK(ret, FAIL, "verify_data");
+ /* Verify that the data are correct */
+ ret = misc13_verify_data_match(data, read_data);
+ CHECK(ret, FAIL, "misc13_verify_data_match");
/* Close the contiguous dataset */
ret = H5Dclose(dsid);
CHECK(ret, FAIL, "H5Dclose");
-}
+
+ /* Free the dataset read buffer */
+ HDfree(read_data);
+
+} /* end misc13_verify_dataset() */
static void
-create_hdf_file(const char *name)
+misc13_create_hdf_file(const char *name, const unsigned *data)
{
- hid_t fid; /* File ID */
- hid_t gid,gid2; /* Group IDs */
- hid_t tid; /* Datatype ID */
- hid_t dcpl; /* Dataset creation property list ID */
- hsize_t chunk_dims[MISC13_RANK]; /* Chunk dimensions */
- herr_t ret; /* Generic return value */
+ hid_t fid = -1; /* File ID */
+ hid_t gid1 = -1; /* Group ID (level 1) */
+ hid_t gid2 = -1; /* Group ID (level 2) */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t dcplid = -1; /* Dataset creation property list ID */
+ hsize_t chunk_dims[MISC13_RANK]; /* Chunk dimensions */
+ herr_t ret; /* Generic return value */
/* Create file */
- fid=H5Fcreate(name, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ fid = H5Fcreate(name, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
CHECK(fid, FAIL, "H5Fcreate");
/* Create DCPL for use with datasets */
- dcpl = H5Pcreate(H5P_DATASET_CREATE);
- CHECK(dcpl, FAIL, "H5Pcreate");
+ dcplid = H5Pcreate(H5P_DATASET_CREATE);
+ CHECK(dcplid, FAIL, "H5Pcreate");
/* Set the DCPL to be chunked */
- ret = H5Pset_layout(dcpl, H5D_CHUNKED);
+ ret = H5Pset_layout(dcplid, H5D_CHUNKED);
CHECK(ret, FAIL, "H5Pset_layout");
/* Use chunked storage for this DCPL */
chunk_dims[0] = MISC13_CHUNK_DIM1;
- chunk_dims[1] = MISC13_CHUNK_DIM2;
- ret = H5Pset_chunk(dcpl, MISC13_RANK, chunk_dims);
+ ret = H5Pset_chunk(dcplid, MISC13_RANK, chunk_dims);
CHECK(ret, FAIL, "H5Pset_chunk");
/* Create contiguous dataset in root group */
- create_dataset(fid, MISC13_DSET1_NAME, H5P_DEFAULT);
+ misc13_create_dataset(fid, MISC13_DSET1_NAME, H5P_DEFAULT, data);
/* Create chunked dataset in root group */
- create_dataset(fid, MISC13_DSET2_NAME, dcpl);
+ misc13_create_dataset(fid, MISC13_DSET2_NAME, dcplid, data);
/* Create a datatype to commit to the file */
tid = H5Tcopy(H5T_NATIVE_INT);
@@ -2206,11 +2208,11 @@ create_hdf_file(const char *name)
CHECK(ret, FAIL, "H5Tclose");
/* Create a group in the root group */
- gid = H5Gcreate2(fid, MISC13_GROUP1_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
- CHECK(gid, FAIL, "H5Gcreate2");
+ gid1 = H5Gcreate2(fid, MISC13_GROUP1_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(gid1, FAIL, "H5Gcreate2");
/* Create another group in the new group */
- gid2 = H5Gcreate2(gid, MISC13_GROUP2_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ gid2 = H5Gcreate2(gid1, MISC13_GROUP2_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
CHECK(gid2, FAIL, "H5Gcreate2");
/* Close the second group */
@@ -2218,17 +2220,17 @@ create_hdf_file(const char *name)
CHECK(ret, FAIL, "H5Gclose");
/* Create contiguous dataset in new group */
- create_dataset(gid, MISC13_DSET1_NAME, H5P_DEFAULT);
+ misc13_create_dataset(gid1, MISC13_DSET1_NAME, H5P_DEFAULT, data);
/* Create chunked dataset in new group */
- create_dataset(gid, MISC13_DSET2_NAME, dcpl);
+ misc13_create_dataset(gid1, MISC13_DSET2_NAME, dcplid, data);
/* Create a datatype to commit to the new group */
tid = H5Tcopy(H5T_NATIVE_INT);
CHECK(tid, FAIL, "H5Tcopy");
/* Create a named datatype in the new group */
- ret = H5Tcommit2(gid, MISC13_DTYPE_NAME, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ ret = H5Tcommit2(gid1, MISC13_DTYPE_NAME, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
CHECK(ret, FAIL, "H5Tcommit2");
/* Close named datatype */
@@ -2236,25 +2238,26 @@ create_hdf_file(const char *name)
CHECK(ret, FAIL, "H5Tclose");
/* Close the first group */
- ret = H5Gclose(gid);
+ ret = H5Gclose(gid1);
CHECK(ret, FAIL, "H5Gclose");
/* Close the DCPL */
- ret = H5Pclose(dcpl);
+ ret = H5Pclose(dcplid);
CHECK(ret, FAIL, "H5Pclose");
/* Close the file */
ret = H5Fclose(fid);
- HDassert(ret >= 0);
CHECK(ret, FAIL, "H5Fclose");
-}
+
+} /* end misc13_create_hdf_file() */
static void
-insert_user_block(const char *old_name, const char *new_name,const char *str,size_t size)
+misc13_insert_user_block(const char *old_name, const char *new_name, const char *str, size_t size)
{
- FILE *new_fp, *old_fp; /* Pointers to new & old files */
- void *user_block; /* Pointer to user block to write to file */
- void *copy_buf; /* Pointer to buffer for copying data */
+ FILE *new_fp = NULL; /* Pointers to new & old files */
+ FILE *old_fp = NULL;
+ void *user_block = NULL; /* Pointer to user block to write to file */
+ void *copy_buf = NULL; /* Pointer to buffer for copying data */
size_t written; /* Amount of data written to new file */
size_t read_in; /* Amount of data read in from old file */
int ret; /* Generic status value */
@@ -2264,10 +2267,10 @@ insert_user_block(const char *old_name, const char *new_name,const char *str,siz
CHECK(user_block, NULL, "HDcalloc");
/* Copy in the user block data */
- HDmemcpy(user_block,str,strlen(str));
+ HDmemcpy(user_block, str, strlen(str));
/* Open the new file */
- new_fp=HDfopen(new_name,"wb");
+ new_fp = HDfopen(new_name,"wb");
CHECK(new_fp, NULL, "HDfopen");
/* Write the user block to the new file */
@@ -2275,7 +2278,7 @@ insert_user_block(const char *old_name, const char *new_name,const char *str,siz
VERIFY(written, size, "HDfwrite");
/* Open the old file */
- old_fp=HDfopen(old_name,"rb");
+ old_fp = HDfopen(old_name,"rb");
CHECK(old_fp, NULL, "HDfopen");
/* Allocate space for the copy buffer */
@@ -2287,14 +2290,14 @@ insert_user_block(const char *old_name, const char *new_name,const char *str,siz
/* Write the data to the new file */
written = HDfwrite(copy_buf, (size_t)1, read_in, new_fp);
VERIFY(written, read_in, "HDfwrite");
- } /* end while */
+ }
/* Close the old file */
- ret=HDfclose(old_fp);
+ ret = HDfclose(old_fp);
VERIFY(ret, 0, "HDfclose");
/* Close the new file */
- ret=HDfclose(new_fp);
+ ret = HDfclose(new_fp);
VERIFY(ret, 0, "HDfclose");
/* Free the copy buffer */
@@ -2302,81 +2305,84 @@ insert_user_block(const char *old_name, const char *new_name,const char *str,siz
/* Free the user block */
HDfree(user_block);
-}
+
+} /* end misc13_insert_user_block() */
static void
-verify_file(const char *name, hsize_t blk_size, unsigned check_new_data)
+misc13_verify_file(const char *name, const unsigned *data, hsize_t userblock_size,
+ hbool_t check_for_new_dataset)
{
- hid_t fid; /* File ID */
- hid_t gid,gid2; /* Group IDs */
- hid_t tid; /* Datatype ID */
- hid_t fcpl; /* File creation property list ID */
- hsize_t userblock; /* Userblock size retrieved from FCPL */
- herr_t ret; /* Generic return value */
+ hid_t fid = -1; /* File ID */
+ hid_t gid1 = -1; /* Group IDs */
+ hid_t gid2 = -1; /* Group IDs */
+ hid_t tid = -1; /* Datatype ID */
+ hid_t fcplid = -1; /* File creation property list ID */
+ hsize_t ub_size_out; /* Userblock size retrieved from FCPL */
+ herr_t ret; /* Generic return value */
/* Open the file */
- fid=H5Fopen(name, H5F_ACC_RDONLY, H5P_DEFAULT);
+ fid = H5Fopen(name, H5F_ACC_RDONLY, H5P_DEFAULT);
CHECK(fid, FAIL, "H5Fopen");
/* Get the file's FCPL */
- fcpl=H5Fget_create_plist(fid);
- CHECK(fcpl, FAIL, "H5Fget_create_plist");
+ fcplid = H5Fget_create_plist(fid);
+ CHECK(fcplid, FAIL, "H5Fget_create_plist");
/* Get the user block size for the file */
- ret=H5Pget_userblock(fcpl,&userblock);
+ ret = H5Pget_userblock(fcplid, &ub_size_out);
CHECK(ret, FAIL, "H5Pget_userblock");
/* Check the userblock size */
- VERIFY(userblock, blk_size, "H5Pget_userblock");
+ VERIFY(userblock_size, ub_size_out, "H5Pget_userblock");
/* Close the FCPL */
- ret = H5Pclose(fcpl);
+ ret = H5Pclose(fcplid);
CHECK(ret, FAIL, "H5Pclose");
/* Verify the contiguous dataset in the root group */
- verify_dataset(fid,MISC13_DSET1_NAME);
+ misc13_verify_dataset(fid, MISC13_DSET1_NAME, data);
/* Verify the chunked dataset in the root group */
- verify_dataset(fid,MISC13_DSET2_NAME);
+ misc13_verify_dataset(fid, MISC13_DSET2_NAME, data);
/* Verify the "new" contiguous dataset in the root group, if asked */
- if(check_new_data)
- verify_dataset(fid,MISC13_DSET3_NAME);
+ if(check_for_new_dataset)
+ misc13_verify_dataset(fid, MISC13_DSET3_NAME, data);
/* Open the named datatype in the root group */
tid = H5Topen2(fid, MISC13_DTYPE_NAME, H5P_DEFAULT);
CHECK(tid, FAIL, "H5Topen2");
/* Verify the type is correct */
- VERIFY(H5Tequal(tid,H5T_NATIVE_INT), TRUE, "H5Tequal");
+ VERIFY(H5Tequal(tid, H5T_NATIVE_INT), TRUE, "H5Tequal");
/* Close named datatype */
- ret=H5Tclose(tid);
+ ret = H5Tclose(tid);
CHECK(ret, FAIL, "H5Tclose");
/* Open the first group */
- gid = H5Gopen2(fid, MISC13_GROUP1_NAME, H5P_DEFAULT);
- CHECK(gid, FAIL, "H5Gopen2");
+ gid1 = H5Gopen2(fid, MISC13_GROUP1_NAME, H5P_DEFAULT);
+ CHECK(gid1, FAIL, "H5Gopen2");
/* Verify the contiguous dataset in the first group */
- verify_dataset(gid,MISC13_DSET1_NAME);
+ misc13_verify_dataset(gid1, MISC13_DSET1_NAME, data);
/* Verify the chunked dataset in the first group */
- verify_dataset(gid,MISC13_DSET2_NAME);
+ misc13_verify_dataset(gid1, MISC13_DSET2_NAME, data);
/* Open the named datatype in the first group */
- tid = H5Topen2(gid,MISC13_DTYPE_NAME, H5P_DEFAULT);
+ tid = H5Topen2(gid1, MISC13_DTYPE_NAME, H5P_DEFAULT);
CHECK(tid, FAIL, "H5Topen2");
/* Verify the type is correct */
- VERIFY(H5Tequal(tid,H5T_NATIVE_INT), TRUE, "H5Tequal");
+ VERIFY(H5Tequal(tid, H5T_NATIVE_INT), TRUE, "H5Tequal");
/* Close named datatype */
- ret=H5Tclose(tid);
+ ret = H5Tclose(tid);
CHECK(ret, FAIL, "H5Tclose");
/* Open the second group */
- gid2 = H5Gopen2(gid, MISC13_GROUP2_NAME, H5P_DEFAULT);
+ gid2 = H5Gopen2(gid1, MISC13_GROUP2_NAME, H5P_DEFAULT);
CHECK(gid2, FAIL, "H5Gopen2");
/* Close the second group */
@@ -2384,31 +2390,33 @@ verify_file(const char *name, hsize_t blk_size, unsigned check_new_data)
CHECK(ret, FAIL, "H5Gclose");
/* Close the first group */
- ret = H5Gclose(gid);
+ ret = H5Gclose(gid1);
CHECK(ret, FAIL, "H5Gclose");
/* Close the file */
ret = H5Fclose(fid);
CHECK(ret, FAIL, "H5Fclose");
-}
+
+} /* end misc13_verify_file() */
static void
-add_to_new_file(const char *name)
+misc13_add_to_new_file(const char *name, const unsigned *data)
{
- hid_t fid; /* File ID */
+ hid_t fid = -1; /* File ID */
herr_t ret; /* Generic return value */
/* Open the file */
- fid=H5Fopen(name, H5F_ACC_RDWR, H5P_DEFAULT);
+ fid = H5Fopen(name, H5F_ACC_RDWR, H5P_DEFAULT);
CHECK(fid, FAIL, "H5Fopen");
/* Create new contiguous dataset in root group */
- create_dataset(fid, MISC13_DSET3_NAME, H5P_DEFAULT);
+ misc13_create_dataset(fid, MISC13_DSET3_NAME, H5P_DEFAULT, data);
/* Close the file */
ret = H5Fclose(fid);
CHECK(ret, FAIL, "H5Fclose");
-}
+
+} /* end misc13_add_to_new_file() */
/****************************************************************
**
@@ -2419,26 +2427,44 @@ add_to_new_file(const char *name)
static void
test_misc13(void)
{
+ unsigned *data = NULL; /* Data to write to dataset */
+ hsize_t userblock_size; /* Correct size of userblock */
+ hbool_t check_for_new_dataset; /* Whether to check for the post-userblock-creation dataset */
+
+ /* Create a data buffer for the datasets */
+ data = (unsigned *)HDcalloc(MISC13_DIM1, sizeof(unsigned));
+ CHECK(data, NULL, "HDcalloc");
+
/* Initialize data to write */
- init_data();
+ misc13_init_data(data);
/* Create first file, with no user block */
- create_hdf_file(MISC13_FILE_1);
+ misc13_create_hdf_file(MISC13_FILE_1, data);
/* Verify file contents are correct */
- verify_file(MISC13_FILE_1,(hsize_t)0,0);
+ userblock_size = 0;
+ check_for_new_dataset = FALSE;
+ misc13_verify_file(MISC13_FILE_1, data, userblock_size, check_for_new_dataset);
/* Create a new file by inserting a user block in front of the first file */
- insert_user_block(MISC13_FILE_1, MISC13_FILE_2, "Test String", (size_t)MISC13_USERBLOCK_SIZE);
+ misc13_insert_user_block(MISC13_FILE_1, MISC13_FILE_2, "Test String", (size_t)MISC13_USERBLOCK_SIZE);
/* Verify file contents are still correct */
- verify_file(MISC13_FILE_2,(hsize_t)MISC13_USERBLOCK_SIZE,0);
+ userblock_size = MISC13_USERBLOCK_SIZE;
+ check_for_new_dataset = FALSE;
+ misc13_verify_file(MISC13_FILE_2, data, userblock_size, check_for_new_dataset);
/* Make certain we can modify the new file */
- add_to_new_file(MISC13_FILE_2);
+ misc13_add_to_new_file(MISC13_FILE_2, data);
/* Verify file contents are still correct */
- verify_file(MISC13_FILE_2,(hsize_t)MISC13_USERBLOCK_SIZE,1);
+ userblock_size = MISC13_USERBLOCK_SIZE;
+ check_for_new_dataset = TRUE;
+ misc13_verify_file(MISC13_FILE_2, data, userblock_size, check_for_new_dataset);
+
+ /* Free the dataset buffer */
+ HDfree(data);
+
} /* end test_misc13() */
/****************************************************************
@@ -3448,34 +3474,6 @@ test_misc19(void)
HDfree(vfd_cls);
-/* Check H5I operations on references */
-
- /* Reference IDs are not used by the library so there's no
- * way of testing if incr/decr, etc. work. Instead, just
- * do a quick smoke check to ensure that a couple of basic
- * calls return sane values.
- *
- * H5I_REFERENCE has been declared deprecated with a tentative
- * removal version of HDF5 1.12.0.
- *
- * Delete this entire block when H5I_REFERENCE no longer exists.
- *
- * The H5Iprivate.h header was included to support H5I_nmembers()
- * so that can also probably be removed as well.
- */
-{
- htri_t tf; /* Boolean generic return */
- int64_t num_members; /* Number of members in type */
-
- tf = H5Itype_exists(H5I_REFERENCE);
- VERIFY(tf, TRUE, "H5Itype_exists");
-
- num_members = 999;
- num_members = H5I_nmembers(H5I_REFERENCE);
- VERIFY(num_members, 0, "H5Inmembers");
-
-} /* end block */
-
} /* end test_misc19() */
/****************************************************************
diff --git a/testpar/CMakeLists.txt b/testpar/CMakeLists.txt
index 298d326..e994b65 100644
--- a/testpar/CMakeLists.txt
+++ b/testpar/CMakeLists.txt
@@ -43,6 +43,7 @@ ENDMACRO (ADD_H5P_EXE file)
set (H5P_TESTS
t_mpi
+ t_bigio
t_cache
t_pflush1
t_pflush2
diff --git a/testpar/Makefile.am b/testpar/Makefile.am
index 90bdd04..b0fe0cd 100644
--- a/testpar/Makefile.am
+++ b/testpar/Makefile.am
@@ -23,7 +23,7 @@ AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/test
# Test programs. These are our main targets.
#
-TEST_PROG_PARA=t_mpi testphdf5 t_cache t_cache_image t_pflush1 t_pflush2 t_pshutdown t_prestart t_init_term t_shapesame t_filters_parallel
+TEST_PROG_PARA=t_mpi t_bigio testphdf5 t_cache t_cache_image t_pflush1 t_pflush2 t_pshutdown t_prestart t_init_term t_shapesame t_filters_parallel
check_PROGRAMS = $(TEST_PROG_PARA)
diff --git a/testpar/t_bigio.c b/testpar/t_bigio.c
new file mode 100644
index 0000000..a4a1323
--- /dev/null
+++ b/testpar/t_bigio.c
@@ -0,0 +1,2153 @@
+
+#include "hdf5.h"
+#include "testphdf5.h"
+#include "H5Dprivate.h" /* For Chunk tests */
+
+// int TestVerbosity = VERBO_LO; /* Default Verbosity is Low */
+
+/* Constants definitions */
+#define MAX_ERR_REPORT 10 /* Maximum number of errors reported */
+
+/* Define some handy debugging shorthands, routines, ... */
+/* debugging tools */
+
+#define MAINPROCESS (!mpi_rank) /* define process 0 as main process */
+
+/* Constants definitions */
+#define RANK 2
+
+#define IN_ORDER 1
+#define OUT_OF_ORDER 2
+
+#define DATASET1 "DSET1"
+#define DATASET2 "DSET2"
+#define DATASET3 "DSET3"
+#define DATASET4 "DSET4"
+#define DATASET5 "DSET5"
+#define DXFER_COLLECTIVE_IO 0x1 /* Collective IO*/
+#define DXFER_INDEPENDENT_IO 0x2 /* Independent IO collectively */
+#define DXFER_BIGCOUNT 536870916
+
+#define HYPER 1
+#define POINT 2
+#define ALL 3
+
+/* Dataset data type. Int's can be easily octo dumped. */
+typedef hsize_t B_DATATYPE;
+
+int facc_type = FACC_MPIO; /*Test file access type */
+int dxfer_coll_type = DXFER_COLLECTIVE_IO;
+size_t bigcount = DXFER_BIGCOUNT;
+char filename[20] = "bigio_test.h5";
+int nerrors = 0;
+int mpi_size, mpi_rank;
+
+hsize_t space_dim1 = SPACE_DIM1 * 256; // 4096
+hsize_t space_dim2 = SPACE_DIM2;
+
+static void coll_chunktest(const char* filename, int chunk_factor, int select_factor,
+ int api_option, int file_selection, int mem_selection, int mode);
+hid_t create_faccess_plist(MPI_Comm comm, MPI_Info info, int l_facc_type);
+
+/*
+ * Setup the coordinates for point selection.
+ */
+static void
+set_coords(hsize_t start[],
+ hsize_t count[],
+ hsize_t stride[],
+ hsize_t block[],
+ size_t num_points,
+ hsize_t coords[],
+ int order)
+{
+ hsize_t i,j, k = 0, m ,n, s1 ,s2;
+
+ if(OUT_OF_ORDER == order)
+ k = (num_points * RANK) - 1;
+ else if(IN_ORDER == order)
+ k = 0;
+
+ s1 = start[0];
+ s2 = start[1];
+
+ for(i = 0 ; i < count[0]; i++)
+ for(j = 0 ; j < count[1]; j++)
+ for(m = 0 ; m < block[0]; m++)
+ for(n = 0 ; n < block[1]; n++)
+ if(OUT_OF_ORDER == order) {
+ coords[k--] = s2 + (stride[1] * j) + n;
+ coords[k--] = s1 + (stride[0] * i) + m;
+ }
+ else if(IN_ORDER == order) {
+ coords[k++] = s1 + stride[0] * i + m;
+ coords[k++] = s2 + stride[1] * j + n;
+ }
+}
+
+/*
+ * Fill the dataset with trivial data for testing.
+ * Assume dimension rank is 2 and data is stored contiguous.
+ */
+static void
+fill_datasets(hsize_t start[], hsize_t block[], B_DATATYPE * dataset)
+{
+ B_DATATYPE *dataptr = dataset;
+ hsize_t i, j;
+
+ /* put some trivial data in the data_array */
+ for (i=0; i < block[0]; i++){
+ for (j=0; j < block[1]; j++){
+ *dataptr = (B_DATATYPE)((i+start[0])*100 + (j+start[1]+1));
+ dataptr++;
+ }
+ }
+}
+
+/*
+ * Setup the coordinates for point selection.
+ */
+void point_set(hsize_t start[],
+ hsize_t count[],
+ hsize_t stride[],
+ hsize_t block[],
+ size_t num_points,
+ hsize_t coords[],
+ int order)
+{
+ hsize_t i,j, k = 0, m ,n, s1 ,s2;
+
+ HDcompile_assert(RANK == 2);
+
+ if(OUT_OF_ORDER == order)
+ k = (num_points * RANK) - 1;
+ else if(IN_ORDER == order)
+ k = 0;
+
+ s1 = start[0];
+ s2 = start[1];
+
+ for(i = 0 ; i < count[0]; i++)
+ for(j = 0 ; j < count[1]; j++)
+ for(m = 0 ; m < block[0]; m++)
+ for(n = 0 ; n < block[1]; n++)
+ if(OUT_OF_ORDER == order) {
+ coords[k--] = s2 + (stride[1] * j) + n;
+ coords[k--] = s1 + (stride[0] * i) + m;
+ }
+ else if(IN_ORDER == order) {
+ coords[k++] = s1 + stride[0] * i + m;
+ coords[k++] = s2 + stride[1] * j + n;
+ }
+
+ if(VERBOSE_MED) {
+ printf("start[]=(%lu, %lu), count[]=(%lu, %lu), stride[]=(%lu, %lu), block[]=(%lu, %lu), total datapoints=%lu\n",
+ (unsigned long)start[0], (unsigned long)start[1], (unsigned long)count[0], (unsigned long)count[1],
+ (unsigned long)stride[0], (unsigned long)stride[1], (unsigned long)block[0], (unsigned long)block[1],
+ (unsigned long)(block[0] * block[1] * count[0] * count[1]));
+ k = 0;
+ for(i = 0; i < num_points ; i++) {
+ printf("(%d, %d)\n", (int)coords[k], (int)coords[k + 1]);
+ k += 2;
+ }
+ }
+}
+
+/*
+ * Print the content of the dataset.
+ */
+static void
+dataset_print(hsize_t start[], hsize_t block[], B_DATATYPE * dataset)
+{
+ B_DATATYPE *dataptr = dataset;
+ hsize_t i, j;
+
+ /* print the column heading */
+ printf("%-8s", "Cols:");
+ for (j=0; j < block[1]; j++){
+ printf("%3lu ", (unsigned long)(start[1]+j));
+ }
+ printf("\n");
+
+ /* print the slab data */
+ for (i=0; i < block[0]; i++){
+ printf("Row %2lu: ", (unsigned long)(i+start[0]));
+ for (j=0; j < block[1]; j++){
+ printf("%llu ", *dataptr++);
+ }
+ printf("\n");
+ }
+}
+
+
+/*
+ * Print the content of the dataset.
+ */
+static int
+verify_data(hsize_t start[], hsize_t count[], hsize_t stride[], hsize_t block[], B_DATATYPE *dataset, B_DATATYPE *original)
+{
+ hsize_t i, j;
+ int vrfyerrs;
+
+ /* print it if VERBOSE_MED */
+ if(VERBOSE_MED) {
+ printf("verify_data dumping:::\n");
+ printf("start(%lu, %lu), count(%lu, %lu), stride(%lu, %lu), block(%lu, %lu)\n",
+ (unsigned long)start[0], (unsigned long)start[1], (unsigned long)count[0], (unsigned long)count[1],
+ (unsigned long)stride[0], (unsigned long)stride[1], (unsigned long)block[0], (unsigned long)block[1]);
+ printf("original values:\n");
+ dataset_print(start, block, original);
+ printf("compared values:\n");
+ dataset_print(start, block, dataset);
+ }
+
+ vrfyerrs = 0;
+ for (i=0; i < block[0]; i++){
+ for (j=0; j < block[1]; j++){
+ if(*dataset != *original){
+ if(vrfyerrs++ < MAX_ERR_REPORT || VERBOSE_MED){
+ printf("Dataset Verify failed at [%lu][%lu](row %lu, col %lu): expect %llu, got %llu\n",
+ (unsigned long)i, (unsigned long)j,
+ (unsigned long)(i+start[0]), (unsigned long)(j+start[1]),
+ *(original), *(dataset));
+ }
+ dataset++;
+ original++;
+ }
+ }
+ }
+ if(vrfyerrs > MAX_ERR_REPORT && !VERBOSE_MED)
+ printf("[more errors ...]\n");
+ if(vrfyerrs)
+ printf("%d errors found in verify_data\n", vrfyerrs);
+ return(vrfyerrs);
+}
+
+/* Set up the selection */
+static void
+ccslab_set(int mpi_rank,
+ int mpi_size,
+ hsize_t start[],
+ hsize_t count[],
+ hsize_t stride[],
+ hsize_t block[],
+ int mode)
+{
+
+ switch (mode){
+
+ case BYROW_CONT:
+ /* Each process takes a slabs of rows. */
+ block[0] = 1;
+ block[1] = 1;
+ stride[0] = 1;
+ stride[1] = 1;
+ count[0] = space_dim1;
+ count[1] = space_dim2;
+ start[0] = mpi_rank*count[0];
+ start[1] = 0;
+
+ break;
+
+ case BYROW_DISCONT:
+ /* Each process takes several disjoint blocks. */
+ block[0] = 1;
+ block[1] = 1;
+ stride[0] = 3;
+ stride[1] = 3;
+ count[0] = space_dim1/(stride[0]*block[0]);
+ count[1] = (space_dim2)/(stride[1]*block[1]);
+ start[0] = space_dim1*mpi_rank;
+ start[1] = 0;
+
+ break;
+
+ case BYROW_SELECTNONE:
+ /* Each process takes a slabs of rows, there are
+ no selections for the last process. */
+ block[0] = 1;
+ block[1] = 1;
+ stride[0] = 1;
+ stride[1] = 1;
+ count[0] = ((mpi_rank >= MAX(1,(mpi_size-2)))?0:space_dim1);
+ count[1] = space_dim2;
+ start[0] = mpi_rank*count[0];
+ start[1] = 0;
+
+ break;
+
+ case BYROW_SELECTUNBALANCE:
+ /* The first one-third of the number of processes only
+ select top half of the domain, The rest will select the bottom
+ half of the domain. */
+
+ block[0] = 1;
+ count[0] = 2;
+ stride[0] = space_dim1*mpi_size/4+1;
+ block[1] = space_dim2;
+ count[1] = 1;
+ start[1] = 0;
+ stride[1] = 1;
+ if((mpi_rank *3)<(mpi_size*2)) start[0] = mpi_rank;
+ else start[0] = 1 + space_dim1*mpi_size/2 + (mpi_rank-2*mpi_size/3);
+ break;
+
+ case BYROW_SELECTINCHUNK:
+ /* Each process will only select one chunk */
+
+ block[0] = 1;
+ count[0] = 1;
+ start[0] = mpi_rank*space_dim1;
+ stride[0]= 1;
+ block[1] = space_dim2;
+ count[1] = 1;
+ stride[1]= 1;
+ start[1] = 0;
+
+ break;
+
+ default:
+ /* Unknown mode. Set it to cover the whole dataset. */
+ block[0] = space_dim1*mpi_size;
+ block[1] = space_dim2;
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = 0;
+ start[1] = 0;
+
+ break;
+ }
+ if (VERBOSE_MED){
+ printf("start[]=(%lu,%lu), count[]=(%lu,%lu), stride[]=(%lu,%lu), block[]=(%lu,%lu), total datapoints=%lu\n",
+ (unsigned long)start[0], (unsigned long)start[1], (unsigned long)count[0], (unsigned long)count[1],
+ (unsigned long)stride[0], (unsigned long)stride[1], (unsigned long)block[0], (unsigned long)block[1],
+ (unsigned long)(block[0]*block[1]*count[0]*count[1]));
+ }
+}
+
+
+/*
+ * Fill the dataset with trivial data for testing.
+ * Assume dimension rank is 2.
+ */
+static void
+ccdataset_fill(hsize_t start[],
+ hsize_t stride[],
+ hsize_t count[],
+ hsize_t block[],
+ DATATYPE * dataset,
+ int mem_selection)
+{
+ DATATYPE *dataptr = dataset;
+ DATATYPE *tmptr;
+ hsize_t i,j,k1,k2,k=0;
+ /* put some trivial data in the data_array */
+ tmptr = dataptr;
+
+ /* assign the disjoint block (two-dimensional)data array value
+ through the pointer */
+
+ for (k1 = 0; k1 < count[0]; k1++) {
+ for(i = 0; i < block[0]; i++) {
+ for(k2 = 0; k2 < count[1]; k2++) {
+ for(j = 0;j < block[1]; j++) {
+
+ if (ALL != mem_selection) {
+ dataptr = tmptr + ((start[0]+k1*stride[0]+i)*space_dim2+
+ start[1]+k2*stride[1]+j);
+ }
+ else {
+ dataptr = tmptr + k;
+ k++;
+ }
+
+ *dataptr = (DATATYPE)(k1+k2+i+j);
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Print the first block of the content of the dataset.
+ */
+static void
+ccdataset_print(hsize_t start[],
+ hsize_t block[],
+ DATATYPE * dataset)
+
+{
+ DATATYPE *dataptr = dataset;
+ hsize_t i, j;
+
+ /* print the column heading */
+ printf("Print only the first block of the dataset\n");
+ printf("%-8s", "Cols:");
+ for (j=0; j < block[1]; j++){
+ printf("%3lu ", (unsigned long)(start[1]+j));
+ }
+ printf("\n");
+
+ /* print the slab data */
+ for (i=0; i < block[0]; i++){
+ printf("Row %2lu: ", (unsigned long)(i+start[0]));
+ for (j=0; j < block[1]; j++){
+ printf("%03d ", *dataptr++);
+ }
+ printf("\n");
+ }
+}
+
+/*
+ * Print the content of the dataset.
+ */
+static int
+ccdataset_vrfy(hsize_t start[],
+ hsize_t count[],
+ hsize_t stride[],
+ hsize_t block[],
+ DATATYPE *dataset,
+ DATATYPE *original,
+ int mem_selection)
+{
+ hsize_t i, j,k1,k2,k=0;
+ int vrfyerrs;
+ DATATYPE *dataptr,*oriptr;
+
+ /* print it if VERBOSE_MED */
+ if (VERBOSE_MED) {
+ printf("dataset_vrfy dumping:::\n");
+ printf("start(%lu, %lu), count(%lu, %lu), stride(%lu, %lu), block(%lu, %lu)\n",
+ (unsigned long)start[0], (unsigned long)start[1], (unsigned long)count[0], (unsigned long)count[1],
+ (unsigned long)stride[0], (unsigned long)stride[1], (unsigned long)block[0], (unsigned long)block[1]);
+ printf("original values:\n");
+ ccdataset_print(start, block, original);
+ printf("compared values:\n");
+ ccdataset_print(start, block, dataset);
+ }
+
+ vrfyerrs = 0;
+
+ for (k1=0;k1<count[0];k1++) {
+ for(i=0;i<block[0];i++) {
+ for(k2=0; k2<count[1];k2++) {
+ for(j=0;j<block[1];j++) {
+ if (ALL != mem_selection) {
+ dataptr = dataset + ((start[0]+k1*stride[0]+i)*space_dim2+
+ start[1]+k2*stride[1]+j);
+ oriptr = original + ((start[0]+k1*stride[0]+i)*space_dim2+
+ start[1]+k2*stride[1]+j);
+ }
+ else {
+ dataptr = dataset + k;
+ oriptr = original + k;
+ k++;
+ }
+ if (*dataptr != *oriptr){
+ if (vrfyerrs++ < MAX_ERR_REPORT || VERBOSE_MED){
+ printf("Dataset Verify failed at [%lu][%lu]: expect %d, got %d\n",
+ (unsigned long)i, (unsigned long)j,
+ *(oriptr), *(dataptr));
+ }
+ }
+ }
+ }
+ }
+ }
+ if (vrfyerrs > MAX_ERR_REPORT && !VERBOSE_MED)
+ printf("[more errors ...]\n");
+ if (vrfyerrs)
+ printf("%d errors found in ccdataset_vrfy\n", vrfyerrs);
+ return(vrfyerrs);
+}
+
+/*
+ * Example of using the parallel HDF5 library to create two datasets
+ * in one HDF5 file with collective parallel access support.
+ * The Datasets are of sizes (number-of-mpi-processes x dim0) x dim1.
+ * Each process controls only a slab of size dim0 x dim1 within each
+ * dataset. [Note: not so yet. Datasets are of sizes dim0xdim1 and
+ * each process controls a hyperslab within.]
+ */
+
+static void
+dataset_big_write(void)
+{
+
+ hid_t xfer_plist; /* Dataset transfer properties list */
+ hid_t sid; /* Dataspace ID */
+ hid_t file_dataspace; /* File dataspace ID */
+ hid_t mem_dataspace; /* memory dataspace ID */
+ hid_t dataset;
+ hid_t datatype; /* Datatype ID */
+ hsize_t dims[RANK]; /* dataset dim sizes */
+ hsize_t start[RANK]; /* for hyperslab setting */
+ hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */
+ hsize_t block[RANK]; /* for hyperslab setting */
+ hsize_t *coords = NULL;
+ int i;
+ herr_t ret; /* Generic return value */
+ hid_t fid; /* HDF5 file ID */
+ hid_t acc_tpl; /* File access templates */
+ hsize_t h;
+ size_t num_points;
+ B_DATATYPE * wdata;
+
+
+ /* allocate memory for data buffer */
+ wdata = (B_DATATYPE *)malloc(bigcount*sizeof(B_DATATYPE));
+ VRFY((wdata != NULL), "wdata malloc succeeded");
+
+ /* setup file access template */
+ acc_tpl = H5Pcreate (H5P_FILE_ACCESS);
+ VRFY((acc_tpl >= 0), "H5P_FILE_ACCESS");
+ H5Pset_fapl_mpio(acc_tpl, MPI_COMM_WORLD, MPI_INFO_NULL);
+
+ /* create the file collectively */
+ fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
+ VRFY((fid >= 0), "H5Fcreate succeeded");
+
+ /* Release file-access template */
+ ret = H5Pclose(acc_tpl);
+ VRFY((ret >= 0), "");
+
+
+ /* Each process takes a slabs of rows. */
+ printf("\nTesting Dataset1 write by ROW\n");
+ /* Create a large dataset */
+ dims[0] = bigcount;
+ dims[1] = mpi_size;
+ sid = H5Screate_simple (RANK, dims, NULL);
+ VRFY((sid >= 0), "H5Screate_simple succeeded");
+ dataset = H5Dcreate2(fid, DATASET1, H5T_NATIVE_LLONG, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VRFY((dataset >= 0), "H5Dcreate2 succeeded");
+ H5Sclose(sid);
+
+ block[0] = dims[0]/mpi_size;
+ block[1] = dims[1];
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = mpi_rank*block[0];
+ start[1] = 0;
+
+ /* create a file dataspace independently */
+ file_dataspace = H5Dget_space (dataset);
+ VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
+ ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+
+ /* create a memory dataspace independently */
+ mem_dataspace = H5Screate_simple (RANK, block, NULL);
+ VRFY((mem_dataspace >= 0), "");
+
+ /* fill the local slab with some trivial data */
+ fill_datasets(start, block, wdata);
+ MESG("data_array initialized");
+ if(VERBOSE_MED){
+ MESG("data_array created");
+ dataset_print(start, block, wdata);
+ }
+
+ /* set up the collective transfer properties list */
+ xfer_plist = H5Pcreate (H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0), "H5Pcreate xfer succeeded");
+ ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist,H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((ret>= 0),"set independent IO collectively succeeded");
+ }
+
+ /* write data collectively */
+ MESG("writeAll by Row");
+ {
+ int j,k =0;
+ for (i=0; i < block[0]; i++){
+ for (j=0; j < block[1]; j++){
+ if(k < 10) {
+ printf("%lld ", wdata[k]);
+ k++;
+ }
+ }
+ }
+ printf("\n");
+ }
+
+ ret = H5Dwrite(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace,
+ xfer_plist, wdata);
+ VRFY((ret >= 0), "H5Dwrite dataset1 succeeded");
+
+ /* release all temporary handles. */
+ H5Sclose(file_dataspace);
+ H5Sclose(mem_dataspace);
+ H5Pclose(xfer_plist);
+
+ ret = H5Dclose(dataset);
+ VRFY((ret >= 0), "H5Dclose1 succeeded");
+
+
+
+ /* Each process takes a slabs of cols. */
+ printf("\nTesting Dataset2 write by COL\n");
+ /* Create a large dataset */
+ dims[0] = bigcount;
+ dims[1] = mpi_size;
+ sid = H5Screate_simple (RANK, dims, NULL);
+ VRFY((sid >= 0), "H5Screate_simple succeeded");
+ dataset = H5Dcreate2(fid, DATASET2, H5T_NATIVE_LLONG, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VRFY((dataset >= 0), "H5Dcreate2 succeeded");
+ H5Sclose(sid);
+
+ block[0] = dims[0];
+ block[1] = dims[1]/mpi_size;
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = 0;
+ start[1] = mpi_rank*block[1];
+
+ /* create a file dataspace independently */
+ file_dataspace = H5Dget_space (dataset);
+ VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
+ ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+
+ /* create a memory dataspace independently */
+ mem_dataspace = H5Screate_simple (RANK, block, NULL);
+ VRFY((mem_dataspace >= 0), "");
+
+ /* fill the local slab with some trivial data */
+ fill_datasets(start, block, wdata);
+ MESG("data_array initialized");
+ if(VERBOSE_MED){
+ MESG("data_array created");
+ dataset_print(start, block, wdata);
+ }
+
+ /* set up the collective transfer properties list */
+ xfer_plist = H5Pcreate (H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0), "H5Pcreate xfer succeeded");
+ ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist,H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((ret>= 0),"set independent IO collectively succeeded");
+ }
+
+ /* write data collectively */
+ MESG("writeAll by Col");
+ {
+ int j,k =0;
+ for (i=0; i < block[0]; i++){
+ for (j=0; j < block[1]; j++){
+ if(k < 10) {
+ printf("%lld ", wdata[k]);
+ k++;
+ }
+ }
+ }
+ printf("\n");
+ }
+
+ ret = H5Dwrite(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace,
+ xfer_plist, wdata);
+ VRFY((ret >= 0), "H5Dwrite dataset1 succeeded");
+
+ /* release all temporary handles. */
+ H5Sclose(file_dataspace);
+ H5Sclose(mem_dataspace);
+ H5Pclose(xfer_plist);
+
+ ret = H5Dclose(dataset);
+ VRFY((ret >= 0), "H5Dclose1 succeeded");
+
+
+
+ /* ALL selection */
+ printf("\nTesting Dataset3 write select ALL proc 0, NONE others\n");
+ /* Create a large dataset */
+ dims[0] = bigcount;
+ dims[1] = 1;
+ sid = H5Screate_simple (RANK, dims, NULL);
+ VRFY((sid >= 0), "H5Screate_simple succeeded");
+ dataset = H5Dcreate2(fid, DATASET3, H5T_NATIVE_LLONG, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VRFY((dataset >= 0), "H5Dcreate2 succeeded");
+ H5Sclose(sid);
+
+ /* create a file dataspace independently */
+ file_dataspace = H5Dget_space (dataset);
+ VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
+ if(MAINPROCESS) {
+ ret = H5Sselect_all(file_dataspace);
+ VRFY((ret >= 0), "H5Sset_all succeeded");
+ }
+ else {
+ ret = H5Sselect_none(file_dataspace);
+ VRFY((ret >= 0), "H5Sset_none succeeded");
+ }
+
+ /* create a memory dataspace independently */
+ mem_dataspace = H5Screate_simple (RANK, dims, NULL);
+ VRFY((mem_dataspace >= 0), "");
+ if(!MAINPROCESS) {
+ ret = H5Sselect_none(mem_dataspace);
+ VRFY((ret >= 0), "H5Sset_none succeeded");
+ }
+
+ /* set up the collective transfer properties list */
+ xfer_plist = H5Pcreate (H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0), "H5Pcreate xfer succeeded");
+ ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist,H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((ret>= 0),"set independent IO collectively succeeded");
+ }
+
+ /* fill the local slab with some trivial data */
+ fill_datasets(start, dims, wdata);
+ MESG("data_array initialized");
+ if(VERBOSE_MED){
+ MESG("data_array created");
+ }
+
+ /* write data collectively */
+ MESG("writeAll by process 0");
+ {
+ int j,k =0;
+ for (i=0; i < block[0]; i++){
+ for (j=0; j < block[1]; j++){
+ if(k < 10) {
+ printf("%lld ", wdata[k]);
+ k++;
+ }
+ }
+ }
+ printf("\n");
+ }
+
+ ret = H5Dwrite(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace,
+ xfer_plist, wdata);
+ VRFY((ret >= 0), "H5Dwrite dataset1 succeeded");
+
+ /* release all temporary handles. */
+ H5Sclose(file_dataspace);
+ H5Sclose(mem_dataspace);
+ H5Pclose(xfer_plist);
+
+ ret = H5Dclose(dataset);
+ VRFY((ret >= 0), "H5Dclose1 succeeded");
+
+ /* Point selection */
+ printf("\nTesting Dataset4 write point selection\n");
+ /* Create a large dataset */
+ dims[0] = bigcount;
+ dims[1] = mpi_size * 4;
+ sid = H5Screate_simple (RANK, dims, NULL);
+ VRFY((sid >= 0), "H5Screate_simple succeeded");
+ dataset = H5Dcreate2(fid, DATASET4, H5T_NATIVE_LLONG, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VRFY((dataset >= 0), "H5Dcreate2 succeeded");
+ H5Sclose(sid);
+
+ block[0] = dims[0]/2;
+ block[1] = 2;
+ stride[0] = dims[0]/2;
+ stride[1] = 2;
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = 0;
+ start[1] = dims[1]/mpi_size * mpi_rank;
+
+ num_points = bigcount;
+
+ coords = (hsize_t *)malloc(num_points * RANK * sizeof(hsize_t));
+ VRFY((coords != NULL), "coords malloc succeeded");
+
+ set_coords (start, count, stride, block, num_points, coords, IN_ORDER);
+ /* create a file dataspace */
+ file_dataspace = H5Dget_space (dataset);
+ VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
+ ret = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
+ VRFY((ret >= 0), "H5Sselect_elements succeeded");
+
+ if(coords) free(coords);
+
+ fill_datasets(start, block, wdata);
+ MESG("data_array initialized");
+ if(VERBOSE_MED){
+ MESG("data_array created");
+ dataset_print(start, block, wdata);
+ }
+
+ /* create a memory dataspace */
+ mem_dataspace = H5Screate_simple (1, &bigcount, NULL);
+ VRFY((mem_dataspace >= 0), "");
+
+ /* set up the collective transfer properties list */
+ xfer_plist = H5Pcreate (H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0), "H5Pcreate xfer succeeded");
+ ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist,H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((ret>= 0),"set independent IO collectively succeeded");
+ }
+
+ ret = H5Dwrite(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace,
+ xfer_plist, wdata);
+ VRFY((ret >= 0), "H5Dwrite dataset1 succeeded");
+
+ /* release all temporary handles. */
+ H5Sclose(file_dataspace);
+ H5Sclose(mem_dataspace);
+ H5Pclose(xfer_plist);
+
+ ret = H5Dclose(dataset);
+ VRFY((ret >= 0), "H5Dclose1 succeeded");
+
+ /* Irregular selection */
+ /* Need larger memory for data buffer */
+ free(wdata);
+#if 0
+ wdata = (B_DATATYPE *)malloc(bigcount*4*sizeof(B_DATATYPE));
+ VRFY((wdata != NULL), "wdata malloc succeeded");
+
+ printf("\nTesting Dataset5 write irregular selection\n");
+ /* Create a large dataset */
+ dims[0] = bigcount/6;
+ dims[1] = mpi_size * 4;
+ sid = H5Screate_simple (RANK, dims, NULL);
+ VRFY((sid >= 0), "H5Screate_simple succeeded");
+ dataset = H5Dcreate2(fid, DATASET5, H5T_NATIVE_LLONG, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ VRFY((dataset >= 0), "H5Dcreate2 succeeded");
+ H5Sclose(sid);
+
+ /* first select 1 col in this procs splice */
+ block[0] = dims[0];
+ block[1] = 1;
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = 0;
+ start[1] = mpi_rank * 4;
+
+ /* create a file dataspace */
+ file_dataspace = H5Dget_space (dataset);
+ VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
+
+ dims[1] = 4;
+ /* create a memory dataspace */
+ mem_dataspace = H5Screate_simple (RANK, dims, NULL);
+ VRFY((mem_dataspace >= 0), "");
+
+ ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+
+ start[1] = 0;
+ ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+
+ /* select every other row in the process splice and OR it with
+ the col selection to create an irregular selection */
+ for(h=0 ; h<dims[0] ; h+=2) {
+ block[0] = 1;
+ block[1] = 4;
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = h;
+ start[1] = mpi_rank * 4;
+
+ ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_OR, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+
+ start[1] = 0;
+ ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_OR, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+ }
+ printf("Setting up for collective transfer\n");
+ /* set up the collective transfer properties list */
+ xfer_plist = H5Pcreate (H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0), "H5Pcreate xfer succeeded");
+ ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist,H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((ret>= 0),"set independent IO collectively succeeded");
+ }
+
+ /* fill the local slab with some trivial data */
+ fill_datasets(start, dims, wdata);
+ MESG("data_array initialized");
+ if(VERBOSE_MED){
+ MESG("data_array created");
+ }
+
+ ret = H5Dwrite(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace,
+ xfer_plist, wdata);
+ VRFY((ret >= 0), "H5Dwrite dataset1 succeeded");
+
+ /* release all temporary handles. */
+ H5Sclose(file_dataspace);
+ H5Sclose(mem_dataspace);
+ H5Pclose(xfer_plist);
+
+ ret = H5Dclose(dataset);
+ VRFY((ret >= 0), "H5Dclose1 succeeded");
+
+ free(wdata);
+#endif
+ H5Fclose(fid);
+}
+
+/*
+ * Example of using the parallel HDF5 library to read two datasets
+ * in one HDF5 file with collective parallel access support.
+ * The Datasets are of sizes (number-of-mpi-processes x dim0) x dim1.
+ * Each process controls only a slab of size dim0 x dim1 within each
+ * dataset. [Note: not so yet. Datasets are of sizes dim0xdim1 and
+ * each process controls a hyperslab within.]
+ */
+
+static void
+dataset_big_read(void)
+{
+ hid_t fid; /* HDF5 file ID */
+ hid_t acc_tpl; /* File access templates */
+ hid_t xfer_plist; /* Dataset transfer properties list */
+ hid_t file_dataspace; /* File dataspace ID */
+ hid_t mem_dataspace; /* memory dataspace ID */
+ hid_t dataset;
+ B_DATATYPE *rdata = NULL; /* data buffer */
+ B_DATATYPE *wdata = NULL; /* expected data buffer */
+ hsize_t dims[RANK]; /* dataset dim sizes */
+ hsize_t start[RANK]; /* for hyperslab setting */
+ hsize_t count[RANK], stride[RANK]; /* for hyperslab setting */
+ hsize_t block[RANK]; /* for hyperslab setting */
+ int i,j,k;
+ hsize_t h;
+ size_t num_points;
+ hsize_t *coords = NULL;
+ herr_t ret; /* Generic return value */
+
+ /* allocate memory for data buffer */
+ rdata = (B_DATATYPE *)malloc(bigcount*sizeof(B_DATATYPE));
+ VRFY((rdata != NULL), "rdata malloc succeeded");
+ wdata = (B_DATATYPE *)malloc(bigcount*sizeof(B_DATATYPE));
+ VRFY((wdata != NULL), "wdata malloc succeeded");
+
+ memset(rdata, 0, bigcount*sizeof(B_DATATYPE));
+
+ /* setup file access template */
+ acc_tpl = H5Pcreate (H5P_FILE_ACCESS);
+ VRFY((acc_tpl >= 0), "H5P_FILE_ACCESS");
+ H5Pset_fapl_mpio(acc_tpl, MPI_COMM_WORLD, MPI_INFO_NULL);
+
+ /* open the file collectively */
+ fid=H5Fopen(filename,H5F_ACC_RDONLY,acc_tpl);
+ VRFY((fid >= 0), "H5Fopen succeeded");
+
+ /* Release file-access template */
+ ret = H5Pclose(acc_tpl);
+ VRFY((ret >= 0), "");
+
+
+ printf("\nRead Testing Dataset1 by COL\n");
+ dataset = H5Dopen2(fid, DATASET1, H5P_DEFAULT);
+ VRFY((dataset >= 0), "H5Dopen2 succeeded");
+
+ dims[0] = bigcount;
+ dims[1] = mpi_size;
+ /* Each process takes a slabs of cols. */
+ block[0] = dims[0];
+ block[1] = dims[1]/mpi_size;
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = 0;
+ start[1] = mpi_rank*block[1];
+
+ /* create a file dataspace independently */
+ file_dataspace = H5Dget_space (dataset);
+ VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
+ ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+
+ /* create a memory dataspace independently */
+ mem_dataspace = H5Screate_simple (RANK, block, NULL);
+ VRFY((mem_dataspace >= 0), "");
+
+ /* fill dataset with test data */
+ fill_datasets(start, block, wdata);
+ MESG("data_array initialized");
+ if(VERBOSE_MED){
+ MESG("data_array created");
+ }
+
+ /* set up the collective transfer properties list */
+ xfer_plist = H5Pcreate (H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0), "");
+ ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pcreate xfer succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist,H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((ret>= 0),"set independent IO collectively succeeded");
+ }
+
+ /* read data collectively */
+ ret = H5Dread(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace,
+ xfer_plist, rdata);
+ VRFY((ret >= 0), "H5Dread dataset1 succeeded");
+
+ {
+ for (i=0; i < block[0]; i++){
+ for (j=0; j < block[1]; j++){
+ if(k < 10) {
+ printf("%lld ", rdata[k]);
+ k++;
+ }
+ }
+ }
+ printf("\n");
+ }
+
+ /* verify the read data with original expected data */
+ ret = verify_data(start, count, stride, block, rdata, wdata);
+ if(ret) {fprintf(stderr, "verify failed\n"); exit(1);}
+
+ /* release all temporary handles. */
+ H5Sclose(file_dataspace);
+ H5Sclose(mem_dataspace);
+ H5Pclose(xfer_plist);
+ ret = H5Dclose(dataset);
+ VRFY((ret >= 0), "H5Dclose1 succeeded");
+
+
+ printf("\nRead Testing Dataset2 by ROW\n");
+ memset(rdata, 0, bigcount*sizeof(B_DATATYPE));
+ dataset = H5Dopen2(fid, DATASET2, H5P_DEFAULT);
+ VRFY((dataset >= 0), "H5Dopen2 succeeded");
+
+ dims[0] = bigcount;
+ dims[1] = mpi_size;
+ /* Each process takes a slabs of rows. */
+ block[0] = dims[0]/mpi_size;
+ block[1] = dims[1];
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = mpi_rank*block[0];
+ start[1] = 0;
+
+ /* create a file dataspace independently */
+ file_dataspace = H5Dget_space (dataset);
+ VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
+ ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+
+ /* create a memory dataspace independently */
+ mem_dataspace = H5Screate_simple (RANK, block, NULL);
+ VRFY((mem_dataspace >= 0), "");
+
+ /* fill dataset with test data */
+ fill_datasets(start, block, wdata);
+ MESG("data_array initialized");
+ if(VERBOSE_MED){
+ MESG("data_array created");
+ }
+
+ /* set up the collective transfer properties list */
+ xfer_plist = H5Pcreate (H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0), "");
+ ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pcreate xfer succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist,H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((ret>= 0),"set independent IO collectively succeeded");
+ }
+
+ /* read data collectively */
+ ret = H5Dread(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace,
+ xfer_plist, rdata);
+ VRFY((ret >= 0), "H5Dread dataset2 succeeded");
+
+ {
+ for (i=0; i < block[0]; i++){
+ for (j=0; j < block[1]; j++){
+ if(k < 10) {
+ printf("%lld ", rdata[k]);
+ k++;
+ }
+ }
+ }
+ printf("\n");
+ }
+
+ /* verify the read data with original expected data */
+ ret = verify_data(start, count, stride, block, rdata, wdata);
+ if(ret) {fprintf(stderr, "verify failed\n"); exit(1);}
+
+ /* release all temporary handles. */
+ H5Sclose(file_dataspace);
+ H5Sclose(mem_dataspace);
+ H5Pclose(xfer_plist);
+ ret = H5Dclose(dataset);
+ VRFY((ret >= 0), "H5Dclose1 succeeded");
+
+
+ printf("\nRead Testing Dataset3 read select ALL proc 0, NONE others\n");
+ memset(rdata, 0, bigcount*sizeof(B_DATATYPE));
+ dataset = H5Dopen2(fid, DATASET3, H5P_DEFAULT);
+ VRFY((dataset >= 0), "H5Dopen2 succeeded");
+
+ dims[0] = bigcount;
+ dims[1] = 1;
+
+ /* create a file dataspace independently */
+ file_dataspace = H5Dget_space (dataset);
+ VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
+ if(MAINPROCESS) {
+ ret = H5Sselect_all(file_dataspace);
+ VRFY((ret >= 0), "H5Sset_all succeeded");
+ }
+ else {
+ ret = H5Sselect_none(file_dataspace);
+ VRFY((ret >= 0), "H5Sset_none succeeded");
+ }
+
+ /* create a memory dataspace independently */
+ mem_dataspace = H5Screate_simple (RANK, dims, NULL);
+ VRFY((mem_dataspace >= 0), "");
+ if(!MAINPROCESS) {
+ ret = H5Sselect_none(mem_dataspace);
+ VRFY((ret >= 0), "H5Sset_none succeeded");
+ }
+
+ /* fill dataset with test data */
+ fill_datasets(start, dims, wdata);
+ MESG("data_array initialized");
+ if(VERBOSE_MED){
+ MESG("data_array created");
+ }
+
+ /* set up the collective transfer properties list */
+ xfer_plist = H5Pcreate (H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0), "");
+ ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pcreate xfer succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist,H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((ret>= 0),"set independent IO collectively succeeded");
+ }
+
+ /* read data collectively */
+ ret = H5Dread(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace,
+ xfer_plist, rdata);
+ VRFY((ret >= 0), "H5Dread dataset3 succeeded");
+
+ {
+ for (i=0; i < block[0]; i++){
+ for (j=0; j < block[1]; j++){
+ if(k < 10) {
+ printf("%lld ", rdata[k]);
+ k++;
+ }
+ }
+ }
+ printf("\n");
+ }
+
+ if(MAINPROCESS) {
+ /* verify the read data with original expected data */
+ ret = verify_data(start, count, stride, block, rdata, wdata);
+ if(ret) {fprintf(stderr, "verify failed\n"); exit(1);}
+ }
+
+ /* release all temporary handles. */
+ H5Sclose(file_dataspace);
+ H5Sclose(mem_dataspace);
+ H5Pclose(xfer_plist);
+ ret = H5Dclose(dataset);
+ VRFY((ret >= 0), "H5Dclose1 succeeded");
+
+ printf("\nRead Testing Dataset4 with Point selection\n");
+ dataset = H5Dopen2(fid, DATASET4, H5P_DEFAULT);
+ VRFY((dataset >= 0), "H5Dopen2 succeeded");
+
+ dims[0] = bigcount;
+ dims[1] = mpi_size * 4;
+
+ block[0] = dims[0]/2;
+ block[1] = 2;
+ stride[0] = dims[0]/2;
+ stride[1] = 2;
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = 0;
+ start[1] = dims[1]/mpi_size * mpi_rank;
+
+ fill_datasets(start, block, wdata);
+ MESG("data_array initialized");
+ if(VERBOSE_MED){
+ MESG("data_array created");
+ dataset_print(start, block, wdata);
+ }
+
+ num_points = bigcount;
+
+ coords = (hsize_t *)malloc(num_points * RANK * sizeof(hsize_t));
+ VRFY((coords != NULL), "coords malloc succeeded");
+
+ set_coords (start, count, stride, block, num_points, coords, IN_ORDER);
+ /* create a file dataspace */
+ file_dataspace = H5Dget_space (dataset);
+ VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
+ ret = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
+ VRFY((ret >= 0), "H5Sselect_elements succeeded");
+
+ if(coords) free(coords);
+
+ /* create a memory dataspace */
+ mem_dataspace = H5Screate_simple (1, &bigcount, NULL);
+ VRFY((mem_dataspace >= 0), "");
+
+ /* set up the collective transfer properties list */
+ xfer_plist = H5Pcreate (H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0), "");
+ ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pcreate xfer succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist,H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((ret>= 0),"set independent IO collectively succeeded");
+ }
+
+ /* read data collectively */
+ ret = H5Dread(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace,
+ xfer_plist, rdata);
+ VRFY((ret >= 0), "H5Dread dataset1 succeeded");
+
+ ret = verify_data(start, count, stride, block, rdata, wdata);
+ if(ret) {fprintf(stderr, "verify failed\n"); exit(1);}
+
+ /* release all temporary handles. */
+ H5Sclose(file_dataspace);
+ H5Sclose(mem_dataspace);
+ H5Pclose(xfer_plist);
+ ret = H5Dclose(dataset);
+ VRFY((ret >= 0), "H5Dclose1 succeeded");
+
+ printf("\nRead Testing Dataset5 with Irregular selection\n");
+ /* Need larger memory for data buffer */
+ free(wdata);
+ free(rdata);
+#if 0
+ wdata = (B_DATATYPE *)malloc(bigcount*4*sizeof(B_DATATYPE));
+ VRFY((wdata != NULL), "wdata malloc succeeded");
+ rdata = (B_DATATYPE *)malloc(bigcount*4*sizeof(B_DATATYPE));
+ VRFY((rdata != NULL), "rdata malloc succeeded");
+
+ dataset = H5Dopen2(fid, DATASET5, H5P_DEFAULT);
+ VRFY((dataset >= 0), "H5Dopen2 succeeded");
+
+ dims[0] = bigcount;
+ dims[1] = mpi_size * 4;
+
+ /* first select 1 col in this proc splice */
+ block[0] = dims[0];
+ block[1] = 1;
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = 0;
+ start[1] = mpi_rank * 4;
+
+ /* get file dataspace */
+ file_dataspace = H5Dget_space (dataset);
+ VRFY((file_dataspace >= 0), "H5Dget_space succeeded");
+
+ /* create a memory dataspace */
+ dims[1] = 4;
+ mem_dataspace = H5Screate_simple (RANK, dims, NULL);
+ VRFY((mem_dataspace >= 0), "");
+
+ ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+
+ start[1] = 0;
+ ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+
+ /* select every other row in the process splice and OR it with
+ the col selection to create an irregular selection */
+ for(h=0 ; h<dims[0] ; h+=2) {
+ block[0] = 1;
+ block[1] = 4;
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = h;
+ start[1] = mpi_rank * 4;
+
+ ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_OR, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+
+ start[1] = 0;
+ ret = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_OR, start, stride, count, block);
+ VRFY((ret >= 0), "H5Sset_hyperslab succeeded");
+
+ //fprintf(stderr, "%d: %d - %d\n", mpi_rank, (int)h, (int)H5Sget_select_npoints(mem_dataspace));
+ }
+
+ /* set up the collective transfer properties list */
+ xfer_plist = H5Pcreate (H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0), "");
+ ret = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((ret >= 0), "H5Pcreate xfer succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ ret = H5Pset_dxpl_mpio_collective_opt(xfer_plist,H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((ret>= 0),"set independent IO collectively succeeded");
+ }
+
+ /* read data collectively */
+ ret = H5Dread(dataset, H5T_NATIVE_LLONG, mem_dataspace, file_dataspace,
+ xfer_plist, rdata);
+ VRFY((ret >= 0), "H5Dread dataset1 succeeded");
+
+ /* fill dataset with test data */
+ fill_datasets(start, dims, wdata);
+ MESG("data_array initialized");
+ if(VERBOSE_MED){
+ MESG("data_array created");
+ }
+
+
+
+ /* verify the read data with original expected data */
+ block[0] = dims[0];
+ block[1] = 1;
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = 0;
+ start[1] = 0;
+ ret = verify_data(start, count, stride, block, rdata, wdata);
+ if(ret) {fprintf(stderr, "verify failed\n"); exit(1);}
+
+ for(h=0 ; h<dims[0] ; h+=2) {
+ block[0] = 1;
+ block[1] = 4;
+ stride[0] = block[0];
+ stride[1] = block[1];
+ count[0] = 1;
+ count[1] = 1;
+ start[0] = h;
+ start[1] = 0;
+ ret = verify_data(start, count, stride, block, rdata, wdata);
+ if(ret) {fprintf(stderr, "verify failed\n"); exit(1);}
+ }
+
+ /* release all temporary handles. */
+ H5Sclose(file_dataspace);
+ H5Sclose(mem_dataspace);
+ H5Pclose(xfer_plist);
+ ret = H5Dclose(dataset);
+ VRFY((ret >= 0), "H5Dclose1 succeeded");
+
+ H5Fclose(fid);
+
+ /* release data buffers */
+ if(rdata) free(rdata);
+ if(wdata) free(wdata);
+#endif
+} /* dataset_large_readAll */
+
+
+/*
+ * Create the appropriate File access property list
+ */
+hid_t
+create_faccess_plist(MPI_Comm comm, MPI_Info info, int l_facc_type)
+{
+ hid_t ret_pl = -1;
+ herr_t ret; /* generic return value */
+ int mpi_rank; /* mpi variables */
+
+ /* need the rank for error checking macros */
+ MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
+
+ ret_pl = H5Pcreate (H5P_FILE_ACCESS);
+ VRFY((ret_pl >= 0), "H5P_FILE_ACCESS");
+
+ if (l_facc_type == FACC_DEFAULT)
+ return (ret_pl);
+
+ if (l_facc_type == FACC_MPIO){
+ /* set Parallel access with communicator */
+ ret = H5Pset_fapl_mpio(ret_pl, comm, info);
+ VRFY((ret >= 0), "");
+ ret = H5Pset_all_coll_metadata_ops(ret_pl, TRUE);
+ VRFY((ret >= 0), "");
+ ret = H5Pset_coll_metadata_write(ret_pl, TRUE);
+ VRFY((ret >= 0), "");
+ return(ret_pl);
+ }
+
+ if (l_facc_type == (FACC_MPIO | FACC_SPLIT)){
+ hid_t mpio_pl;
+
+ mpio_pl = H5Pcreate (H5P_FILE_ACCESS);
+ VRFY((mpio_pl >= 0), "");
+ /* set Parallel access with communicator */
+ ret = H5Pset_fapl_mpio(mpio_pl, comm, info);
+ VRFY((ret >= 0), "");
+
+ /* setup file access template */
+ ret_pl = H5Pcreate (H5P_FILE_ACCESS);
+ VRFY((ret_pl >= 0), "");
+ /* set Parallel access with communicator */
+ ret = H5Pset_fapl_split(ret_pl, ".meta", mpio_pl, ".raw", mpio_pl);
+ VRFY((ret >= 0), "H5Pset_fapl_split succeeded");
+ H5Pclose(mpio_pl);
+ return(ret_pl);
+ }
+
+ /* unknown file access types */
+ return (ret_pl);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: coll_chunk1
+ *
+ * Purpose: Wrapper to test the collective chunk IO for regular JOINT
+ selection with a single chunk
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Unknown
+ * July 12th, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/* ------------------------------------------------------------------------
+ * Descriptions for the selection: One big singluar selection inside one chunk
+ * Two dimensions,
+ *
+ * dim1 = space_dim1(5760)*mpi_size
+ * dim2 = space_dim2(3)
+ * chunk_dim1 = dim1
+ * chunk_dim2 = dim2
+ * block = 1 for all dimensions
+ * stride = 1 for all dimensions
+ * count0 = space_dim1(5760)
+ * count1 = space_dim2(3)
+ * start0 = mpi_rank*space_dim1
+ * start1 = 0
+ * ------------------------------------------------------------------------
+ */
+
+void
+coll_chunk1(void)
+{
+ if (MAINPROCESS)
+ printf("coll_chunk1\n");
+
+ coll_chunktest(filename, 1, BYROW_CONT, API_NONE, HYPER, HYPER, OUT_OF_ORDER);
+ coll_chunktest(filename, 1, BYROW_CONT, API_NONE, HYPER, POINT, OUT_OF_ORDER);
+ coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, ALL, OUT_OF_ORDER);
+ coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, POINT, OUT_OF_ORDER);
+ coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, HYPER, OUT_OF_ORDER);
+
+ coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, ALL, IN_ORDER);
+ coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, POINT, IN_ORDER);
+ coll_chunktest(filename, 1, BYROW_CONT, API_NONE, POINT, HYPER, IN_ORDER);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: coll_chunk2
+ *
+ * Purpose: Wrapper to test the collective chunk IO for regular DISJOINT
+ selection with a single chunk
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Unknown
+ * July 12th, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+ /* ------------------------------------------------------------------------
+ * Descriptions for the selection: many disjoint selections inside one chunk
+ * Two dimensions,
+ *
+ * dim1 = space_dim1*mpi_size(5760)
+ * dim2 = space_dim2(3)
+ * chunk_dim1 = dim1
+ * chunk_dim2 = dim2
+ * block = 1 for all dimensions
+ * stride = 3 for all dimensions
+ * count0 = space_dim1/stride0(5760/3)
+ * count1 = space_dim2/stride(3/3 = 1)
+ * start0 = mpi_rank*space_dim1
+ * start1 = 0
+ *
+ * ------------------------------------------------------------------------
+ */
+void
+coll_chunk2(void)
+{
+ if (MAINPROCESS)
+ printf("coll_chunk2\n");
+
+ coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, HYPER, HYPER, OUT_OF_ORDER);
+ coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, HYPER, POINT, OUT_OF_ORDER);
+ coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, ALL, OUT_OF_ORDER);
+ coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, POINT, OUT_OF_ORDER);
+ coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, HYPER, OUT_OF_ORDER);
+
+ coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, ALL, IN_ORDER);
+ coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, POINT, IN_ORDER);
+ coll_chunktest(filename, 1, BYROW_DISCONT, API_NONE, POINT, HYPER, IN_ORDER);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: coll_chunk3
+ *
+ * Purpose: Wrapper to test the collective chunk IO for regular JOINT
+ selection with at least number of 2*mpi_size chunks
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Unknown
+ * July 12th, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/* ------------------------------------------------------------------------
+ * Descriptions for the selection: one singular selection accross many chunks
+ * Two dimensions, Num of chunks = 2* mpi_size
+ *
+ * dim1 = space_dim1*mpi_size
+ * dim2 = space_dim2(3)
+ * chunk_dim1 = space_dim1
+ * chunk_dim2 = dim2/2
+ * block = 1 for all dimensions
+ * stride = 1 for all dimensions
+ * count0 = space_dim1
+ * count1 = space_dim2(3)
+ * start0 = mpi_rank*space_dim1
+ * start1 = 0
+ *
+ * ------------------------------------------------------------------------
+ */
+
+void
+coll_chunk3(void)
+{
+ if (MAINPROCESS)
+ printf("coll_chunk3\n");
+
+ coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, HYPER, HYPER, OUT_OF_ORDER);
+ coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, HYPER, POINT, OUT_OF_ORDER);
+ coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, ALL, OUT_OF_ORDER);
+ coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, POINT, OUT_OF_ORDER);
+ coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, HYPER, OUT_OF_ORDER);
+
+ coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, ALL, IN_ORDER);
+ coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, POINT, IN_ORDER);
+ coll_chunktest(filename, mpi_size, BYROW_CONT, API_NONE, POINT, HYPER, IN_ORDER);
+}
+
+
+//-------------------------------------------------------------------------
+// Borrowed/Modified (slightly) from t_coll_chunk.c
+/*-------------------------------------------------------------------------
+ * Function: coll_chunktest
+ *
+ * Purpose: The real testing routine for regular selection of collective
+ chunking storage
+ testing both write and read,
+ If anything fails, it may be read or write. There is no
+ separation test between read and write.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Modifications:
+ * Remove invalid temporary property checkings for API_LINK_HARD and
+ * API_LINK_TRUE cases.
+ * Programmer: Jonathan Kim
+ * Date: 2012-10-10
+ *
+ * Programmer: Unknown
+ * July 12th, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+coll_chunktest(const char* filename,
+ int chunk_factor,
+ int select_factor,
+ int api_option,
+ int file_selection,
+ int mem_selection,
+ int mode)
+{
+ hid_t file, dataset, file_dataspace, mem_dataspace;
+ hid_t acc_plist,xfer_plist,crp_plist;
+
+ hsize_t dims[RANK], chunk_dims[RANK];
+ int* data_array1 = NULL;
+ int* data_origin1 = NULL;
+
+ hsize_t start[RANK],count[RANK],stride[RANK],block[RANK];
+
+#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
+ unsigned prop_value;
+#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
+
+ herr_t status;
+ MPI_Comm comm = MPI_COMM_WORLD;
+ MPI_Info info = MPI_INFO_NULL;
+
+ size_t num_points; /* for point selection */
+ hsize_t *coords = NULL; /* for point selection */
+ hsize_t current_dims; /* for point selection */
+ int i;
+
+ /* Create the data space */
+
+ acc_plist = create_faccess_plist(comm,info,facc_type);
+ VRFY((acc_plist >= 0),"");
+
+ file = H5Fcreate(filename,H5F_ACC_TRUNC,H5P_DEFAULT,acc_plist);
+ VRFY((file >= 0),"H5Fcreate succeeded");
+
+ status = H5Pclose(acc_plist);
+ VRFY((status >= 0),"");
+
+ /* setup dimensionality object */
+ dims[0] = space_dim1*mpi_size;
+ dims[1] = space_dim2;
+
+ /* allocate memory for data buffer */
+ data_array1 = (int *)HDmalloc(dims[0] * dims[1] * sizeof(int));
+ VRFY((data_array1 != NULL), "data_array1 malloc succeeded");
+
+ /* set up dimensions of the slab this process accesses */
+ ccslab_set(mpi_rank, mpi_size, start, count, stride, block, select_factor);
+
+ /* set up the coords array selection */
+ num_points = block[0] * block[1] * count[0] * count[1];
+ coords = (hsize_t *)HDmalloc(num_points * RANK * sizeof(hsize_t));
+ VRFY((coords != NULL), "coords malloc succeeded");
+ point_set(start, count, stride, block, num_points, coords, mode);
+
+ file_dataspace = H5Screate_simple(2, dims, NULL);
+ VRFY((file_dataspace >= 0), "file dataspace created succeeded");
+
+ if(ALL != mem_selection) {
+ mem_dataspace = H5Screate_simple(2, dims, NULL);
+ VRFY((mem_dataspace >= 0), "mem dataspace created succeeded");
+ }
+ else {
+ current_dims = num_points;
+ mem_dataspace = H5Screate_simple (1, &current_dims, NULL);
+ VRFY((mem_dataspace >= 0), "mem_dataspace create succeeded");
+ }
+
+ crp_plist = H5Pcreate(H5P_DATASET_CREATE);
+ VRFY((crp_plist >= 0),"");
+
+ /* Set up chunk information. */
+ chunk_dims[0] = dims[0]/chunk_factor;
+
+ /* to decrease the testing time, maintain bigger chunk size */
+ (chunk_factor == 1) ? (chunk_dims[1] = space_dim2) : (chunk_dims[1] = space_dim2/2);
+ status = H5Pset_chunk(crp_plist, 2, chunk_dims);
+ VRFY((status >= 0),"chunk creation property list succeeded");
+
+ dataset = H5Dcreate2(file, DSET_COLLECTIVE_CHUNK_NAME, H5T_NATIVE_INT,
+ file_dataspace, H5P_DEFAULT, crp_plist, H5P_DEFAULT);
+ VRFY((dataset >= 0),"dataset created succeeded");
+
+ status = H5Pclose(crp_plist);
+ VRFY((status >= 0), "");
+
+ /*put some trivial data in the data array */
+ ccdataset_fill(start, stride, count,block, data_array1, mem_selection);
+
+ MESG("data_array initialized");
+
+ switch (file_selection) {
+ case HYPER:
+ status = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((status >= 0),"hyperslab selection succeeded");
+ break;
+
+ case POINT:
+ if (num_points) {
+ status = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
+ VRFY((status >= 0),"Element selection succeeded");
+ }
+ else {
+ status = H5Sselect_none(file_dataspace);
+ VRFY((status >= 0),"none selection succeeded");
+ }
+ break;
+
+ case ALL:
+ status = H5Sselect_all(file_dataspace);
+ VRFY((status >= 0), "H5Sselect_all succeeded");
+ break;
+ }
+
+ switch (mem_selection) {
+ case HYPER:
+ status = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((status >= 0),"hyperslab selection succeeded");
+ break;
+
+ case POINT:
+ if (num_points) {
+ status = H5Sselect_elements(mem_dataspace, H5S_SELECT_SET, num_points, coords);
+ VRFY((status >= 0),"Element selection succeeded");
+ }
+ else {
+ status = H5Sselect_none(mem_dataspace);
+ VRFY((status >= 0),"none selection succeeded");
+ }
+ break;
+
+ case ALL:
+ status = H5Sselect_all(mem_dataspace);
+ VRFY((status >= 0), "H5Sselect_all succeeded");
+ break;
+ }
+
+ /* set up the collective transfer property list */
+ xfer_plist = H5Pcreate(H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0), "");
+
+ status = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((status>= 0),"MPIO collective transfer property succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ status = H5Pset_dxpl_mpio_collective_opt(xfer_plist, H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((status>= 0),"set independent IO collectively succeeded");
+ }
+
+ switch(api_option){
+ case API_LINK_HARD:
+ status = H5Pset_dxpl_mpio_chunk_opt(xfer_plist,H5FD_MPIO_CHUNK_ONE_IO);
+ VRFY((status>= 0),"collective chunk optimization succeeded");
+ break;
+
+ case API_MULTI_HARD:
+ status = H5Pset_dxpl_mpio_chunk_opt(xfer_plist,H5FD_MPIO_CHUNK_MULTI_IO);
+ VRFY((status>= 0),"collective chunk optimization succeeded ");
+ break;
+
+ case API_LINK_TRUE:
+ status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist,2);
+ VRFY((status>= 0),"collective chunk optimization set chunk number succeeded");
+ break;
+
+ case API_LINK_FALSE:
+ status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist,6);
+ VRFY((status>= 0),"collective chunk optimization set chunk number succeeded");
+ break;
+
+ case API_MULTI_COLL:
+ status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist,8);/* make sure it is using multi-chunk IO */
+ VRFY((status>= 0),"collective chunk optimization set chunk number succeeded");
+ status = H5Pset_dxpl_mpio_chunk_opt_ratio(xfer_plist,50);
+ VRFY((status>= 0),"collective chunk optimization set chunk ratio succeeded");
+ break;
+
+ case API_MULTI_IND:
+ status = H5Pset_dxpl_mpio_chunk_opt_num(xfer_plist,8);/* make sure it is using multi-chunk IO */
+ VRFY((status>= 0),"collective chunk optimization set chunk number succeeded");
+ status = H5Pset_dxpl_mpio_chunk_opt_ratio(xfer_plist,100);
+ VRFY((status>= 0),"collective chunk optimization set chunk ratio succeeded");
+ break;
+
+ default:
+ ;
+ }
+
+#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
+ if(facc_type == FACC_MPIO) {
+ switch(api_option) {
+ case API_LINK_HARD:
+ prop_value = H5D_XFER_COLL_CHUNK_DEF;
+ status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, H5D_XFER_COLL_CHUNK_SIZE, &prop_value,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ VRFY((status >= 0),"testing property list inserted succeeded");
+ break;
+
+ case API_MULTI_HARD:
+ prop_value = H5D_XFER_COLL_CHUNK_DEF;
+ status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_HARD_NAME, H5D_XFER_COLL_CHUNK_SIZE, &prop_value,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ VRFY((status >= 0),"testing property list inserted succeeded");
+ break;
+
+ case API_LINK_TRUE:
+ prop_value = H5D_XFER_COLL_CHUNK_DEF;
+ status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_TRUE_NAME, H5D_XFER_COLL_CHUNK_SIZE, &prop_value,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ VRFY((status >= 0),"testing property list inserted succeeded");
+ break;
+
+ case API_LINK_FALSE:
+ prop_value = H5D_XFER_COLL_CHUNK_DEF;
+ status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME, H5D_XFER_COLL_CHUNK_SIZE, &prop_value,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ VRFY((status >= 0),"testing property list inserted succeeded");
+ break;
+
+ case API_MULTI_COLL:
+ prop_value = H5D_XFER_COLL_CHUNK_DEF;
+ status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME, H5D_XFER_COLL_CHUNK_SIZE, &prop_value,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ VRFY((status >= 0),"testing property list inserted succeeded");
+ break;
+
+ case API_MULTI_IND:
+ prop_value = H5D_XFER_COLL_CHUNK_DEF;
+ status = H5Pinsert2(xfer_plist, H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME, H5D_XFER_COLL_CHUNK_SIZE, &prop_value,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ VRFY((status >= 0),"testing property list inserted succeeded");
+ break;
+
+ default:
+ ;
+ }
+ }
+#endif
+
+ /* write data collectively */
+ status = H5Dwrite(dataset, H5T_NATIVE_INT, mem_dataspace, file_dataspace,
+ xfer_plist, data_array1);
+ VRFY((status >= 0),"dataset write succeeded");
+
+#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
+ if(facc_type == FACC_MPIO) {
+ switch(api_option){
+ case API_LINK_HARD:
+ status = H5Pget(xfer_plist,H5D_XFER_COLL_CHUNK_LINK_HARD_NAME,&prop_value);
+ VRFY((status >= 0),"testing property list get succeeded");
+ VRFY((prop_value == 0),"API to set LINK COLLECTIVE IO directly succeeded");
+ break;
+
+ case API_MULTI_HARD:
+ status = H5Pget(xfer_plist,H5D_XFER_COLL_CHUNK_MULTI_HARD_NAME,&prop_value);
+ VRFY((status >= 0),"testing property list get succeeded");
+ VRFY((prop_value == 0),"API to set MULTI-CHUNK COLLECTIVE IO optimization succeeded");
+ break;
+
+ case API_LINK_TRUE:
+ status = H5Pget(xfer_plist,H5D_XFER_COLL_CHUNK_LINK_NUM_TRUE_NAME,&prop_value);
+ VRFY((status >= 0),"testing property list get succeeded");
+ VRFY((prop_value == 0),"API to set LINK COLLECTIVE IO succeeded");
+ break;
+
+ case API_LINK_FALSE:
+ status = H5Pget(xfer_plist,H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME,&prop_value);
+ VRFY((status >= 0),"testing property list get succeeded");
+ VRFY((prop_value == 0),"API to set LINK IO transferring to multi-chunk IO succeeded");
+ break;
+
+ case API_MULTI_COLL:
+ status = H5Pget(xfer_plist,H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME,&prop_value);
+ VRFY((status >= 0),"testing property list get succeeded");
+ VRFY((prop_value == 0),"API to set MULTI-CHUNK COLLECTIVE IO with optimization succeeded");
+ break;
+
+ case API_MULTI_IND:
+ status = H5Pget(xfer_plist,H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME,&prop_value);
+ VRFY((status >= 0),"testing property list get succeeded");
+ VRFY((prop_value == 0),"API to set MULTI-CHUNK IO transferring to independent IO succeeded");
+ break;
+
+ default:
+ ;
+ }
+ }
+#endif
+
+ status = H5Dclose(dataset);
+ VRFY((status >= 0),"");
+
+ status = H5Pclose(xfer_plist);
+ VRFY((status >= 0),"property list closed");
+
+ status = H5Sclose(file_dataspace);
+ VRFY((status >= 0),"");
+
+ status = H5Sclose(mem_dataspace);
+ VRFY((status >= 0),"");
+
+
+ status = H5Fclose(file);
+ VRFY((status >= 0),"");
+
+ if (data_array1) HDfree(data_array1);
+
+ /* Use collective read to verify the correctness of collective write. */
+
+ /* allocate memory for data buffer */
+ data_array1 = (int *)HDmalloc(dims[0]*dims[1]*sizeof(int));
+ VRFY((data_array1 != NULL), "data_array1 malloc succeeded");
+
+ /* allocate memory for data buffer */
+ data_origin1 = (int *)HDmalloc(dims[0]*dims[1]*sizeof(int));
+ VRFY((data_origin1 != NULL), "data_origin1 malloc succeeded");
+
+ acc_plist = create_faccess_plist(comm, info, facc_type);
+ VRFY((acc_plist >= 0),"MPIO creation property list succeeded");
+
+ file = H5Fopen(filename,H5F_ACC_RDONLY,acc_plist);
+ VRFY((file >= 0),"H5Fcreate succeeded");
+
+ status = H5Pclose(acc_plist);
+ VRFY((status >= 0),"");
+
+ /* open the collective dataset*/
+ dataset = H5Dopen2(file, DSET_COLLECTIVE_CHUNK_NAME, H5P_DEFAULT);
+ VRFY((dataset >= 0), "");
+
+ /* set up dimensions of the slab this process accesses */
+ ccslab_set(mpi_rank, mpi_size, start, count, stride, block, select_factor);
+
+ /* obtain the file and mem dataspace*/
+ file_dataspace = H5Dget_space (dataset);
+ VRFY((file_dataspace >= 0), "");
+
+ if (ALL != mem_selection) {
+ mem_dataspace = H5Dget_space (dataset);
+ VRFY((mem_dataspace >= 0), "");
+ }
+ else {
+ current_dims = num_points;
+ mem_dataspace = H5Screate_simple (1, &current_dims, NULL);
+ VRFY((mem_dataspace >= 0), "mem_dataspace create succeeded");
+ }
+
+ switch (file_selection) {
+ case HYPER:
+ status = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((status >= 0),"hyperslab selection succeeded");
+ break;
+
+ case POINT:
+ if (num_points) {
+ status = H5Sselect_elements(file_dataspace, H5S_SELECT_SET, num_points, coords);
+ VRFY((status >= 0),"Element selection succeeded");
+ }
+ else {
+ status = H5Sselect_none(file_dataspace);
+ VRFY((status >= 0),"none selection succeeded");
+ }
+ break;
+
+ case ALL:
+ status = H5Sselect_all(file_dataspace);
+ VRFY((status >= 0), "H5Sselect_all succeeded");
+ break;
+ }
+
+ switch (mem_selection) {
+ case HYPER:
+ status = H5Sselect_hyperslab(mem_dataspace, H5S_SELECT_SET, start, stride, count, block);
+ VRFY((status >= 0),"hyperslab selection succeeded");
+ break;
+
+ case POINT:
+ if (num_points) {
+ status = H5Sselect_elements(mem_dataspace, H5S_SELECT_SET, num_points, coords);
+ VRFY((status >= 0),"Element selection succeeded");
+ }
+ else {
+ status = H5Sselect_none(mem_dataspace);
+ VRFY((status >= 0),"none selection succeeded");
+ }
+ break;
+
+ case ALL:
+ status = H5Sselect_all(mem_dataspace);
+ VRFY((status >= 0), "H5Sselect_all succeeded");
+ break;
+ }
+
+ /* fill dataset with test data */
+ ccdataset_fill(start, stride,count,block, data_origin1, mem_selection);
+ xfer_plist = H5Pcreate (H5P_DATASET_XFER);
+ VRFY((xfer_plist >= 0),"");
+
+ status = H5Pset_dxpl_mpio(xfer_plist, H5FD_MPIO_COLLECTIVE);
+ VRFY((status>= 0),"MPIO collective transfer property succeeded");
+ if(dxfer_coll_type == DXFER_INDEPENDENT_IO) {
+ status = H5Pset_dxpl_mpio_collective_opt(xfer_plist,H5FD_MPIO_INDIVIDUAL_IO);
+ VRFY((status>= 0),"set independent IO collectively succeeded");
+ }
+
+ status = H5Dread(dataset, H5T_NATIVE_INT, mem_dataspace, file_dataspace,
+ xfer_plist, data_array1);
+ VRFY((status >=0),"dataset read succeeded");
+
+ /* verify the read data with original expected data */
+ status = ccdataset_vrfy(start, count, stride, block, data_array1, data_origin1, mem_selection);
+ if (status) nerrors++;
+
+ status = H5Pclose(xfer_plist);
+ VRFY((status >= 0),"property list closed");
+
+ /* close dataset collectively */
+ status=H5Dclose(dataset);
+ VRFY((status >= 0), "H5Dclose");
+
+ /* release all IDs created */
+ status = H5Sclose(file_dataspace);
+ VRFY((status >= 0),"H5Sclose");
+
+ status = H5Sclose(mem_dataspace);
+ VRFY((status >= 0),"H5Sclose");
+
+ /* close the file collectively */
+ status = H5Fclose(file);
+ VRFY((status >= 0),"H5Fclose");
+
+ /* release data buffers */
+ if(coords) HDfree(coords);
+ if(data_array1) HDfree(data_array1);
+ if(data_origin1) HDfree(data_origin1);
+
+}
+
+
+
+/*****************************************************************************
+ *
+ * Function: do_express_test()
+ *
+ * Purpose: Do an MPI_Allreduce to obtain the maximum value returned
+ * by GetTestExpress() across all processes. Return this
+ * value.
+ *
+ * Envirmoment variables can be different across different
+ * processes. This function ensures that all processes agree
+ * on whether to do an express test.
+ *
+ * Return: Success: Maximum of the values returned by
+ * GetTestExpress() across all processes.
+ *
+ * Failure: -1
+ *
+ * Programmer: JRM -- 4/25/06
+ *
+ *****************************************************************************/
+static int
+do_express_test(int world_mpi_rank)
+{
+ int express_test;
+ int max_express_test;
+ int result;
+
+ express_test = GetTestExpress();
+
+ result = MPI_Allreduce((void *)&express_test,
+ (void *)&max_express_test,
+ 1,
+ MPI_INT,
+ MPI_MAX,
+ MPI_COMM_WORLD);
+
+ if ( result != MPI_SUCCESS ) {
+ nerrors++;
+ max_express_test = -1;
+ if ( VERBOSE_MED && (world_mpi_rank == 0)) {
+ HDfprintf(stdout, "%d:%s: MPI_Allreduce() failed.\n",
+ world_mpi_rank, FUNC );
+ }
+ }
+
+ return(max_express_test);
+
+} /* do_express_test() */
+
+
+int main(int argc, char **argv)
+{
+ int ExpressMode = 0;
+ hsize_t newsize = 1048576;
+ hsize_t oldsize = H5S_mpio_set_bigio_count(newsize);
+
+ if (newsize != oldsize) {
+ bigcount = newsize * 2;
+ }
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD,&mpi_size);
+ MPI_Comm_rank(MPI_COMM_WORLD,&mpi_rank);
+
+ ExpressMode = do_express_test(mpi_rank);
+
+ dataset_big_write();
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ dataset_big_read();
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ if (ExpressMode > 0) {
+ printf("***Express test mode on. Several tests are skipped\n");
+ }
+ else {
+ coll_chunk1();
+ MPI_Barrier(MPI_COMM_WORLD);
+ coll_chunk2();
+ MPI_Barrier(MPI_COMM_WORLD);
+ coll_chunk3();
+ }
+
+ /* close HDF5 library */
+ H5close();
+
+ MPI_Finalize();
+
+ return 0;
+}
+
diff --git a/tools/lib/h5diff.c b/tools/lib/h5diff.c
index afb36d9..9da5b6b 100644
--- a/tools/lib/h5diff.c
+++ b/tools/lib/h5diff.c
@@ -11,8 +11,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdlib.h>
-
#include "H5private.h"
#include "h5tools.h"
#include "h5tools_utils.h"
diff --git a/tools/lib/h5diff_array.c b/tools/lib/h5diff_array.c
index 0b1a96e..7236ad1 100644
--- a/tools/lib/h5diff_array.c
+++ b/tools/lib/h5diff_array.c
@@ -673,21 +673,33 @@ static hsize_t diff_datum(void *_mem1,
h5difftrace("diff_datum H5T_STRING variable\n");
/* Get pointer to first string */
s1 = *(char**) mem1;
- size1 = HDstrlen(s1);
+ if(s1)
+ size1 = HDstrlen(s1);
+ else
+ size1 = 0;
/* Get pointer to second string */
s2 = *(char**) mem2;
- size2 = HDstrlen(s2);
+ if(s2)
+ size2 = HDstrlen(s2);
+ else
+ size2 = 0;
}
else if (H5T_STR_NULLTERM == pad) {
h5difftrace("diff_datum H5T_STRING null term\n");
/* Get pointer to first string */
s1 = (char*) mem1;
- size1 = HDstrlen(s1);
+ if(s1)
+ size1 = HDstrlen(s1);
+ else
+ size1 = 0;
if (size1 > size_mtype)
size1 = size_mtype;
/* Get pointer to second string */
s2 = (char*) mem2;
- size2 = HDstrlen(s2);
+ if(s2)
+ size2 = HDstrlen(s2);
+ else
+ size2 = 0;
if (size2 > size_mtype)
size2 = size_mtype;
}
diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c
index 3729cac..5031e44 100644
--- a/tools/lib/h5tools.c
+++ b/tools/lib/h5tools.c
@@ -12,16 +12,10 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * Programmer: Robb Matzke <matzke@llnl.gov>
- * Thursday, July 23, 1998
- *
* Purpose: A library for displaying the values of a dataset in a human
* readable format.
*/
-#include <stdio.h>
-#include <stdlib.h>
-
#include "h5tools.h"
#include "h5tools_dump.h"
#include "h5tools_ref.h"
diff --git a/tools/lib/h5tools_dump.c b/tools/lib/h5tools_dump.c
index 1a57512..fb79b77 100644
--- a/tools/lib/h5tools_dump.c
+++ b/tools/lib/h5tools_dump.c
@@ -12,16 +12,10 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * Programmer: Robb Matzke <matzke@llnl.gov>
- * Thursday, July 23, 1998
- *
* Purpose: A library for displaying the values of a dataset in a human
* readable format.
*/
-#include <stdio.h>
-#include <stdlib.h>
-
#include "h5tools.h"
#include "h5tools_dump.h"
#include "h5tools_ref.h"
diff --git a/tools/lib/h5tools_ref.c b/tools/lib/h5tools_ref.c
index 85850e3..e000080 100644
--- a/tools/lib/h5tools_ref.c
+++ b/tools/lib/h5tools_ref.c
@@ -11,8 +11,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdio.h>
-#include <stdlib.h>
#include "h5tools_ref.h"
#include "H5private.h"
#include "H5SLprivate.h"
diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c
index fa15785..a66cfe5 100644
--- a/tools/lib/h5tools_str.c
+++ b/tools/lib/h5tools_str.c
@@ -12,16 +12,8 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * Programmer: Bill Wendling <wendling@ncsa.uiuc.edu>
- * Monday, 19. February 2001
- *
* Purpose: These are string functions for us to use and abuse.
*/
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
#include "H5private.h"
#include "h5tools.h" /* for h5tool_format_t structure */
#include "h5tools_ref.h"
diff --git a/tools/lib/h5tools_utils.c b/tools/lib/h5tools_utils.c
index c361e25..08213df 100644
--- a/tools/lib/h5tools_utils.c
+++ b/tools/lib/h5tools_utils.c
@@ -12,20 +12,10 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * Programmer: Bill Wendling <wendling@ncsa.uiuc.edu>
- * Tuesday, 6. March 2001
- */
-
-/*
* Portions of this work are derived from _Obfuscated C and Other Mysteries_,
* by Don Libes, copyright (c) 1993 by John Wiley & Sons, Inc.
*/
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
#include "h5tools.h"
#include "h5tools_utils.h"
#include "H5private.h"
diff --git a/tools/lib/io_timer.c b/tools/lib/io_timer.c
index e3318e9..a6885df 100644
--- a/tools/lib/io_timer.c
+++ b/tools/lib/io_timer.c
@@ -22,16 +22,9 @@
* This is a module of useful timing functions for performance testing.
*/
-#include <stdio.h>
-#include <stdlib.h>
-
#include "H5private.h"
#include "hdf5.h"
-#ifdef H5_HAVE_PARALLEL
-#include <mpi.h>
-#endif
-
#include "io_timer.h"
/*
diff --git a/tools/lib/ph5diff.h b/tools/lib/ph5diff.h
index 9628d45..996a611 100644
--- a/tools/lib/ph5diff.h
+++ b/tools/lib/ph5diff.h
@@ -42,9 +42,5 @@ struct diffs_found
int not_cmp;
};
-#ifdef H5_HAVE_PARALLEL
-#include <mpi.h>
-#endif
-
#endif /* _PH5DIFF_H__ */
diff --git a/tools/src/h5copy/h5copy.c b/tools/src/h5copy/h5copy.c
index 390b93e..3f91fce 100644
--- a/tools/src/h5copy/h5copy.c
+++ b/tools/src/h5copy/h5copy.c
@@ -14,8 +14,6 @@
#include "H5private.h"
#include "h5tools.h"
#include "h5tools_utils.h"
-#include <string.h>
-#include <stdlib.h>
/* Name of tool */
#define PROGRAMNAME "h5copy"
diff --git a/tools/src/h5diff/h5diff_common.c b/tools/src/h5diff/h5diff_common.c
index 0537b9f..1069a31 100644
--- a/tools/src/h5diff/h5diff_common.c
+++ b/tools/src/h5diff/h5diff_common.c
@@ -11,8 +11,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdlib.h>
-#include <string.h>
#include "H5private.h"
#include "h5diff.h"
#include "h5diff_common.h"
diff --git a/tools/src/h5diff/h5diff_main.c b/tools/src/h5diff/h5diff_main.c
index 92a1610..66ff71e 100644
--- a/tools/src/h5diff/h5diff_main.c
+++ b/tools/src/h5diff/h5diff_main.c
@@ -11,9 +11,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdlib.h>
-#include <assert.h>
-#include <memory.h>
#include "H5private.h"
#include "h5diff.h"
#include "h5diff_common.h"
diff --git a/tools/src/h5diff/ph5diff_main.c b/tools/src/h5diff/ph5diff_main.c
index bfeb408..192067f 100644
--- a/tools/src/h5diff/ph5diff_main.c
+++ b/tools/src/h5diff/ph5diff_main.c
@@ -11,9 +11,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
#include "H5private.h"
#include "h5diff.h"
#include "ph5diff.h"
diff --git a/tools/src/h5dump/h5dump.c b/tools/src/h5dump/h5dump.c
index b53c212..bf2e127 100644
--- a/tools/src/h5dump/h5dump.c
+++ b/tools/src/h5dump/h5dump.c
@@ -10,8 +10,6 @@
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdio.h>
-#include <stdlib.h>
#include "h5dump.h"
#include "h5dump_ddl.h"
diff --git a/tools/src/h5dump/h5dump_ddl.c b/tools/src/h5dump/h5dump_ddl.c
index 8ce6cd6..0a45840 100644
--- a/tools/src/h5dump/h5dump_ddl.c
+++ b/tools/src/h5dump/h5dump_ddl.c
@@ -10,8 +10,6 @@
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdio.h>
-#include <stdlib.h>
#include "H5private.h"
#include "h5tools.h"
diff --git a/tools/src/h5dump/h5dump_xml.c b/tools/src/h5dump/h5dump_xml.c
index 1c3978d..49d4f96 100644
--- a/tools/src/h5dump/h5dump_xml.c
+++ b/tools/src/h5dump/h5dump_xml.c
@@ -10,8 +10,6 @@
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdio.h>
-#include <stdlib.h>
#include "H5private.h"
#include "h5tools.h"
@@ -782,20 +780,20 @@ xml_escape_the_string(const char *str, int slen)
esc_len = 1;
}
else if (*cp == '\'') {
- HDstrncpy(ncp, apos, ncp_len);
esc_len = HDstrlen(apos);
+ HDstrncpy(ncp, apos, esc_len);
}
else if (*cp == '<') {
- HDstrncpy(ncp, lt, ncp_len);
esc_len = HDstrlen(lt);
+ HDstrncpy(ncp, lt, esc_len);
}
else if (*cp == '>') {
- HDstrncpy(ncp, gt, ncp_len);
esc_len = HDstrlen(gt);
+ HDstrncpy(ncp, gt, esc_len);
}
else if (*cp == '&') {
- HDstrncpy(ncp, amp, ncp_len);
esc_len = HDstrlen(amp);
+ HDstrncpy(ncp, amp, esc_len);
}
else {
*ncp = *cp;
diff --git a/tools/src/h5repack/h5repack.c b/tools/src/h5repack/h5repack.c
index bc8527b..4860d9e 100644
--- a/tools/src/h5repack/h5repack.c
+++ b/tools/src/h5repack/h5repack.c
@@ -11,10 +11,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
#include "H5private.h"
#include "h5repack.h"
#include "h5tools.h"
diff --git a/tools/src/h5stat/h5stat.c b/tools/src/h5stat/h5stat.c
index 6aee7a8..6f196b4 100644
--- a/tools/src/h5stat/h5stat.c
+++ b/tools/src/h5stat/h5stat.c
@@ -11,8 +11,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdlib.h>
-#include <string.h>
#include "H5private.h" /* Generic Functions */
#include "h5tools.h"
#include "h5tools_utils.h"
diff --git a/tools/src/misc/h5mkgrp.c b/tools/src/misc/h5mkgrp.c
index 597b6b3..43d6bfe 100644
--- a/tools/src/misc/h5mkgrp.c
+++ b/tools/src/misc/h5mkgrp.c
@@ -15,8 +15,6 @@
#include "H5private.h"
#include "h5tools.h"
#include "h5tools_utils.h"
-#include <string.h>
-#include <stdlib.h>
/* Name of tool */
#define PROGRAMNAME "h5mkgrp"
diff --git a/tools/src/misc/h5repart.c b/tools/src/misc/h5repart.c
index 4432621..cdc554f 100644
--- a/tools/src/misc/h5repart.c
+++ b/tools/src/misc/h5repart.c
@@ -25,39 +25,9 @@
/* See H5private.h for how to include system headers */
#include "hdf5.h"
#include "H5private.h"
-#ifdef H5_STDC_HEADERS
-# include <ctype.h>
-# 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
-
-#ifndef FALSE
-# define FALSE 0
-#endif
-#ifndef TRUE
-# define TRUE 1
-#endif
-# define NAMELEN 4096
-#define GB *1024*1024*1024
-#ifndef MIN
-# define MIN(X,Y) ((X)<(Y)?(X):(Y))
-#endif
-#ifndef MIN3
-# define MIN3(X,Y,Z) MIN(MIN(X,Y),Z)
-#endif
+#define NAMELEN 4096
+#define GB *1024*1024*1024
/*Make these 2 private properties(defined in H5Fprivate.h) available to h5repart.
*The first one updates the member file size in the superblock. The second one
diff --git a/tools/test/h5copy/h5copygentest.c b/tools/test/h5copy/h5copygentest.c
index d4d6a08..35f9132 100644
--- a/tools/test/h5copy/h5copygentest.c
+++ b/tools/test/h5copy/h5copygentest.c
@@ -14,7 +14,6 @@
/*
* Generate the binary hdf5 file for the h5copy tests
*/
-#include <stdlib.h>
#include "hdf5.h"
#include "H5private.h"
diff --git a/tools/test/h5diff/CMakeTests.cmake b/tools/test/h5diff/CMakeTests.cmake
index 72dda6b..608795c 100644
--- a/tools/test/h5diff/CMakeTests.cmake
+++ b/tools/test/h5diff/CMakeTests.cmake
@@ -95,6 +95,8 @@
${HDF5_TOOLS_DIR}/testfiles/vds/5_b.h5
${HDF5_TOOLS_DIR}/testfiles/vds/5_c.h5
${HDF5_TOOLS_DIR}/testfiles/vds/5_vds.h5
+ # tools/testfiles
+ ${HDF5_TOOLS_DIR}/testfiles/tvlstr.h5
)
set (LIST_OTHER_TEST_FILES
@@ -286,6 +288,7 @@
${HDF5_TOOLS_TEST_H5DIFF_SOURCE_DIR}/testfiles/h5diff_v1.txt
${HDF5_TOOLS_TEST_H5DIFF_SOURCE_DIR}/testfiles/h5diff_v2.txt
${HDF5_TOOLS_TEST_H5DIFF_SOURCE_DIR}/testfiles/h5diff_v3.txt
+ ${HDF5_TOOLS_TEST_H5DIFF_SOURCE_DIR}/testfiles/h5diff_vlstr.txt
)
set (LIST_WIN_TEST_FILES
@@ -311,6 +314,11 @@
HDFTEST_COPY_FILE("${h5_tstfiles}" "${PROJECT_BINARY_DIR}/PAR/testfiles/${fname}" "h5diff_files")
endif ()
endforeach ()
+ # copy second version of tvlstr.h5
+ HDFTEST_COPY_FILE("${HDF5_TOOLS_DIR}/testfiles/tvlstr.h5" "${PROJECT_BINARY_DIR}/testfiles/tvlstr2.h5" "h5diff_files")
+ if (H5_HAVE_PARALLEL)
+ HDFTEST_COPY_FILE("${HDF5_TOOLS_DIR}/testfiles/tvlstr.h5" "${PROJECT_BINARY_DIR}/PAR/testfiles/tvlstr2.h5" "h5diff_files")
+ endif ()
#
@@ -888,6 +896,8 @@
h5diff_v2.out.err
h5diff_v3.out
h5diff_v3.out.err
+ h5diff_vlstr.out
+ h5diff_vlstr.out.err
)
set_tests_properties (H5DIFF-clearall-objects PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles")
if (NOT "${last_test}" STREQUAL "")
@@ -1465,6 +1475,7 @@ ADD_H5_TEST (h5diff_487 1 -v --exclude-path "/group1/dset" h5diff_exclude3-1.h5
# # diff various multiple vlen and fixed strings in a compound type dataset
# ##############################################################################
ADD_H5_TEST (h5diff_530 0 -v ${COMP_VL_STRS_FILE} ${COMP_VL_STRS_FILE} /group /group_copy)
+ADD_H5_TEST (h5diff_vlstr 0 -v tvlstr.h5 tvlstr2.h5)
# ##############################################################################
# # Test container types (array,vlen) with multiple nested compound types
diff --git a/tools/test/h5diff/testfiles/h5diff_vlstr.txt b/tools/test/h5diff/testfiles/h5diff_vlstr.txt
new file mode 100644
index 0000000..67141f1
--- /dev/null
+++ b/tools/test/h5diff/testfiles/h5diff_vlstr.txt
@@ -0,0 +1,16 @@
+
+file1 file2
+---------------------------------------
+ x x /
+ x x /Dataset1
+ x x /vl_string_type
+
+group : </> and </>
+0 differences found
+attribute: <test_scalar of </>> and <test_scalar of </>>
+0 differences found
+dataset: </Dataset1> and </Dataset1>
+0 differences found
+datatype: </vl_string_type> and </vl_string_type>
+0 differences found
+EXIT CODE: 0
diff --git a/tools/test/h5diff/testh5diff.sh.in b/tools/test/h5diff/testh5diff.sh.in
index d769c23..df472d4 100644
--- a/tools/test/h5diff/testh5diff.sh.in
+++ b/tools/test/h5diff/testh5diff.sh.in
@@ -124,6 +124,7 @@ $SRC_H5DIFF_TESTFILES/tmpSingleSiteBethe.reference.h5
$SRC_H5DIFF_TESTFILES/tmpSingleSiteBethe.output.h5
$SRC_H5DIFF_TESTFILES/diff_strings1.h5
$SRC_H5DIFF_TESTFILES/diff_strings2.h5
+$SRC_TOOLS_TESTFILES/tvlstr.h5
"
LIST_HDF5_VDS_TEST_FILES="
@@ -341,6 +342,7 @@ $SRC_H5DIFF_TESTFILES/h5diff_tmp2.txt
$SRC_H5DIFF_TESTFILES/h5diff_v1.txt
$SRC_H5DIFF_TESTFILES/h5diff_v2.txt
$SRC_H5DIFF_TESTFILES/h5diff_v3.txt
+$SRC_H5DIFF_TESTFILES/h5diff_vlstr.txt
"
#
@@ -566,6 +568,8 @@ SKIP() {
##############################################################################
# prepare for test
COPY_TESTFILES_TO_TESTDIR
+# second copy of tvlstr.h5
+$CP -f $SRC_TOOLS_TESTFILES/tvlstr.h5 $TESTDIR/tvlstr2.h5
# ############################################################################
# # Common usage
@@ -1141,6 +1145,7 @@ TOOLTEST h5diff_487.txt -v --exclude-path "/group1/dset" h5diff_exclude3-1.h5 h5
# # diff various multiple vlen and fixed strings in a compound type dataset
# ##############################################################################
TOOLTEST h5diff_530.txt -v h5diff_comp_vl_strs.h5 h5diff_comp_vl_strs.h5 /group /group_copy
+TOOLTEST h5diff_vlstr.txt -v tvlstr.h5 tvlstr2.h5
# ##############################################################################
# # Test container types (array,vlen) with multiple nested compound types
diff --git a/tools/test/h5dump/CMakeTestsXML.cmake b/tools/test/h5dump/CMakeTestsXML.cmake
index 92e08a0..bdc6755 100644
--- a/tools/test/h5dump/CMakeTestsXML.cmake
+++ b/tools/test/h5dump/CMakeTestsXML.cmake
@@ -50,6 +50,7 @@
${HDF5_TOOLS_DIR}/testfiles/tname-quot.h5
${HDF5_TOOLS_DIR}/testfiles/tname-sp.h5
${HDF5_TOOLS_DIR}/testfiles/tnamed_dtype_attr.h5
+ ${HDF5_TOOLS_DIR}/testfiles/test35.nc
${HDF5_TOOLS_DIR}/testfiles/tnestedcomp.h5
${HDF5_TOOLS_DIR}/testfiles/tnodata.h5
${HDF5_TOOLS_DIR}/testfiles/tobjref.h5
@@ -99,6 +100,7 @@
${HDF5_TOOLS_DIR}/testfiles/tempty-ns.h5.xml
${HDF5_TOOLS_DIR}/testfiles/tempty-ns-2.h5.xml
${HDF5_TOOLS_DIR}/testfiles/tenum.h5.xml
+ ${HDF5_TOOLS_DIR}/testfiles/test35.nc.xml
${HDF5_TOOLS_DIR}/testfiles/textlink.h5.xml
${HDF5_TOOLS_DIR}/testfiles/tfpformat.h5.xml
${HDF5_TOOLS_DIR}/testfiles/tgroup.h5.xml
@@ -258,6 +260,8 @@
tempty.h5.out.err
tenum.h5.out
tenum.h5.out.err
+ test35.nc.out
+ test35.nc.out.err
textlink.h5.out
textlink.h5.out.err
tfpformat.h5.out
@@ -430,3 +434,6 @@
# tests for floating point user defined printf format
ADD_XML_H5_TEST (tfpformat.h5 0 -u -m %.7f tfpformat.h5)
+ # test for HDFFV-10256 issue
+ ADD_XML_H5_TEST (test35.nc 0 test35.nc)
+
diff --git a/tools/test/h5dump/h5dumpgentest.c b/tools/test/h5dump/h5dumpgentest.c
index 44c4369..2128acb 100644
--- a/tools/test/h5dump/h5dumpgentest.c
+++ b/tools/test/h5dump/h5dumpgentest.c
@@ -20,7 +20,6 @@
* trying it on a new platform, ...), you need to verify the correctness
* of the expected output and update the corresponding *.ddl files.
*/
-#include <limits.h>
#include "hdf5.h"
#include "H5private.h"
diff --git a/tools/test/h5dump/testh5dumpxml.sh.in b/tools/test/h5dump/testh5dumpxml.sh.in
index 5f62946..b3b9e14 100644
--- a/tools/test/h5dump/testh5dumpxml.sh.in
+++ b/tools/test/h5dump/testh5dumpxml.sh.in
@@ -80,6 +80,7 @@ $SRC_H5DUMP_TESTFILES/tdset.h5
$SRC_H5DUMP_TESTFILES/tdset2.h5
$SRC_H5DUMP_TESTFILES/tempty.h5
$SRC_H5DUMP_TESTFILES/tenum.h5
+$SRC_H5DUMP_TESTFILES/test35.nc
$SRC_H5DUMP_TESTFILES/textlink.h5
$SRC_H5DUMP_TESTFILES/tfpformat.h5
$SRC_H5DUMP_TESTFILES/tgroup.h5
@@ -144,6 +145,7 @@ $SRC_H5DUMP_TESTFILES/tempty-nons-uri.h5.xml
$SRC_H5DUMP_TESTFILES/tempty-ns.h5.xml
$SRC_H5DUMP_TESTFILES/tempty-ns-2.h5.xml
$SRC_H5DUMP_TESTFILES/tenum.h5.xml
+$SRC_H5DUMP_TESTFILES/test35.nc.xml
$SRC_H5DUMP_TESTFILES/textlink.h5.xml
$SRC_H5DUMP_TESTFILES/tfpformat.h5.xml
$SRC_H5DUMP_TESTFILES/tgroup.h5.xml
@@ -383,6 +385,9 @@ TOOLTEST torderattr4.h5.xml --xml -H --sort_by=creation_order --sort_order=desce
# tests for floating point user defined printf format
TOOLTEST tfpformat.h5.xml -u -m %.7f tfpformat.h5
+# test for HDFFV-10256 issue
+TOOLTEST test35.nc.xml --xml test35.nc
+
# Clean up temporary files/directories
CLEAN_TESTFILES_AND_TESTDIR
diff --git a/tools/test/h5import/h5importtest.c b/tools/test/h5import/h5importtest.c
index 00ae2e7..489bc01 100644
--- a/tools/test/h5import/h5importtest.c
+++ b/tools/test/h5import/h5importtest.c
@@ -11,7 +11,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdio.h>
#include "H5private.h"
#ifdef H5_HAVE_WIN32_API
diff --git a/tools/test/h5jam/h5jamgentest.c b/tools/test/h5jam/h5jamgentest.c
index d713bb9..9f3d000 100644
--- a/tools/test/h5jam/h5jamgentest.c
+++ b/tools/test/h5jam/h5jamgentest.c
@@ -20,8 +20,6 @@
* trying it on a new platform, ...), you need to verify the correctness
* of the expected output and update the corresponding *.ddl files.
*/
-#include <assert.h>
-#include <limits.h>
#include "hdf5.h"
#include "H5private.h"
diff --git a/tools/test/h5jam/tellub.c b/tools/test/h5jam/tellub.c
index fad14b7..8e4b3ac 100644
--- a/tools/test/h5jam/tellub.c
+++ b/tools/test/h5jam/tellub.c
@@ -11,12 +11,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdio.h>
-
-#ifdef H5_HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
#include "hdf5.h"
#include "H5private.h"
#include "h5tools.h"
diff --git a/tools/test/h5repack/CMakeTests.cmake b/tools/test/h5repack/CMakeTests.cmake
index 897209c..225f6a8 100644
--- a/tools/test/h5repack/CMakeTests.cmake
+++ b/tools/test/h5repack/CMakeTests.cmake
@@ -76,6 +76,12 @@
${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/h5repack_shuffle.h5
${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/h5repack_soffset.h5
${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/h5repack_szip.h5
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/h5repack_aggr.h5
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/h5repack_fsm_aggr_nopersist.h5
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/h5repack_fsm_aggr_persist.h5
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/h5repack_none.h5
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/h5repack_paged_nopersist.h5
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/h5repack_paged_persist.h5
# h5diff/testfile
${HDF5_TOOLS_TEST_H5DIFF_SOURCE_DIR}/testfiles/h5diff_attr1.h5
# tools/testfiles
@@ -139,6 +145,12 @@
${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/4_vds.h5-vds_conti-v.ddl
${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/h5repack_layout.h5-plugin_zero.tst
${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/crtorder.tordergr.h5.ddl
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/SP.h5repack_fsm_aggr_nopersist.h5.ddl
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/S.h5repack_fsm_aggr_persist.h5.ddl
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/STG.h5repack_none.h5.ddl
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/GS.h5repack_paged_nopersist.h5.ddl
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/SP.h5repack_paged_persist.h5.ddl
+ ${HDF5_TOOLS_TEST_H5REPACK_SOURCE_DIR}/testfiles/SPT.h5repack_aggr.h5.ddl
)
foreach (h5_file ${LIST_HDF5_TEST_FILES} ${LIST_OTHER_TEST_FILES})
@@ -238,7 +250,8 @@
if (HDF5_ENABLE_USING_MEMCHECKER)
add_test (
NAME H5REPACK_CMP-${testname}
- COMMAND $<TARGET_FILE:h5repack> ${ARGN} ${PROJECT_BINARY_DIR}/testfiles/${resultfile} ${PROJECT_BINARY_DIR}/testfiles/out-${testname}.${resultfile})
+ COMMAND $<TARGET_FILE:h5repack> ${ARGN} ${PROJECT_BINARY_DIR}/testfiles/${resultfile} ${PROJECT_BINARY_DIR}/testfiles/out-${testname}.${resultfile}
+ )
else ()
add_test (
NAME H5REPACK_CMP-${testname}
@@ -272,7 +285,8 @@
if (HDF5_ENABLE_USING_MEMCHECKER)
add_test (
NAME H5REPACK_MASK-${testname}
- COMMAND $<TARGET_FILE:h5repack> ${ARGN} ${PROJECT_BINARY_DIR}/testfiles/${resultfile} ${PROJECT_BINARY_DIR}/testfiles/out-${testname}.${resultfile})
+ COMMAND $<TARGET_FILE:h5repack> ${ARGN} ${PROJECT_BINARY_DIR}/testfiles/${resultfile} ${PROJECT_BINARY_DIR}/testfiles/out-${testname}.${resultfile}
+ )
else (HDF5_ENABLE_USING_MEMCHECKER)
add_test (
NAME H5REPACK_MASK-${testname}
@@ -305,7 +319,8 @@
# If using memchecker add tests without using scripts
add_test (
NAME H5REPACK_DMP-${testname}
- COMMAND $<TARGET_FILE:h5repack> ${ARGN} ${PROJECT_BINARY_DIR}/testfiles/${resultfile} ${PROJECT_BINARY_DIR}/testfiles/out-${testname}.${resultfile})
+ COMMAND $<TARGET_FILE:h5repack> ${ARGN} ${PROJECT_BINARY_DIR}/testfiles/${resultfile} ${PROJECT_BINARY_DIR}/testfiles/out-${testname}.${resultfile}
+ )
if (NOT "${last_test}" STREQUAL "")
set_tests_properties (H5REPACK_DMP-${testname} PROPERTIES DEPENDS ${last_test})
endif ()
@@ -326,6 +341,40 @@
endif ()
endmacro ()
+ macro (ADD_H5_STAT_TEST testname testtype resultcode statarg resultfile)
+ if ("${testtype}" STREQUAL "SKIP")
+ if (NOT HDF5_ENABLE_USING_MEMCHECKER)
+ add_test (
+ NAME H5REPACK_STAT-${testname}-SKIPPED
+ COMMAND ${CMAKE_COMMAND} -E echo "SKIP ${ARGN} ${PROJECT_BINARY_DIR}/testfiles/${resultfile} ${PROJECT_BINARY_DIR}/testfiles/out-${statarg}.${resultfile}"
+ )
+ endif ()
+ else ()
+ # If using memchecker add tests without using scripts
+ add_test (
+ NAME H5REPACK_STAT-${testname}
+ COMMAND $<TARGET_FILE:h5repack> ${ARGN} ${PROJECT_BINARY_DIR}/testfiles/${resultfile} ${PROJECT_BINARY_DIR}/testfiles/out-${statarg}.${resultfile}
+ )
+ if (NOT "${last_test}" STREQUAL "")
+ set_tests_properties (H5REPACK_STAT-${testname} PROPERTIES DEPENDS ${last_test})
+ endif ()
+ if (NOT HDF5_ENABLE_USING_MEMCHECKER)
+ add_test (
+ NAME H5REPACK_STAT-h5stat-${testname}
+ COMMAND "${CMAKE_COMMAND}"
+ -D "TEST_PROGRAM=$<TARGET_FILE:h5stat>"
+ -D "TEST_ARGS:STRING=-S;-s;out-${statarg}.${resultfile}"
+ -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles"
+ -D "TEST_OUTPUT=${resultfile}-${testname}.out"
+ -D "TEST_EXPECT=${resultcode}"
+ -D "TEST_REFERENCE=${statarg}.${resultfile}.ddl"
+ -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake"
+ )
+ set_tests_properties (H5REPACK_STAT-h5stat-${testname} PROPERTIES DEPENDS "H5REPACK_STAT-${testname}")
+ endif ()
+ endif ()
+ endmacro ()
+
macro (ADD_H5_VERIFY_TEST testname testtype resultcode testfile testdset testfilter)
if ("${testtype}" STREQUAL "SKIP")
if (NOT HDF5_ENABLE_USING_MEMCHECKER)
@@ -972,6 +1021,48 @@
set (TESTTYPE "TEST")
ADD_H5_DMP_TEST (crtorder ${TESTTYPE} 0 ${arg})
+###################################################################################################
+# Testing paged aggregation related options:
+# -G pagesize
+# -P 1 or 0
+# -S strategy
+# -T threshold
+#
+# The testfiles used are generated by test/gen_filespace.c and the file names are prepended with "h5repack_":
+# (1) "fsm_aggr_nopersist.h5" /* H5F_FSPACE_STRATEGY_FSM_AGGR + not persisting free-space */
+# (2) "fsm_aggr_persist.h5" /* H5F_FSPACE_STRATEGY_FSM_AGGR + persisting free-space */
+# (3) "paged_nopersist.h5" /* H5F_FSPACE_STRATEGY_PAGE + not persisting free-space */
+# (4) "paged_persist.h5" /* H5F_FSPACE_STRATEGY_PAGE + persisting free-space */
+# (5) "aggr.h5" /* H5F_FSPACE_STRATEGY_AGGR */
+# (6) "none.h5" /* H5F_FSPACE_STRATEGY_NONE */
+#
+#####################################################################################################
+#
+ set (arg h5repack_fsm_aggr_nopersist.h5 -S PAGE -P 1)
+ set (TESTTYPE "TEST")
+ ADD_H5_STAT_TEST (SP_PAGE ${TESTTYPE} 0 SP ${arg})
+
+ set (arg h5repack_fsm_aggr_persist.h5 -S AGGR)
+ set (TESTTYPE "TEST")
+ ADD_H5_STAT_TEST (S_AGGR ${TESTTYPE} 0 S ${arg})
+
+ set (arg h5repack_none.h5 -S PAGE -T 10 -G 2048)
+ set (TESTTYPE "TEST")
+ ADD_H5_STAT_TEST (STG_PAGE ${TESTTYPE} 0 STG ${arg})
+
+ set (arg h5repack_paged_nopersist.h5 -G 512 -S AGGR)
+ set (TESTTYPE "TEST")
+ ADD_H5_STAT_TEST (GS_AGGR ${TESTTYPE} 0 GS ${arg})
+
+ set (arg h5repack_paged_persist.h5 -S NONE -P 1)
+ set (TESTTYPE "TEST")
+ ADD_H5_STAT_TEST (SP_NONE ${TESTTYPE} 0 SP ${arg})
+
+ set (arg h5repack_aggr.h5 -S FSM_AGGR -P 1 -T 5)
+ set (TESTTYPE "TEST")
+ ADD_H5_STAT_TEST (SPT_FSM_AGGR ${TESTTYPE} 0 SPT ${arg})
+
+
#########################################################
# layout options (these files have no filters)
#########################################################
diff --git a/tools/test/h5repack/h5repack.sh.in b/tools/test/h5repack/h5repack.sh.in
index bc6b527..e474bc3 100644
--- a/tools/test/h5repack/h5repack.sh.in
+++ b/tools/test/h5repack/h5repack.sh.in
@@ -36,6 +36,9 @@ H5DIFF_BIN=`pwd`/$H5DIFF # The path of the h5diff tool binary
H5DUMP=../../src/h5dump/h5dump # The h5dump tool name
H5DUMP_BIN=`pwd`/$H5DUMP # The path of the h5dump tool binary
+H5STAT=../../src/h5stat/h5stat # The h5stat tool name
+H5STAT_BIN=`pwd`/$H5STAT # The path of the h5stat tool binary
+
RM='rm -rf'
CMP='cmp'
DIFF='diff -c'
@@ -101,6 +104,12 @@ $SRC_H5REPACK_TESTFILES/h5repack_refs.h5
$SRC_H5REPACK_TESTFILES/h5repack_shuffle.h5
$SRC_H5REPACK_TESTFILES/h5repack_soffset.h5
$SRC_H5REPACK_TESTFILES/h5repack_szip.h5
+$SRC_H5REPACK_TESTFILES/h5repack_aggr.h5
+$SRC_H5REPACK_TESTFILES/h5repack_fsm_aggr_nopersist.h5
+$SRC_H5REPACK_TESTFILES/h5repack_fsm_aggr_persist.h5
+$SRC_H5REPACK_TESTFILES/h5repack_none.h5
+$SRC_H5REPACK_TESTFILES/h5repack_paged_nopersist.h5
+$SRC_H5REPACK_TESTFILES/h5repack_paged_persist.h5
$SRC_H5DIFF_TESTFILES/h5diff_attr1.h5
$SRC_TOOLS_TESTFILES/tfamily00000.h5
$SRC_TOOLS_TESTFILES/tfamily00001.h5
@@ -156,6 +165,12 @@ $SRC_H5REPACK_TESTFILES/2_vds.h5-vds_chunk3x6x9-v.ddl
$SRC_H5REPACK_TESTFILES/3_1_vds.h5-vds_chunk2x5x8-v.ddl
$SRC_H5REPACK_TESTFILES/4_vds.h5-vds_compa-v.ddl
$SRC_H5REPACK_TESTFILES/4_vds.h5-vds_conti-v.ddl
+$SRC_H5REPACK_TESTFILES/SP.h5repack_fsm_aggr_nopersist.h5.ddl
+$SRC_H5REPACK_TESTFILES/S.h5repack_fsm_aggr_persist.h5.ddl
+$SRC_H5REPACK_TESTFILES/STG.h5repack_none.h5.ddl
+$SRC_H5REPACK_TESTFILES/GS.h5repack_paged_nopersist.h5.ddl
+$SRC_H5REPACK_TESTFILES/SP.h5repack_paged_persist.h5.ddl
+$SRC_H5REPACK_TESTFILES/SPT.h5repack_aggr.h5.ddl
"
#
@@ -707,6 +722,58 @@ TOOLTEST_DUMP()
rm -f $outfile
}
+# This is similar to TOOLTEST_DUMP().
+# Test h5repack with options added for paged aggregation.
+# h5stat is used on the repacked file and the expected output
+# is compared for correctness.
+#
+TOOLTEST_STAT()
+{
+ infile=$2
+ outfile=out-$1.$2
+ expect="$TESTDIR/$1.$2.ddl"
+ actual="$TESTDIR/out-$1.$2.out"
+ actual_err="$TESTDIR/out-$1.$2.err"
+
+ shift
+ shift
+
+ # Run test.
+ TESTING $H5REPACK $@
+ (
+ cd $TESTDIR
+ $RUNSERIAL $H5REPACK_BIN "$@" $infile $outfile
+ ) >$actual 2>$actual_err
+ RET=$?
+ if [ $RET != 0 ] ; then
+ echo "*FAILED*"
+ nerrors="`expr $nerrors + 1`"
+ else
+ echo " PASSED"
+ VERIFY h5stat output $@
+ (
+ cd $TESTDIR
+ $RUNSERIAL $H5STAT_BIN -S -s $outfile
+ ) >$actual 2>$actual_err
+ cat $actual_err >> $actual
+
+ RET=$?
+
+ fi
+
+ if cmp -s $expect $actual; then
+ echo " PASSED"
+ else
+ echo "*FAILED*"
+ echo " Expected result (*.ddl) differs from actual result (*.out)"
+ nerrors="`expr $nerrors + 1`"
+ test yes = "$verbose" && diff -c $expect $actual |sed 's/^/ /'
+ fi
+
+ rm -f $actual $actual_err
+ rm -f $outfile
+}
+
# TOOLTEST_META:
# Test metadata block size option.
# Reason to create a function here is to localize all special steps related to
@@ -1057,6 +1124,42 @@ fi
arg="tordergr.h5 -L"
TOOLTEST_DUMP crtorder $arg
+###################################################################################################
+# Testing paged aggregation related options:
+# -G pagesize
+# -P 1 or 0
+# -S strategy
+# -T threshold
+#
+# The testfiles used are generated by test/gen_filespace.c and the file names are prepended with "h5repack_":
+# (1) "fsm_aggr_nopersist.h5" /* H5F_FSPACE_STRATEGY_FSM_AGGR + not persisting free-space */
+# (2) "fsm_aggr_persist.h5" /* H5F_FSPACE_STRATEGY_FSM_AGGR + persisting free-space */
+# (3) "paged_nopersist.h5" /* H5F_FSPACE_STRATEGY_PAGE + not persisting free-space */
+# (4) "paged_persist.h5" /* H5F_FSPACE_STRATEGY_PAGE + persisting free-space */
+# (5) "aggr.h5" /* H5F_FSPACE_STRATEGY_AGGR */
+# (6) "none.h5" /* H5F_FSPACE_STRATEGY_NONE */
+#
+#####################################################################################################
+#
+arg="h5repack_fsm_aggr_nopersist.h5 -S PAGE -P 1"
+TOOLTEST_STAT SP $arg
+#
+arg="h5repack_fsm_aggr_persist.h5 -S AGGR"
+TOOLTEST_STAT S $arg
+#
+arg="h5repack_none.h5 -S PAGE -T 10 -G 2048"
+TOOLTEST_STAT STG $arg
+#
+arg="h5repack_paged_nopersist.h5 -G 512 -S AGGR"
+TOOLTEST_STAT GS $arg
+#
+arg="h5repack_paged_persist.h5 -S NONE -P 1"
+TOOLTEST_STAT SP $arg
+#
+arg="h5repack_aggr.h5 -S FSM_AGGR -P 1 -T 5"
+TOOLTEST_STAT SPT $arg
+
+
#########################################################
# layout options (these files have no filters)
#########################################################
diff --git a/tools/test/h5repack/testfiles/GS.h5repack_paged_nopersist.h5.ddl b/tools/test/h5repack/testfiles/GS.h5repack_paged_nopersist.h5.ddl
new file mode 100644
index 0000000..d8ca992
--- /dev/null
+++ b/tools/test/h5repack/testfiles/GS.h5repack_paged_nopersist.h5.ddl
@@ -0,0 +1,15 @@
+Filename: out-GS.h5repack_paged_nopersist.h5
+Free-space persist: FALSE
+Free-space section threshold: 1 bytes
+Small size free-space sections (< 10 bytes):
+ Total # of small size sections: 0
+Free-space section bins:
+ Total # of sections: 0
+File space management strategy: H5F_FSPACE_STRATEGY_AGGR
+File space page size: 512 bytes
+Summary of file space information:
+ File metadata: 1272 bytes
+ Raw data: 400 bytes
+ Amount/Percent of tracked free space: 0 bytes/0.0%
+ Unaccounted space: 776 bytes
+Total space: 2448 bytes
diff --git a/tools/test/h5repack/testfiles/S.h5repack_fsm_aggr_persist.h5.ddl b/tools/test/h5repack/testfiles/S.h5repack_fsm_aggr_persist.h5.ddl
new file mode 100644
index 0000000..87ccbc4
--- /dev/null
+++ b/tools/test/h5repack/testfiles/S.h5repack_fsm_aggr_persist.h5.ddl
@@ -0,0 +1,15 @@
+Filename: out-S.h5repack_fsm_aggr_persist.h5
+Free-space persist: FALSE
+Free-space section threshold: 1 bytes
+Small size free-space sections (< 10 bytes):
+ Total # of small size sections: 0
+Free-space section bins:
+ Total # of sections: 0
+File space management strategy: H5F_FSPACE_STRATEGY_AGGR
+File space page size: 4096 bytes
+Summary of file space information:
+ File metadata: 1272 bytes
+ Raw data: 400 bytes
+ Amount/Percent of tracked free space: 0 bytes/0.0%
+ Unaccounted space: 776 bytes
+Total space: 2448 bytes
diff --git a/tools/test/h5repack/testfiles/SP.h5repack_fsm_aggr_nopersist.h5.ddl b/tools/test/h5repack/testfiles/SP.h5repack_fsm_aggr_nopersist.h5.ddl
new file mode 100644
index 0000000..affa93b
--- /dev/null
+++ b/tools/test/h5repack/testfiles/SP.h5repack_fsm_aggr_nopersist.h5.ddl
@@ -0,0 +1,16 @@
+Filename: out-SP.h5repack_fsm_aggr_nopersist.h5
+Free-space persist: TRUE
+Free-space section threshold: 1 bytes
+Small size free-space sections (< 10 bytes):
+ Total # of small size sections: 0
+Free-space section bins:
+ # of sections of size 1000 - 9999: 2
+ Total # of sections: 2
+File space management strategy: H5F_FSPACE_STRATEGY_PAGE
+File space page size: 4096 bytes
+Summary of file space information:
+ File metadata: 1602 bytes
+ Raw data: 400 bytes
+ Amount/Percent of tracked free space: 6307 bytes/38.5%
+ Unaccounted space: 8075 bytes
+Total space: 16384 bytes
diff --git a/tools/test/h5repack/testfiles/SP.h5repack_paged_persist.h5.ddl b/tools/test/h5repack/testfiles/SP.h5repack_paged_persist.h5.ddl
new file mode 100644
index 0000000..1084090
--- /dev/null
+++ b/tools/test/h5repack/testfiles/SP.h5repack_paged_persist.h5.ddl
@@ -0,0 +1,15 @@
+Filename: out-SP.h5repack_paged_persist.h5
+Free-space persist: FALSE
+Free-space section threshold: 1 bytes
+Small size free-space sections (< 10 bytes):
+ Total # of small size sections: 0
+Free-space section bins:
+ Total # of sections: 0
+File space management strategy: H5F_FSPACE_STRATEGY_NONE
+File space page size: 4096 bytes
+Summary of file space information:
+ File metadata: 1272 bytes
+ Raw data: 400 bytes
+ Amount/Percent of tracked free space: 0 bytes/0.0%
+ Unaccounted space: 0 bytes
+Total space: 1672 bytes
diff --git a/tools/test/h5repack/testfiles/SPT.h5repack_aggr.h5.ddl b/tools/test/h5repack/testfiles/SPT.h5repack_aggr.h5.ddl
new file mode 100644
index 0000000..1ce06b2
--- /dev/null
+++ b/tools/test/h5repack/testfiles/SPT.h5repack_aggr.h5.ddl
@@ -0,0 +1,16 @@
+Filename: out-SPT.h5repack_aggr.h5
+Free-space persist: TRUE
+Free-space section threshold: 5 bytes
+Small size free-space sections (< 10 bytes):
+ Total # of small size sections: 0
+Free-space section bins:
+ # of sections of size 100 - 999: 1
+ Total # of sections: 1
+File space management strategy: H5F_FSPACE_STRATEGY_FSM_AGGR
+File space page size: 4096 bytes
+Summary of file space information:
+ File metadata: 1485 bytes
+ Raw data: 400 bytes
+ Amount/Percent of tracked free space: 680 bytes/26.5%
+ Unaccounted space: 0 bytes
+Total space: 2565 bytes
diff --git a/tools/test/h5repack/testfiles/STG.h5repack_none.h5.ddl b/tools/test/h5repack/testfiles/STG.h5repack_none.h5.ddl
new file mode 100644
index 0000000..51cd7e5
--- /dev/null
+++ b/tools/test/h5repack/testfiles/STG.h5repack_none.h5.ddl
@@ -0,0 +1,15 @@
+Filename: out-STG.h5repack_none.h5
+Free-space persist: FALSE
+Free-space section threshold: 10 bytes
+Small size free-space sections (< 10 bytes):
+ Total # of small size sections: 0
+Free-space section bins:
+ Total # of sections: 0
+File space management strategy: H5F_FSPACE_STRATEGY_PAGE
+File space page size: 2048 bytes
+Summary of file space information:
+ File metadata: 1272 bytes
+ Raw data: 400 bytes
+ Amount/Percent of tracked free space: 0 bytes/0.0%
+ Unaccounted space: 2424 bytes
+Total space: 4096 bytes
diff --git a/tools/test/h5repack/testfiles/h5repack_aggr.h5 b/tools/test/h5repack/testfiles/h5repack_aggr.h5
new file mode 100644
index 0000000..8da0751
--- /dev/null
+++ b/tools/test/h5repack/testfiles/h5repack_aggr.h5
Binary files differ
diff --git a/tools/test/h5repack/testfiles/h5repack_fsm_aggr_nopersist.h5 b/tools/test/h5repack/testfiles/h5repack_fsm_aggr_nopersist.h5
new file mode 100644
index 0000000..1cd5f3f
--- /dev/null
+++ b/tools/test/h5repack/testfiles/h5repack_fsm_aggr_nopersist.h5
Binary files differ
diff --git a/tools/test/h5repack/testfiles/h5repack_fsm_aggr_persist.h5 b/tools/test/h5repack/testfiles/h5repack_fsm_aggr_persist.h5
new file mode 100644
index 0000000..469dbce
--- /dev/null
+++ b/tools/test/h5repack/testfiles/h5repack_fsm_aggr_persist.h5
Binary files differ
diff --git a/tools/test/h5repack/testfiles/h5repack_none.h5 b/tools/test/h5repack/testfiles/h5repack_none.h5
new file mode 100644
index 0000000..2e4d789
--- /dev/null
+++ b/tools/test/h5repack/testfiles/h5repack_none.h5
Binary files differ
diff --git a/tools/test/h5repack/testfiles/h5repack_paged_nopersist.h5 b/tools/test/h5repack/testfiles/h5repack_paged_nopersist.h5
new file mode 100644
index 0000000..352e586
--- /dev/null
+++ b/tools/test/h5repack/testfiles/h5repack_paged_nopersist.h5
Binary files differ
diff --git a/tools/test/h5repack/testfiles/h5repack_paged_persist.h5 b/tools/test/h5repack/testfiles/h5repack_paged_persist.h5
new file mode 100644
index 0000000..64c3b23
--- /dev/null
+++ b/tools/test/h5repack/testfiles/h5repack_paged_persist.h5
Binary files differ
diff --git a/tools/test/h5repack/testh5repack_detect_szip.c b/tools/test/h5repack/testh5repack_detect_szip.c
index e08d5ab..6e7a24e 100644
--- a/tools/test/h5repack/testh5repack_detect_szip.c
+++ b/tools/test/h5repack/testh5repack_detect_szip.c
@@ -11,7 +11,6 @@
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include <stdio.h>
#include "h5repack.h"
#include "h5tools.h"
#include "h5tools_utils.h"
diff --git a/tools/test/misc/repart_test.c b/tools/test/misc/repart_test.c
index 372f46a..4016ee8 100644
--- a/tools/test/misc/repart_test.c
+++ b/tools/test/misc/repart_test.c
@@ -12,19 +12,16 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * Programmer: Raymond Lu <slu@ncsa.uiuc.edu>
- * June 1, 2005
- *
* Purpose: This program tests family files after being repartitioned
* by h5repart. It simply tries to reopen the files with
* correct family driver and member size.
*/
#include "hdf5.h"
+#include "H5private.h"
#define KB 1024
#define FAMILY_H5REPART_SIZE1 20000
#define FAMILY_H5REPART_SIZE2 (5*KB)
-#define MAX(a,b) (a>b ? a:b)
const char *FILENAME[] = {
"fst_family%05d.h5",
@@ -42,52 +39,54 @@ herr_t test_sec2_h5repart_opens(void);
*
* Purpose: Tries to reopen family files.
*
- * Return: Success: exit(0)
- *
- * Failure: exit(1)
+ * Return: SUCCEED/FAIL
*
- * Programmer: Raymond Lu
- * June 1, 2005
- *
- * Modifications:
*-------------------------------------------------------------------------
*/
herr_t
test_family_h5repart_opens(void)
{
- hid_t file=(-1), fapl=(-1);
+ hid_t fid = -1;
+ hid_t fapl_id = -1;
/* open 1st file(single member file) with correct family size(20000 byte) */
- if ((fapl=H5Pcreate(H5P_FILE_ACCESS))<0)
+ if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
goto error;
- if(H5Pset_fapl_family(fapl, (hsize_t)FAMILY_H5REPART_SIZE1, H5P_DEFAULT)<0)
+ if (H5Pset_fapl_family(fapl_id, (hsize_t)FAMILY_H5REPART_SIZE1, H5P_DEFAULT) < 0)
goto error;
- if((file=H5Fopen(FILENAME[0], H5F_ACC_RDWR, fapl))<0)
+ if ((fid = H5Fopen(FILENAME[0], H5F_ACC_RDWR, fapl_id))<0)
goto error;
- if(H5Fclose(file)<0)
+ if (H5Fclose(fid) < 0)
goto error;
/* open 2nd file(multiple member files) with correct family size(5KB) */
- if(H5Pset_fapl_family(fapl, (hsize_t)FAMILY_H5REPART_SIZE2, H5P_DEFAULT)<0)
+ if (H5Pset_fapl_family(fapl_id, (hsize_t)FAMILY_H5REPART_SIZE2, H5P_DEFAULT) < 0)
+ goto error;
+
+ if ((fid = H5Fopen(FILENAME[1], H5F_ACC_RDWR, fapl_id)) < 0)
goto error;
- if((file=H5Fopen(FILENAME[1], H5F_ACC_RDWR, fapl))<0)
+ if (H5Pclose(fapl_id) < 0)
goto error;
- if(H5Fclose(file)<0)
+ if (H5Fclose(fid) < 0)
goto error;
- return 0;
+ return SUCCEED;
error:
H5E_BEGIN_TRY {
- H5Fclose(file);
+ H5Pclose(fapl_id);
+ H5Fclose(fid);
} H5E_END_TRY;
- return -1;
-}
+
+ return FAIL;
+
+} /* end test_family_h5repart_opens() */
+
/*-------------------------------------------------------------------------
@@ -95,36 +94,32 @@ error:
*
* Purpose: Tries to reopen a sec2 file.
*
- * Return: Success: exit(0)
+ * Return: SUCCEED/FAIL
*
- * Failure: exit(1)
- *
- * Programmer: Raymond Lu
- * June 21, 2005
- *
- * Modifications:
*-------------------------------------------------------------------------
*/
herr_t
test_sec2_h5repart_opens(void)
{
- hid_t file=(-1);
+ hid_t fid = -1;
/* open the sec2 file */
- if((file=H5Fopen(FILENAME[2], H5F_ACC_RDWR, H5P_DEFAULT))<0)
+ if ((fid = H5Fopen(FILENAME[2], H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
goto error;
- if(H5Fclose(file)<0)
+ if (H5Fclose(fid) < 0)
goto error;
- return 0;
+ return SUCCEED;
error:
H5E_BEGIN_TRY {
- H5Fclose(file);
+ H5Fclose(fid);
} H5E_END_TRY;
- return -1;
-}
+
+ return FAIL;
+
+} /* end test_sec2_h5repart_opens() */
/*-------------------------------------------------------------------------
@@ -132,32 +127,26 @@ error:
*
* Purpose: Tests h5repart-ed family files
*
- * Return: Success: exit(0)
- *
- * Failure: exit(1)
- *
- * Programmer: Raymond Lu
- * June 1, 2005
- *
- * Modifications:
+ * Return: EXIT_SUCCESS/EXIT_FAILURE
*
*-------------------------------------------------------------------------
*/
int
main(void)
{
- int nerrors=0;
+ int nerrors = 0;
- nerrors += test_family_h5repart_opens()<0 ?1:0;
- nerrors += test_sec2_h5repart_opens()<0 ?1:0;
+ nerrors += test_family_h5repart_opens() < 0 ? 1 : 0;
+ nerrors += test_sec2_h5repart_opens() < 0 ? 1 : 0;
- if (nerrors) goto error;
+ if (nerrors)
+ goto error;
- return 0;
+ HDexit(EXIT_SUCCESS);
error:
nerrors = MAX(1, nerrors);
- printf("***** %d FAMILY FILE TEST%s FAILED! *****\n",
+ HDprintf("***** %d FAMILY FILE TEST%s FAILED! *****\n",
nerrors, 1 == nerrors ? "" : "S");
- return 1;
-}
+ HDexit(EXIT_FAILURE);
+} /* end main() */
diff --git a/tools/test/misc/talign.c b/tools/test/misc/talign.c
index 9a72557..ce866b4 100644
--- a/tools/test/misc/talign.c
+++ b/tools/test/misc/talign.c
@@ -15,9 +15,6 @@
* Small program to illustrate the "misalignment" of members within a compound
* datatype, in a datatype fixed by H5Tget_native_type().
*/
-#include <string.h>
-#include <stdlib.h>
-/*#include <unistd.h> *//* Required for unlink() */
#include "hdf5.h"
#include "H5private.h"
diff --git a/tools/test/perform/CMakeTests.cmake b/tools/test/perform/CMakeTests.cmake
index 2933563..39faa73 100644
--- a/tools/test/perform/CMakeTests.cmake
+++ b/tools/test/perform/CMakeTests.cmake
@@ -146,6 +146,7 @@ else ()
-P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake"
)
endif ()
+set_tests_properties (PERFORM_zip_perf PROPERTIES DEPENDS PERFORM_zip_perf_help)
if (H5_HAVE_PARALLEL)
add_test (NAME PERFORM_h5perf COMMAND ${MPIEXEC} ${MPIEXEC_PREFLAGS} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_POSTFLAGS} $<TARGET_FILE:h5perf>)
diff --git a/tools/testfiles/test35.nc b/tools/testfiles/test35.nc
new file mode 100644
index 0000000..4bd5d7f
--- /dev/null
+++ b/tools/testfiles/test35.nc
Binary files differ
diff --git a/tools/testfiles/test35.nc.xml b/tools/testfiles/test35.nc.xml
new file mode 100644
index 0000000..a38ed8a
--- /dev/null
+++ b/tools/testfiles/test35.nc.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<hdf5:HDF5-File xmlns:hdf5="http://hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hdfgroup.org/HDF5/XML/schema/HDF5-File http://www.hdfgroup.org/HDF5/XML/schema/HDF5-File.xsd">
+<hdf5:RootGroup OBJ-XID="xid_48" H5Path="/">
+ <hdf5:Attribute Name="aaa">
+ <hdf5:Dataspace>
+ <hdf5:ScalarDataspace />
+ </hdf5:Dataspace>
+ <hdf5:DataType>
+ <hdf5:AtomicType>
+ <hdf5:StringType Cset="H5T_CSET_ASCII" StrSize="14108" StrPad="H5T_STR_NULLTERM"/>
+ </hdf5:AtomicType>
+ </hdf5:DataType>
+ <hdf5:Data>
+ <hdf5:DataFromFile>
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaa&gt;aaaa&lt;aaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaa&gt;aaaa&lt;aaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaa&gt;a&lt;aaaaaa&gt;aaaaaaaa&lt;aaaaaa&gt;a&lt;aaaaaa&gt;aaaaaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&apos;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaa&gt;aaaaaaaaaaaaa&lt;aaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&apos;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"aaaaa\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaaaaa&lt;aaaa&gt;aaaa&lt;aaaa&gt;&gt;aaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaa&gt;aaaaaaaaaaaaaaaaaa&lt;aaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;a&gt;aaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaaaaaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaaaaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaa&lt;&gt;aaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaa&lt;aa&gt;aaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaa&lt;aa&gt;aaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaa&lt;aa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaaaaaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaa&gt;aaaaa&lt;aaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&lt;aaaaaaa&gt;aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ </hdf5:DataFromFile>
+ </hdf5:Data>
+ </hdf5:Attribute>
+</hdf5:RootGroup>
+</hdf5:HDF5-File>