From a45b73e4275b26505d8b659d1d807a654bb60df7 Mon Sep 17 00:00:00 2001 From: Dana Robinson <43805+derobins@users.noreply.github.com> Date: Tue, 5 Oct 2021 22:37:12 -0700 Subject: VFD SWMR: Normalization with develop (#1078) Brings many changes from develop, particularly VOL changes for async --- CMakeFilters.cmake | 18 +- CMakeLists.txt | 29 +- MANIFEST | 62 +- bin/release | 11 +- bin/trace | 2 - c++/src/H5DataType.cpp | 5 +- c++/src/H5IdComponent.cpp | 5 +- c++/src/H5PropList.cpp | 5 +- c++/src/h5c++.in | 6 +- c++/test/tattr.cpp | 18 +- c++/test/ttypes.cpp | 2 +- config/cmake/ConfigureChecks.cmake | 14 +- config/cmake/H5pubconf.h.in | 15 +- config/cmake/HDF5_Examples.cmake.in | 2 +- config/cmake/HDF5_Examples_options.cmake | 7 +- config/cmake/HDFCXXCompilerFlags.cmake | 316 ++- config/cmake/HDFCompilerFlags.cmake | 303 ++- config/cmake/HDFFortranCompilerFlags.cmake | 7 +- config/cmake/README.txt.cmake.in | 2 +- config/cmake/UseJava.cmake | 838 +++--- config/cmake/UseJavaClassFilelist.cmake | 17 +- config/cmake/UseJavaSymlinks.cmake | 11 +- config/cmake/hdf5-config.cmake.in | 1 + config/cmake/javaTargets.cmake.in | 39 + config/cmake/libh5cc.in | 2 +- config/cmake/libhdf5.settings.cmake.in | 1 + config/cmake/scripts/HDF5config.cmake | 6 +- config/cmake/scripts/HDF5options.cmake | 2 +- config/cmake_ext_mod/ConfigureChecks.cmake | 2 +- config/gnu-fflags | 8 +- config/intel-warnings/18 | 6 - config/intel-warnings/general-19 | 2 - config/intel-warnings/win-developer-general | 1 + config/intel-warnings/win-general | 1 + config/sanitizer/sanitizers.cmake | 8 +- config/toolchain/clang.cmake | 9 +- configure.ac | 35 +- doc/contributing.md | 35 +- doxygen/CMakeLists.txt | 46 + doxygen/Doxyfile.in | 18 +- doxygen/aliases | 100 +- doxygen/dox/APIVersions.dox | 173 ++ doxygen/dox/About.dox | 14 +- doxygen/dox/Cookbook.dox | 16 +- doxygen/dox/H5Acreate.dox | 9 - doxygen/dox/H5Aiterate.dox | 9 - doxygen/dox/H5Fget_info.dox | 44 - doxygen/dox/H5Lget_info.dox | 17 - doxygen/dox/H5Lget_info_by_idx.dox | 17 - doxygen/dox/H5Literate.dox | 20 - doxygen/dox/H5Literate_by_name.dox | 21 - doxygen/dox/H5Lvisit.dox | 20 - doxygen/dox/H5Lvisit_by_name.dox | 20 - doxygen/dox/H5Oget_info.dox | 72 - doxygen/dox/H5Oget_info_by_idx.dox | 55 - doxygen/dox/H5Oget_info_by_name.dox | 58 - doxygen/dox/H5Ovisit.dox | 55 - doxygen/dox/H5Ovisit_by_name.dox | 54 - doxygen/dox/H5Sencode.dox | 5 - doxygen/dox/MetadataCachingInHDF5.dox | 6 +- doxygen/dox/RFC.dox | 91 + doxygen/dox/ReferenceManual.dox | 116 +- doxygen/dox/cookbook/Accessibility.c | 48 + doxygen/dox/cookbook/Accessibility.dox | 39 + doxygen/dox/cookbook/Attributes.c | 61 + doxygen/dox/cookbook/Attributes.dox | 38 + doxygen/dox/cookbook/Files.c | 87 + doxygen/dox/cookbook/Files.dox | 71 + doxygen/dox/cookbook/Performance.dox | 21 + doxygen/dox/maybe_metadata_reads.dox | 68 +- doxygen/dox/rm-template.dox | 171 +- doxygen/examples/H5D_examples.c | 81 +- doxygen/examples/H5E_examples.c | 97 + doxygen/examples/H5F_examples.c | 55 +- doxygen/examples/H5G_examples.c | 186 ++ doxygen/examples/H5I_examples.c | 242 ++ doxygen/examples/H5L_examples.c | 156 ++ doxygen/examples/H5O_examples.c | 193 ++ doxygen/examples/H5PL_examples.c | 97 + doxygen/examples/H5P_examples.c | 227 ++ doxygen/examples/H5R_examples.c | 171 ++ doxygen/examples/H5S_examples.c | 132 + doxygen/examples/H5T_examples.c | 136 + doxygen/examples/H5Z_examples.c | 108 + doxygen/examples/H5_examples.c | 85 + doxygen/hdf5_header.html | 2 +- doxygen/hdf5doxy_layout.xml | 1 + examples/CMakeTests.cmake | 7 +- fortran/src/CMakeLists.txt | 13 + fortran/src/H5Fff.F90 | 4 +- fortran/test/fortranlib_test.F90 | 4 + fortran/test/tH5F.F90 | 122 +- fortran/test/tH5Z.F90 | 7 +- hl/CMakeLists.txt | 12 +- hl/Makefile.am | 5 +- hl/c++/src/H5PacketTable.cpp | 25 +- hl/c++/src/H5PacketTable.h | 20 +- hl/c++/test/ptableTest.cpp | 2 +- hl/examples/ex_table_01.c | 8 +- hl/examples/ex_table_02.c | 10 +- hl/examples/ex_table_03.c | 6 +- hl/examples/ex_table_04.c | 10 +- hl/examples/ex_table_05.c | 4 +- hl/examples/ex_table_06.c | 2 +- hl/examples/ex_table_07.c | 10 +- hl/examples/ex_table_08.c | 10 +- hl/examples/ex_table_09.c | 10 +- hl/examples/ex_table_10.c | 8 +- hl/examples/ex_table_11.c | 10 +- hl/examples/ex_table_12.c | 10 +- hl/src/CMakeLists.txt | 29 + hl/src/H5LT.c | 63 +- hl/src/H5LTpublic.h | 6 + hl/test/gen_test_ds.c | 2 +- hl/test/test_ds.c | 2 + hl/test/test_lite.c | 109 +- hl/test/test_packet.c | 8 +- hl/test/test_table.c | 46 +- hl/tools/h5watch/h5watchgentest.c | 4 +- java/src/hdf/hdf5lib/HDFArray.java | 52 +- java/src/hdf/hdf5lib/HDFNativeData.java | 30 +- java/src/hdf/hdf5lib/structs/H5FD_hdfs_fapl_t.java | 15 +- java/src/hdf/hdf5lib/structs/H5FD_ros3_fapl_t.java | 15 +- java/src/jni/h5Constants.c | 12 +- java/src/jni/h5util.c | 19 +- java/test/TestH5Arw.java | 2 +- java/test/TestH5Pfapl.java | 2 +- release_docs/INSTALL_CMake.txt | 1 + release_docs/README_HDF5_CMake | 17 +- release_docs/RELEASE.txt | 125 +- release_docs/USING_CMake_Examples.txt | 1 + release_docs/USING_HDF5_CMake.txt | 32 +- src/CMakeLists.txt | 3 + src/H5.c | 253 +- src/H5A.c | 355 ++- src/H5ACprivate.h | 16 +- src/H5Adeprec.c | 35 +- src/H5Aint.c | 40 +- src/H5Amodule.h | 24 +- src/H5Apkg.h | 16 +- src/H5Apublic.h | 267 +- src/H5CS.c | 14 +- src/H5CX.c | 453 ++-- src/H5D.c | 391 ++- src/H5Dchunk.c | 83 +- src/H5Ddeprec.c | 31 +- src/H5Dint.c | 27 +- src/H5Dio.c | 91 +- src/H5Dmodule.h | 8 +- src/H5Dpkg.h | 4 +- src/H5Dpublic.h | 567 ++-- src/H5Dvirtual.c | 2 +- src/H5E.c | 35 +- src/H5ES.c | 407 ++- src/H5ESdevelop.h | 50 + src/H5ESevent.c | 16 +- src/H5ESint.c | 434 +++- src/H5ESmodule.h | 6 +- src/H5ESpkg.h | 18 +- src/H5ESprivate.h | 5 +- src/H5ESpublic.h | 70 +- src/H5Eint.c | 22 +- src/H5Emodule.h | 75 +- src/H5Epublic.h | 36 +- src/H5F.c | 794 ++++-- src/H5FDfamily.c | 8 +- src/H5FDhdfs.c | 18 +- src/H5FDhdfs.h | 15 +- src/H5FDlog.c | 2 - src/H5FDmirror.c | 4 +- src/H5FDmulti.c | 8 +- src/H5FDros3.c | 2 + src/H5FDsplitter.c | 22 +- src/H5FL.c | 56 +- src/H5Faccum.c | 2 +- src/H5Fdeprec.c | 53 +- src/H5Fefc.c | 8 +- src/H5Fint.c | 77 +- src/H5Fmodule.h | 19 +- src/H5Fmount.c | 25 +- src/H5Fmpi.c | 45 +- src/H5Fpkg.h | 38 +- src/H5Fprivate.h | 94 +- src/H5Fpublic.h | 4 +- src/H5G.c | 83 +- src/H5Gcompact.c | 18 +- src/H5Gdense.c | 39 +- src/H5Gdeprec.c | 291 ++- src/H5Gloc.c | 62 +- src/H5Gmodule.h | 25 +- src/H5Gname.c | 55 +- src/H5Gobj.c | 21 +- src/H5Gpkg.h | 79 +- src/H5Gprivate.h | 73 +- src/H5Gpublic.h | 2 + src/H5Gstab.c | 26 +- src/H5Gtest.c | 6 +- src/H5I.c | 20 +- src/H5Idbg.c | 4 +- src/H5Iint.c | 36 +- src/H5Imodule.h | 81 +- src/H5Ipublic.h | 33 +- src/H5Itest.c | 10 +- src/H5L.c | 425 ++- src/H5Ldeprec.c | 146 +- src/H5Lexternal.c | 14 +- src/H5Lint.c | 69 +- src/H5Lmodule.h | 25 +- src/H5Lpkg.h | 43 +- src/H5Lprivate.h | 44 - src/H5Lpublic.h | 2 + src/H5M.c | 346 ++- src/H5MF.c | 22 +- src/H5MFprivate.h | 3 +- src/H5Mmodule.h | 6 +- src/H5Mprivate.h | 7 +- src/H5Mpublic.h | 112 + src/H5O.c | 443 ++-- src/H5Ocache.c | 21 +- src/H5Odeprec.c | 155 +- src/H5Oflush.c | 29 +- src/H5Ofsinfo.c | 15 +- src/H5Omodule.h | 41 +- src/H5Opkg.h | 5 + src/H5Oprivate.h | 10 +- src/H5Opublic.h | 679 +---- src/H5PL.c | 2 +- src/H5PLint.c | 6 +- src/H5PLmodule.h | 30 +- src/H5PLplugin_cache.c | 84 +- src/H5Pdapl.c | 4 +- src/H5Pdxpl.c | 8 +- src/H5Pencdec.c | 2 +- src/H5Pfapl.c | 58 + src/H5Pint.c | 3 +- src/H5Plapl.c | 2 +- src/H5Pmodule.h | 164 +- src/H5Ppublic.h | 142 +- src/H5R.c | 199 +- src/H5RS.c | 10 +- src/H5RSprivate.h | 2 +- src/H5Rdeprec.c | 133 +- src/H5Rint.c | 13 +- src/H5Rmodule.h | 29 +- src/H5Rpublic.h | 10 +- src/H5SL.c | 4 +- src/H5SM.c | 2 +- src/H5Smodule.h | 45 +- src/H5Spublic.h | 112 +- src/H5T.c | 19 +- src/H5Tcommit.c | 119 +- src/H5Tconv.c | 120 +- src/H5Tmodule.h | 36 +- src/H5Tprivate.h | 7 +- src/H5Tref.c | 125 +- src/H5Tvlen.c | 50 +- src/H5VL.c | 180 +- src/H5VLcallback.c | 1752 +++++++------ src/H5VLconnector.h | 883 ++++++- src/H5VLconnector_passthru.h | 101 +- src/H5VLdyn_ops.c | 334 +++ src/H5VLint.c | 270 +- src/H5VLmodule.h | 8 +- src/H5VLnative.c | 45 +- src/H5VLnative.h | 387 ++- src/H5VLnative_attr.c | 213 +- src/H5VLnative_blob.c | 34 +- src/H5VLnative_dataset.c | 240 +- src/H5VLnative_datatype.c | 46 +- src/H5VLnative_file.c | 365 +-- src/H5VLnative_group.c | 129 +- src/H5VLnative_introspect.c | 5 +- src/H5VLnative_link.c | 135 +- src/H5VLnative_object.c | 174 +- src/H5VLnative_private.h | 72 +- src/H5VLpassthru.c | 682 ++--- src/H5VLpkg.h | 12 + src/H5VLprivate.h | 116 +- src/H5VLpublic.h | 8 +- src/H5VLtest.c | 96 + src/H5Zmodule.h | 109 +- src/H5Zscaleoffset.c | 58 +- src/H5Ztrans.c | 18 +- src/H5detect.c | 12 +- src/H5module.h | 27 +- src/H5mpi.c | 2 +- src/H5private.h | 52 +- src/H5public.h | 36 +- src/H5system.c | 28 +- src/H5trace.c | 86 +- src/H5win32defs.h | 2 +- src/Makefile.am | 6 +- src/hdf5.h | 2 + test/CMakeTests.cmake | 4 +- test/Makefile.am | 2 +- test/ShellTests.cmake | 118 +- test/big.c | 8 +- test/cache.c | 1118 ++++---- test/chunk_info.c | 52 +- test/cmpd_dset.c | 4 +- test/cve_2020_10810.h5 | Bin 0 -> 1808 bytes test/dsets.c | 378 ++- test/dt_arith.c | 8 +- test/dtransform.c | 97 +- test/dtypes.c | 10 +- test/enc_dec_plist.c | 4 +- test/error_test.c | 4 +- test/event_set.c | 66 + test/fheap.c | 4 +- test/file_image.c | 4 +- test/fillval.c | 6 +- test/gheap.c | 2 +- test/h5test.c | 4 +- test/hyperslab.c | 6 +- test/null_vol_connector.c | 1 + test/ohdr.c | 58 +- test/pool.c | 2 +- test/set_extent.c | 6 +- test/swmr_common.c | 2 +- test/swmr_common.h | 2 +- test/tattr.c | 7 +- test/tconfig.c | 5 +- test/test_usecases.sh.in | 22 +- test/testcheck_version.sh.in | 106 +- test/testhdf5.h | 2 +- test/testswmr.sh.in | 40 +- test/testvdsswmr.sh.in | 16 +- test/tfile.c | 2 +- test/timer.c | 18 +- test/tmeta.c | 4 +- test/tmisc.c | 2 +- test/tsohm.c | 2 +- test/tunicode.c | 2 +- test/tvltypes.c | 8 +- test/vds.c | 12 +- test/vfd.c | 12 +- test/vol.c | 926 ++++++- testpar/t_filters_parallel.c | 403 ++- testpar/t_filters_parallel.h | 20 + tools/lib/h5diff_array.c | 8 +- tools/lib/h5tools_str.c | 3 +- tools/libtest/Makefile.am | 18 +- tools/libtest/h5tools_test_utils.c | 4 +- tools/src/CMakeLists.txt | 5 +- tools/src/Makefile.am | 2 +- tools/src/h5dump/h5dump.c | 78 - tools/src/h5dump/h5dump_ddl.c | 20 +- tools/src/h5dump/h5dump_xml.c | 39 +- tools/src/h5format_convert/h5format_convert.c | 23 +- tools/src/h5import/h5import.c | 7 +- tools/src/h5jam/h5jam.c | 12 +- tools/src/h5jam/h5unjam.c | 10 +- tools/src/h5perf/CMakeLists.txt | 103 + tools/src/h5perf/Makefile.am | 63 + tools/src/h5perf/perf.c | 796 ++++++ tools/src/h5perf/pio_engine.c | 2745 ++++++++++++++++++++ tools/src/h5perf/pio_perf.c | 1718 ++++++++++++ tools/src/h5perf/pio_perf.h | 109 + tools/src/h5perf/sio_engine.c | 1328 ++++++++++ tools/src/h5perf/sio_perf.c | 1301 ++++++++++ tools/src/h5perf/sio_perf.h | 104 + tools/src/h5repack/h5repack_copy.c | 25 +- tools/src/h5stat/h5stat.c | 83 - tools/src/misc/h5clear.c | 39 +- tools/test/h5diff/CMakeTests.cmake | 63 +- tools/test/h5dump/h5dumpgentest.c | 4 +- tools/test/h5jam/h5jamgentest.c | 447 ++-- tools/test/h5repack/h5repacktst.c | 4 +- tools/test/h5stat/CMakeTests.cmake | 2 +- tools/test/h5stat/h5stat_gentest.c | 145 +- tools/test/h5stat/testh5stat.sh.in | 2 +- tools/test/misc/CMakeTestsClear.cmake | 4 +- tools/test/misc/testh5clear.sh.in | 4 +- tools/test/perform/CMakeLists.txt | 81 +- tools/test/perform/Makefile.am | 23 +- tools/test/perform/chunk_cache.c | 6 +- tools/test/perform/perf.c | 471 ---- tools/test/perform/pio_engine.c | 2745 -------------------- tools/test/perform/pio_perf.c | 1699 ------------ tools/test/perform/pio_perf.h | 100 - tools/test/perform/pio_standalone.c | 140 - tools/test/perform/pio_standalone.h | 17 +- tools/test/perform/sio_engine.c | 1328 ---------- tools/test/perform/sio_perf.c | 1437 ---------- tools/test/perform/sio_perf.h | 104 - tools/test/perform/sio_standalone.c | 5 - tools/test/perform/sio_standalone.h | 17 +- tools/test/perform/zip_perf.c | 53 +- 388 files changed, 26663 insertions(+), 17892 deletions(-) create mode 100644 config/cmake/javaTargets.cmake.in delete mode 100644 config/intel-warnings/general-19 create mode 100644 config/intel-warnings/win-developer-general create mode 100644 config/intel-warnings/win-general create mode 100644 doxygen/CMakeLists.txt create mode 100644 doxygen/dox/APIVersions.dox delete mode 100644 doxygen/dox/H5Acreate.dox delete mode 100644 doxygen/dox/H5Aiterate.dox delete mode 100644 doxygen/dox/H5Fget_info.dox delete mode 100644 doxygen/dox/H5Lget_info.dox delete mode 100644 doxygen/dox/H5Lget_info_by_idx.dox delete mode 100644 doxygen/dox/H5Literate.dox delete mode 100644 doxygen/dox/H5Literate_by_name.dox delete mode 100644 doxygen/dox/H5Lvisit.dox delete mode 100644 doxygen/dox/H5Lvisit_by_name.dox delete mode 100644 doxygen/dox/H5Oget_info.dox delete mode 100644 doxygen/dox/H5Oget_info_by_idx.dox delete mode 100644 doxygen/dox/H5Oget_info_by_name.dox delete mode 100644 doxygen/dox/H5Ovisit.dox delete mode 100644 doxygen/dox/H5Ovisit_by_name.dox delete mode 100644 doxygen/dox/H5Sencode.dox create mode 100644 doxygen/dox/RFC.dox create mode 100644 doxygen/dox/cookbook/Accessibility.c create mode 100644 doxygen/dox/cookbook/Accessibility.dox create mode 100644 doxygen/dox/cookbook/Attributes.c create mode 100644 doxygen/dox/cookbook/Attributes.dox create mode 100644 doxygen/dox/cookbook/Files.c create mode 100644 doxygen/dox/cookbook/Files.dox create mode 100644 doxygen/dox/cookbook/Performance.dox create mode 100644 doxygen/examples/H5E_examples.c create mode 100644 doxygen/examples/H5G_examples.c create mode 100644 doxygen/examples/H5I_examples.c create mode 100644 doxygen/examples/H5L_examples.c create mode 100644 doxygen/examples/H5O_examples.c create mode 100644 doxygen/examples/H5PL_examples.c create mode 100644 doxygen/examples/H5P_examples.c create mode 100644 doxygen/examples/H5R_examples.c create mode 100644 doxygen/examples/H5S_examples.c create mode 100644 doxygen/examples/H5T_examples.c create mode 100644 doxygen/examples/H5Z_examples.c create mode 100644 doxygen/examples/H5_examples.c create mode 100644 src/H5ESdevelop.h create mode 100644 src/H5VLdyn_ops.c create mode 100644 src/H5VLtest.c create mode 100644 test/cve_2020_10810.h5 create mode 100644 tools/src/h5perf/CMakeLists.txt create mode 100644 tools/src/h5perf/Makefile.am create mode 100644 tools/src/h5perf/perf.c create mode 100644 tools/src/h5perf/pio_engine.c create mode 100644 tools/src/h5perf/pio_perf.c create mode 100644 tools/src/h5perf/pio_perf.h create mode 100644 tools/src/h5perf/sio_engine.c create mode 100644 tools/src/h5perf/sio_perf.c create mode 100644 tools/src/h5perf/sio_perf.h delete mode 100644 tools/test/perform/perf.c delete mode 100644 tools/test/perform/pio_engine.c delete mode 100644 tools/test/perform/pio_perf.c delete mode 100644 tools/test/perform/pio_perf.h delete mode 100644 tools/test/perform/sio_engine.c delete mode 100644 tools/test/perform/sio_perf.c delete mode 100644 tools/test/perform/sio_perf.h diff --git a/CMakeFilters.cmake b/CMakeFilters.cmake index d5f801e..51ac61c 100644 --- a/CMakeFilters.cmake +++ b/CMakeFilters.cmake @@ -10,6 +10,7 @@ # help@hdfgroup.org. # option (USE_LIBAEC "Use AEC library as SZip Filter" OFF) +option (USE_LIBAEC_STATIC "Use static AEC library " OFF) include (ExternalProject) include (FetchContent) @@ -110,13 +111,24 @@ option (HDF5_ENABLE_SZIP_SUPPORT "Use SZip Filter" OFF) if (HDF5_ENABLE_SZIP_SUPPORT) option (HDF5_ENABLE_SZIP_ENCODING "Use SZip Encoding" OFF) if (NOT SZIP_USE_EXTERNAL) - find_package (SZIP NAMES ${SZIP_PACKAGE_NAME}${HDF_PACKAGE_EXT} COMPONENTS static shared) - if (NOT SZIP_FOUND) - find_package (SZIP) # Legacy find + set(SZIP_FOUND FALSE) + if (USE_LIBAEC) + set(libaec_USE_STATIC_LIBS ${USE_LIBAEC_STATIC}) + find_package (libaec 1.0.5 CONFIG) if (SZIP_FOUND) set (LINK_COMP_LIBS ${LINK_COMP_LIBS} ${SZIP_LIBRARIES}) endif () endif () + + if (NOT SZIP_FOUND) + find_package (SZIP NAMES ${SZIP_PACKAGE_NAME}${HDF_PACKAGE_EXT} COMPONENTS static shared) + if (NOT SZIP_FOUND) + find_package (SZIP) # Legacy find + if (SZIP_FOUND) + set (LINK_COMP_LIBS ${LINK_COMP_LIBS} ${SZIP_LIBRARIES}) + endif () + endif () + endif () endif () if (SZIP_FOUND) set (H5_HAVE_FILTER_SZIP 1) diff --git a/CMakeLists.txt b/CMakeLists.txt index 734d945..11644b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -572,20 +572,6 @@ endif () # endif () #----------------------------------------------------------------------------- -# Option to build documentation -#----------------------------------------------------------------------------- -option (HDF5_BUILD_DOC "Build documentation" OFF) -if (HDF5_BUILD_DOC AND EXISTS "${HDF5_DOXYGEN_DIR}" AND IS_DIRECTORY "${HDF5_DOXYGEN_DIR}") -# check if Doxygen is installed - find_package(Doxygen) - if (DOXYGEN_FOUND) - message(STATUS "Doxygen version: ${DOXYGEN_VERSION}") - else () - message(STATUS "Doxygen needs to be installed to generate the doxygen documentation") - endif () -endif () - -#----------------------------------------------------------------------------- # Option to indicate using a memory checker #----------------------------------------------------------------------------- option (HDF5_ENABLE_USING_MEMCHECKER "Indicate that a memory checker is used" OFF) @@ -931,6 +917,21 @@ if (HDF5_ALLOW_EXTERNAL_SUPPORT MATCHES "GIT" OR HDF5_ALLOW_EXTERNAL_SUPPORT MAT endif () #----------------------------------------------------------------------------- +# Option to build documentation +#----------------------------------------------------------------------------- +option (HDF5_BUILD_DOC "Build documentation" OFF) +if (HDF5_BUILD_DOC AND EXISTS "${HDF5_DOXYGEN_DIR}" AND IS_DIRECTORY "${HDF5_DOXYGEN_DIR}") +# check if Doxygen is installed + find_package(Doxygen) + if (DOXYGEN_FOUND) + message(STATUS "Doxygen version: ${DOXYGEN_VERSION}") + add_subdirectory (doxygen) + else () + message(STATUS "Doxygen needs to be installed to generate the doxygen documentation") + endif () +endif () + +#----------------------------------------------------------------------------- # Dashboard and Testing Settings #----------------------------------------------------------------------------- option (BUILD_TESTING "Build HDF5 Unit Testing" ON) diff --git a/MANIFEST b/MANIFEST index dcdedef..ca1a58c 100644 --- a/MANIFEST +++ b/MANIFEST @@ -202,7 +202,8 @@ ./config/intel-warnings/18 ./config/intel-warnings/developer-general ./config/intel-warnings/general -./config/intel-warnings/general-19 +./config/intel-warnings/win-developer-general +./config/intel-warnings/win-general ./config/intel-warnings/ifort-general ./config/site-specific/BlankForm @@ -219,7 +220,9 @@ ./doc/contributing.md ./doxygen/aliases +./doxygen/CMakeLists.txt ./doxygen/Doxyfile.in +./doxygen/dox/APIVersions.dox ./doxygen/dox/About.dox ./doxygen/dox/Cookbook.dox ./doxygen/dox/DDLBNF110.dox @@ -227,30 +230,23 @@ ./doxygen/dox/FileFormatSpec.dox ./doxygen/dox/GettingStarted.dox ./doxygen/dox/H5AC_cache_config_t.dox -./doxygen/dox/H5Acreate.dox -./doxygen/dox/H5Aiterate.dox -./doxygen/dox/H5Fget_info.dox -./doxygen/dox/H5Lget_info_by_idx.dox -./doxygen/dox/H5Lget_info.dox -./doxygen/dox/H5Literate_by_name.dox -./doxygen/dox/H5Literate.dox -./doxygen/dox/H5Lvisit_by_name.dox -./doxygen/dox/H5Lvisit.dox -./doxygen/dox/H5Oget_info_by_idx.dox -./doxygen/dox/H5Oget_info_by_name.dox -./doxygen/dox/H5Oget_info.dox -./doxygen/dox/H5Ovisit_by_name.dox -./doxygen/dox/H5Ovisit.dox -./doxygen/dox/H5Sencode.dox ./doxygen/dox/MetadataCachingInHDF5.dox ./doxygen/dox/OtherSpecs.dox ./doxygen/dox/Overview.dox ./doxygen/dox/ReferenceManual.dox +./doxygen/dox/RFC.dox ./doxygen/dox/Specifications.dox ./doxygen/dox/TechnicalNotes.dox ./doxygen/dox/api-compat-macros.dox ./doxygen/dox/maybe_metadata_reads.dox ./doxygen/dox/rm-template.dox +./doxygen/dox/cookbook/Accessibility.c +./doxygen/dox/cookbook/Accessibility.dox +./doxygen/dox/cookbook/Attributes.c +./doxygen/dox/cookbook/Attributes.dox +./doxygen/dox/cookbook/Files.c +./doxygen/dox/cookbook/Files.dox +./doxygen/dox/cookbook/Performance.dox ./doxygen/examples/FF-IH_FileGroup.gif ./doxygen/examples/FF-IH_FileObject.gif ./doxygen/examples/FileFormatSpecChunkDiagram.jpg @@ -262,13 +258,25 @@ ./doxygen/examples/H5.format.html ./doxygen/examples/H5A_examples.c ./doxygen/examples/H5D_examples.c +./doxygen/examples/H5E_examples.c ./doxygen/examples/H5Fclose.c ./doxygen/examples/H5Fcreate.c ./doxygen/examples/H5F_examples.c +./doxygen/examples/H5G_examples.c +./doxygen/examples/H5I_examples.c +./doxygen/examples/H5L_examples.c +./doxygen/examples/H5O_examples.c +./doxygen/examples/H5PL_examples.c ./doxygen/examples/H5Pget_metadata_read_attempts.1.c ./doxygen/examples/H5Pget_metadata_read_attempts.2.c ./doxygen/examples/H5Pget_metadata_read_attempts.3.c ./doxygen/examples/H5Pget_object_flush_cb.c +./doxygen/examples/H5P_examples.c +./doxygen/examples/H5R_examples.c +./doxygen/examples/H5S_examples.c +./doxygen/examples/H5T_examples.c +./doxygen/examples/H5Z_examples.c +./doxygen/examples/H5_examples.c ./doxygen/examples/ImageSpec.html ./doxygen/examples/PaletteExample1.gif ./doxygen/examples/Palettes.fm.anc.gif @@ -750,6 +758,7 @@ ./src/H5EAstat.c ./src/H5EAtest.c ./src/H5ES.c +./src/H5ESdevelop.h ./src/H5ESevent.c ./src/H5ESint.c ./src/H5ESlist.c @@ -1106,6 +1115,7 @@ ./src/H5VLcallback.c ./src/H5VLconnector.h ./src/H5VLconnector_passthru.h +./src/H5VLdyn_ops.c ./src/H5VLint.c ./src/H5VLmodule.h ./src/H5VLnative.c @@ -1126,6 +1136,7 @@ ./src/H5VLpkg.h ./src/H5VLprivate.h ./src/H5VLpublic.h +./src/H5VLtest.c ./src/H5VM.c ./src/H5VMprivate.h ./src/H5WB.c @@ -1188,6 +1199,7 @@ ./test/cork.c ./test/corrupt_stab_msg.h5 ./test/cross_read.c +./test/cve_2020_10810.h5 ./test/dangle.c ./test/deflate.h5 ./test/del_many_dense_attrs.c @@ -2992,6 +3004,15 @@ ./tools/testfiles/h5mkgrp_single_p.ls ./tools/testfiles/h5mkgrp_single_l.ls +./tools/src/h5perf/Makefile.am +./tools/src/h5perf/perf.c +./tools/src/h5perf/pio_engine.c +./tools/src/h5perf/pio_perf.c +./tools/src/h5perf/pio_perf.h +./tools/src/h5perf/sio_engine.c +./tools/src/h5perf/sio_perf.c +./tools/src/h5perf/sio_perf.h + ./tools/test/perform/Makefile.am ./tools/test/perform/build_h5perf_alone.sh ./tools/test/perform/build_h5perf_serial_alone.sh @@ -3001,16 +3022,9 @@ ./tools/test/perform/gen_report.pl ./tools/test/perform/iopipe.c ./tools/test/perform/overhead.c -./tools/test/perform/perf.c ./tools/test/perform/perf_meta.c -./tools/test/perform/pio_engine.c -./tools/test/perform/pio_perf.c -./tools/test/perform/pio_perf.h ./tools/test/perform/pio_standalone.c ./tools/test/perform/pio_standalone.h -./tools/test/perform/sio_engine.c -./tools/test/perform/sio_perf.c -./tools/test/perform/sio_perf.h ./tools/test/perform/sio_standalone.c ./tools/test/perform/sio_standalone.h ./tools/test/perform/zip_perf.c @@ -3615,6 +3629,7 @@ ./config/cmake/HDF5PluginMacros.cmake ./config/cmake/HDF5PluginCache.cmake ./config/cmake/HDF5UseFortran.cmake +./config/cmake/javaTargets.cmake.in ./config/cmake/jrunTest.cmake ./config/cmake/jvolTest.cmake ./config/cmake/libh5cc.in @@ -3753,6 +3768,7 @@ ./tools/test/h5stat/CMakeLists.txt ./tools/test/h5stat/CMakeTests.cmake ./tools/src/misc/CMakeLists.txt +./tools/src/h5perf/CMakeLists.txt ./tools/test/misc/CMakeLists.txt ./tools/test/misc/CMakeTestsClear.cmake ./tools/test/misc/CMakeTestsMkgrp.cmake diff --git a/bin/release b/bin/release index 2570b38..8774851 100755 --- a/bin/release +++ b/bin/release @@ -229,11 +229,14 @@ tar2cmakezip() (cd $cmziptmpsubdir; echo "ctest -S HDF5config.cmake,BUILD_GENERATOR=VS201564 -C Release -V -O hdf5.log" > build-VS2015-64.bat; chmod 755 build-VS2015-64.bat) (cd $cmziptmpsubdir; echo "ctest -S HDF5config.cmake,BUILD_GENERATOR=VS2017 -C Release -V -O hdf5.log" > build-VS2017-32.bat; chmod 755 build-VS2017-32.bat) (cd $cmziptmpsubdir; echo "ctest -S HDF5config.cmake,BUILD_GENERATOR=VS201764 -C Release -V -O hdf5.log" > build-VS2017-64.bat; chmod 755 build-VS2017-64.bat) + (cd $cmziptmpsubdir; echo "ctest -S HDF5config.cmake,BUILD_GENERATOR=VS2019 -C Release -V -O hdf5.log" > build-VS2019-32.bat; chmod 755 build-VS2019-32.bat) + (cd $cmziptmpsubdir; echo "ctest -S HDF5config.cmake,BUILD_GENERATOR=VS201964 -C Release -V -O hdf5.log" > build-VS2019-64.bat; chmod 755 build-VS2019-64.bat) # step 3: add LIBAEC.tar.gz, ZLib.tar.gz and cmake files cp /mnt/scr1/pre-release/hdf5/CMake/LIBAEC.tar.gz $cmziptmpsubdir cp /mnt/scr1/pre-release/hdf5/CMake/ZLib.tar.gz $cmziptmpsubdir - cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.1-Source.zip $cmziptmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.4-Source.zip $cmziptmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/hdf5_plugins-master.zip $cmziptmpsubdir cp $cmziptmpsubdir/$version/config/cmake/scripts/CTestScript.cmake $cmziptmpsubdir cp $cmziptmpsubdir/$version/config/cmake/scripts/HDF5config.cmake $cmziptmpsubdir cp $cmziptmpsubdir/$version/config/cmake/scripts/HDF5options.cmake $cmziptmpsubdir @@ -328,7 +331,8 @@ tar2cmaketgz() # step 3: add LIBAEC.tar.gz, ZLib.tar.gz and cmake files cp /mnt/scr1/pre-release/hdf5/CMake/LIBAEC.tar.gz $cmgztmpsubdir cp /mnt/scr1/pre-release/hdf5/CMake/ZLib.tar.gz $cmgztmpsubdir - cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.1-Source.tar.gz $cmgztmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.4-Source.tar.gz $cmgztmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/hdf5_plugins-master.tar.gz $cmgztmpsubdir cp $cmgztmpsubdir/$version/config/cmake/scripts/CTestScript.cmake $cmgztmpsubdir cp $cmgztmpsubdir/$version/config/cmake/scripts/HDF5config.cmake $cmgztmpsubdir cp $cmgztmpsubdir/$version/config/cmake/scripts/HDF5options.cmake $cmgztmpsubdir @@ -411,7 +415,8 @@ tar2hpccmaketgz() # step 3: add LIBAEC.tar.gz, ZLib.tar.gz and cmake files cp /mnt/scr1/pre-release/hdf5/CMake/LIBAEC.tar.gz $cmgztmpsubdir cp /mnt/scr1/pre-release/hdf5/CMake/ZLib.tar.gz $cmgztmpsubdir - cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.1-Source.tar.gz $cmgztmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/HDF5Examples-1.14.4-Source.tar.gz $cmgztmpsubdir + cp /mnt/scr1/pre-release/hdf5/CMake/hdf5_plugins-master.tar.gz $cmgztmpsubdir cp $cmgztmpsubdir/$version/config/cmake/scripts/CTestScript.cmake $cmgztmpsubdir cp $cmgztmpsubdir/$version/config/cmake/scripts/HDF5config.cmake $cmgztmpsubdir diff --git a/bin/trace b/bin/trace index ba2fcf7..cc26f86 100755 --- a/bin/trace +++ b/bin/trace @@ -162,8 +162,6 @@ $Source = ""; "H5VL_group_get_t" => "Vi", "H5VL_group_specific_t" => "Vj", "H5VL_link_create_t" => "Vk", -# XXX: DELETE LATER - part of combo branch merge - "H5VL_link_create_type_t" => "Vk", "H5VL_link_get_t" => "Vl", "H5VL_get_conn_lvl_t" => "VL", "H5VL_link_specific_t" => "Vm", diff --git a/c++/src/H5DataType.cpp b/c++/src/H5DataType.cpp index b00a526..af58a90 100644 --- a/c++/src/H5DataType.cpp +++ b/c++/src/H5DataType.cpp @@ -338,10 +338,7 @@ DataType::encode() bool DataType::hasBinaryDesc() const { - if (encoded_buf != NULL) - return true; - else - return false; + return encoded_buf != NULL; } //-------------------------------------------------------------------------- diff --git a/c++/src/H5IdComponent.cpp b/c++/src/H5IdComponent.cpp index d546d32..e1fc687 100644 --- a/c++/src/H5IdComponent.cpp +++ b/c++/src/H5IdComponent.cpp @@ -432,10 +432,7 @@ IdComponent::p_valid_id(const hid_t obj_id) return false; H5I_type_t id_type = H5Iget_type(obj_id); - if (id_type <= H5I_BADID || id_type >= H5I_NTYPES) - return false; - else - return true; + return (id_type > H5I_BADID && id_type < H5I_NTYPES); } // Notes about IdComponent::id diff --git a/c++/src/H5PropList.cpp b/c++/src/H5PropList.cpp index 7dca716..7ee8395 100644 --- a/c++/src/H5PropList.cpp +++ b/c++/src/H5PropList.cpp @@ -543,7 +543,7 @@ PropList::getPropSize(const H5std_string &name) const // Function: PropList::getClassName ///\brief Return the name of a generic property list class. ///\return A string containing the class name, if success, otherwise, -/// a NULL string. +/// an empty string. // Programmer: Binh-Minh Ribler - April, 2004 //-------------------------------------------------------------------------- H5std_string @@ -557,8 +557,9 @@ PropList::getClassName() const return (class_name); } else - return 0; + return ""; } + //-------------------------------------------------------------------------- // Function: PropList::getNumProps ///\brief Returns the number of properties in this property list or class. diff --git a/c++/src/h5c++.in b/c++/src/h5c++.in index cf993b9..573d20d 100644 --- a/c++/src/h5c++.in +++ b/c++/src/h5c++.in @@ -35,10 +35,10 @@ HL="@HL@" ## (Advanced usage - know what you're doing - you're on your own here.) ## ## The four variables below can be used to insert paths and flags in ## ## CPPFLAGS, CXXFLAGS, LDFLAGS, or LIBS in the h5cc compile line: ## -## $CLINKER $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CXXFLAGS $CXXFLAGS ## +## $CXXLINKER $H5BLD_CPPFLAGS $CPPFLAGS $H5BLD_CXXFLAGS $CXXFLAGS ## ## $LDFLAGS $LIBS $clibpath $link_objs $link_args $shared_link ## ## ## -## These settings can be overridden by setting HDF5_CXXFLAGS, ## +## These settings can be overridden by setting HDF5_CXXFLAGS, ## ## HDF5_CPPFLAGS, HDF5_LDFLAGS, or HDF5_LIBS in the environment. ## ## ## ############################################################################ @@ -93,7 +93,7 @@ H5BLD_LDFLAGS="@AM_LDFLAGS@ @LDFLAGS@" H5BLD_LIBS="@LIBS@" CXX="${HDF5_CXX:-$CXXBASE}" -CXXLINKER="${HDF5_CLINKER:-$CXXLINKERBASE}" +CXXLINKER="${HDF5_CXXLINKER:-$CXXLINKERBASE}" CXXFLAGS="${HDF5_CXXFLAGS:-$CXXFLAGSBASE}" CPPFLAGS="${HDF5_CPPFLAGS:-$CPPFLAGSBASE}" LDFLAGS="${HDF5_LDFLAGS:-$LDFLAGSBASE}" diff --git a/c++/test/tattr.cpp b/c++/test/tattr.cpp index 35db334..26699d2 100644 --- a/c++/test/tattr.cpp +++ b/c++/test/tattr.cpp @@ -285,7 +285,7 @@ test_attr_getname() // Check for existence of attribute FATTR1_NAME bool attr_exists = fid1.attrExists(FATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); // Open attribute @@ -361,7 +361,7 @@ test_attr_getname() // Check for existence of attribute attr_exists = dataset.attrExists(ATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); // Open attribute @@ -410,7 +410,7 @@ test_attr_rename() // Check for existence of attribute bool attr_exists = fid1.attrExists(FATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); // Change attribute name @@ -436,7 +436,7 @@ test_attr_rename() // Check for existence of attribute attr_exists = dataset.attrExists(ATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); // Change attribute name @@ -464,7 +464,7 @@ test_attr_rename() // Check for existence of second attribute attr_exists = dataset.attrExists(ATTR2_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); // Open the second attribute @@ -492,7 +492,7 @@ test_attr_rename() // Check for existence of attribute after renaming attr_exists = dataset.attrExists(ATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "Attribute should exist but does not"); PASSED(); @@ -1681,13 +1681,13 @@ test_attr_exists() // Check for existence of attribute bool attr_exists = fid1.attrExists(ATTR1_FL_STR_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "fid1, ATTR1_FL_STR_NAMEAttribute should exist but does not"); // Check for existence of attribute attr_exists = fid1.attrExists(FATTR1_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "fid1,FATTR2_NAMEAttribute should exist but does not"); @@ -1696,7 +1696,7 @@ test_attr_exists() // Check for existence of attribute attr_exists = group.attrExists(ATTR2_NAME); - if (attr_exists == false) + if (!attr_exists) throw InvalidActionException("H5File::attrExists", "group, ATTR2_NAMEAttribute should exist but does not"); diff --git a/c++/test/ttypes.cpp b/c++/test/ttypes.cpp index 1cedef6..69c93d1 100644 --- a/c++/test/ttypes.cpp +++ b/c++/test/ttypes.cpp @@ -699,7 +699,7 @@ test_named() } // Check that it is committed. - if (itype.committed() == false) + if (!itype.committed()) cerr << "IntType::committed() returned false" << endl; // We should not be able to modify a type after it has been committed. diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index 7baf77b..263cedf 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -149,7 +149,7 @@ if (NOT WINDOWS) OUTPUT_VARIABLE OUTPUT ) if (TEST_DIRECT_VFD_WORKS_COMPILE) - if (TEST_DIRECT_VFD_WORKS_RUN MATCHES 0) + if (TEST_DIRECT_VFD_WORKS_RUN EQUAL "0") HDF_FUNCTION_TEST (HAVE_DIRECT) set (CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_GNU_SOURCE") add_definitions ("-D_GNU_SOURCE") @@ -259,9 +259,9 @@ macro (C_RUN FUNCTION_NAME SOURCE_CODE RETURN_VAR) message (VERBOSE "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ") endif () - if (${COMPILE_RESULT_VAR}) - if (${RUN_RESULT_VAR} MATCHES 0) - set (${RUN_RESULT_VAR} 1 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") + if (COMPILE_RESULT_VAR) + if (RUN_RESULT_VAR EQUAL "0") + set (${RETURN_VAR} 1 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") message (VERBOSE "Testing C ${FUNCTION_NAME} - OK") endif () @@ -273,7 +273,7 @@ macro (C_RUN FUNCTION_NAME SOURCE_CODE RETURN_VAR) if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") message (VERBOSE "Testing C ${FUNCTION_NAME} - Fail") endif () - set (${RUN_RESULT_VAR} 0 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") + set (${RETURN_VAR} 0 CACHE INTERNAL "Have C function ${FUNCTION_NAME}") file (APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Determining if the C ${FUNCTION_NAME} exists failed with the following output:\n" "${OUTPUT_VAR}\n\n") @@ -318,7 +318,7 @@ message (STATUS "Testing maximum decimal precision for C - ${PROG_OUTPUT4}") list (GET PROG_OUTPUT4 0 H5_LDBL_DIG) list (GET PROG_OUTPUT4 1 H5_FLT128_DIG) -if (${HDF_PREFIX}_SIZEOF___FLOAT128 EQUAL 0 OR FLT128_DIG EQUAL 0) +if (${HDF_PREFIX}_SIZEOF___FLOAT128 EQUAL "0" OR FLT128_DIG EQUAL "0") set (${HDF_PREFIX}_HAVE_FLOAT128 0) set (${HDF_PREFIX}_SIZEOF___FLOAT128 0) set (_PAC_C_MAX_REAL_PRECISION ${H5_LDBL_DIG}) @@ -344,7 +344,7 @@ macro (H5ConversionTests TEST msg) OUTPUT_VARIABLE OUTPUT ) if (${TEST}_COMPILE) - if (${TEST}_RUN MATCHES 0) + if (${TEST}_RUN EQUAL "0") set (${TEST} 1 CACHE INTERNAL ${msg}) if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") message (VERBOSE "${msg}... yes") diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index 740a0cf..8fd1331 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -271,6 +271,9 @@ /* Define to 1 if you have the header file. */ #cmakedefine H5_HAVE_PTHREAD_H @H5_HAVE_PTHREAD_H@ +/* Define to 1 if you have the header file. */ +#cmakedefine H5_HAVE_PWD_H @H5_HAVE_PWD_H@ + /* Define to 1 if you have the header file. */ #cmakedefine H5_HAVE_QUADMATH_H @H5_HAVE_QUADMATH_H@ @@ -637,6 +640,12 @@ PTHREAD_SCOPE_SYSTEM) call. */ #cmakedefine H5_SYSTEM_SCOPE_THREADS @H5_SYSTEM_SCOPE_THREADS@ +/* Define using v1.6 public API symbols by default */ +#cmakedefine H5_USE_16_API_DEFAULT @H5_USE_16_API_DEFAULT@ + +/* Define using v1.8 public API symbols by default */ +#cmakedefine H5_USE_18_API_DEFAULT @H5_USE_18_API_DEFAULT@ + /* Define using v1.10 public API symbols by default */ #cmakedefine H5_USE_110_API_DEFAULT @H5_USE_110_API_DEFAULT@ @@ -646,12 +655,6 @@ /* Define using v1.14 public API symbols by default */ #cmakedefine H5_USE_114_API_DEFAULT @H5_USE_114_API_DEFAULT@ -/* Define using v1.6 public API symbols by default */ -#cmakedefine H5_USE_16_API_DEFAULT @H5_USE_16_API_DEFAULT@ - -/* Define using v1.8 public API symbols by default */ -#cmakedefine H5_USE_18_API_DEFAULT @H5_USE_18_API_DEFAULT@ - /* Define if the library will use file locking */ #cmakedefine H5_USE_FILE_LOCKING @H5_USE_FILE_LOCKING@ diff --git a/config/cmake/HDF5_Examples.cmake.in b/config/cmake/HDF5_Examples.cmake.in index 3eea743..2d8dc58 100644 --- a/config/cmake/HDF5_Examples.cmake.in +++ b/config/cmake/HDF5_Examples.cmake.in @@ -77,7 +77,7 @@ set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DSITE:STRING=${CTEST_SITE} -DBUILDN #TAR_SOURCE - name of tarfile #if(NOT DEFINED TAR_SOURCE) -# set(CTEST_USE_TAR_SOURCE "HDF5Examples-1.14.1-Source") +# set(CTEST_USE_TAR_SOURCE "HDF5Examples-1.14.4-Source") #endif() ############################################################################################################### diff --git a/config/cmake/HDF5_Examples_options.cmake b/config/cmake/HDF5_Examples_options.cmake index b639b19..cdd49eb 100644 --- a/config/cmake/HDF5_Examples_options.cmake +++ b/config/cmake/HDF5_Examples_options.cmake @@ -42,19 +42,24 @@ ### enable JAVA builds #set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF_BUILD_JAVA:BOOL=ON") +############################################################################################# ### enable FILTERS builds #set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF_BUILD_FILTERS:BOOL=ON") +### default HDF5_PLUGIN_PATH to where the filter libraries are located +#set(ENV{HDF5_PLUGIN_PATH} "${INSTALLDIR}/lib/plugin") ############################################################################################# ### enable parallel program builds #set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF_ENABLE_PARALLEL:BOOL=ON") +############################################################################################# +### match the hdf5 library namespace +set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF5_NAMESPACE:STRING=hdf5::") ############################################################################################# ### enable threadsafe program builds #set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF_ENABLE_THREADSAFE:BOOL=ON") - ############################################################################################# ### enable test program builds, requires reference files in testfiles subdirectory #set(ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DBUILD_TESTING:BOOL=ON") diff --git a/config/cmake/HDFCXXCompilerFlags.cmake b/config/cmake/HDFCXXCompilerFlags.cmake index bd14a0d..a121d0a 100644 --- a/config/cmake/HDFCXXCompilerFlags.cmake +++ b/config/cmake/HDFCXXCompilerFlags.cmake @@ -9,17 +9,49 @@ # If you do not have access to either file, you may request a copy from # help@hdfgroup.org. # -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED TRUE) -set(CMAKE_CXX_EXTENSIONS OFF) +ENABLE_LANGUAGE (CXX) + +set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD_REQUIRED TRUE) + +set (CMAKE_CXX_EXTENSIONS OFF) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_SANITIZER_FLAGS} ${CMAKE_CXX_FLAGS}") if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "Warnings Configuration: CXX default: ${CMAKE_CXX_FLAGS}") + message (VERBOSE "Warnings Configuration: CXX default: ${CMAKE_CXX_FLAGS}") endif () #----------------------------------------------------------------------------- # Compiler specific flags : Shouldn't there be compiler tests for these #----------------------------------------------------------------------------- +if (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + set (_INTEL_WINDOWS 1) +endif () + +if (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") + set (_CLANG_MSVC_WINDOWS 1) +endif() + +# MSVC 14.28 enables C5105, but the Windows SDK 10.0.18362.0 triggers it. +if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND CMAKE_CXX_COMPILER_LOADED) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc") + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.28) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd5105") + endif () +endif () + +if (CMAKE_CXX_COMPILER_ID STREQUAL SunPro AND CMAKE_CXX_COMPILER_LOADED) + if (NOT DEFINED CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13) + if (NOT CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD EQUAL 98) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03") + endif () + else () + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4") + endif () + endif () +endif () + if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_LOADED) set (CMAKE_CXX_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_CXX_FLAGS}") if (${HDF_CFG_NAME} MATCHES "Debug") @@ -71,163 +103,167 @@ endif () # HDF5 library compile options #----------------------------------------------------------------------------- -if (NOT MSVC AND NOT MINGW) - if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") - list (APPEND HDF5_CMAKE_CXX_FLAGS "-erroff=%none -DBSD_COMP") - else () - # General flags - # - # Note that some of the flags listed here really should be developer - # flags (listed in a separate variable, below) but we put them here - # because they are not raised by the current code and we'd like to - # know if they do start showing up. - # - # NOTE: Don't add -Wpadded here since we can't/won't fix the (many) - # warnings that are emitted. If you need it, add it at configure time. - if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") +if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + list (APPEND HDF5_CMAKE_CXX_FLAGS "-erroff=%none -DBSD_COMP") +else () + # General flags + # + # Note that some of the flags listed here really should be developer + # flags (listed in a separate variable, below) but we put them here + # because they are not raised by the current code and we'd like to + # know if they do start showing up. + # + # NOTE: Don't add -Wpadded here since we can't/won't fix the (many) + # warnings that are emitted. If you need it, add it at configure time. + if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + if (_INTEL_WINDOWS) + ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/win-general") + else () ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/general") + endif() + if (NOT _INTEL_WINDOWS) if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15.0) ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/15") endif() if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0) ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/18") endif() - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_LOADED - AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - # add the general CXX flags for g++ compiler versions 4.8 and above. - ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-general") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-general") - else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-noerror-general") - endif () + endif() + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_LOADED + AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + # add the general CXX flags for g++ compiler versions 4.8 and above. + ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-general") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-general") + else () + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-noerror-general") endif () - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/general") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "PGI") - list (APPEND HDF5_CMAKE_CXX_FLAGS "-Minform=inform") - endif () - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "CMAKE_CXX_FLAGS_GENERAL=${HDF5_CMAKE_CXX_FLAGS}") endif () + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + ADD_H5_FLAGS (HDF5_CMAKE_CXX_FLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/general") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "PGI") + list (APPEND HDF5_CMAKE_CXX_FLAGS "-Minform=inform") endif () - - #----------------------------------------------------------------------------- - # Option to allow the user to enable developer warnings - # Developer warnings (suggestions from gcc, not code problems) - #----------------------------------------------------------------------------- - if (HDF5_ENABLE_DEV_WARNINGS) - message (STATUS "....HDF5 developer group warnings are enabled") - if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/developer-general") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-general") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/developer-general") - endif () - else () - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-general") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/no-developer-general") - endif () + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") + message (VERBOSE "CMAKE_CXX_FLAGS_GENERAL=${HDF5_CMAKE_CXX_FLAGS}") endif () +endif () +#----------------------------------------------------------------------------- +# Option to allow the user to enable developer warnings +# Developer warnings (suggestions from gcc, not code problems) +#----------------------------------------------------------------------------- +if (HDF5_ENABLE_DEV_WARNINGS) + message (STATUS "....HDF5 developer group warnings are enabled") + if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/developer-general") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-general") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/developer-general") + endif () +else () if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - # Technically, variable-length arrays are part of the C99 standard, but - # we should approach them a bit cautiously... Only needed for gcc 4.X - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0 AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8-4.last") - endif () + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-general") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/no-developer-general") + endif () +endif () - # Append more extra warning flags that only gcc 4.8+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-4.8") - if (HDF5_ENABLE_DEV_WARNINGS) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-4.8") - else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-4.8") - endif () - endif () +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # Technically, variable-length arrays are part of the C99 standard, but + # we should approach them a bit cautiously... Only needed for gcc 4.X + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0 AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8-4.last") + endif () - # Append more extra warning flags that only gcc 4.9+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) + # Append more extra warning flags that only gcc 4.8+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-4.8") + if (HDF5_ENABLE_DEV_WARNINGS) # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-4.9") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-4.8") + else () + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-4.8") endif () + endif () - # Append more extra warning flags that only gcc 5.1+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) - # autotools always add the C flags with the CXX flags - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-5") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-5") - else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-noerror-5") - endif () - endif () + # Append more extra warning flags that only gcc 4.9+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-4.9") + endif () - # Append more extra warning flags that only gcc 6.x+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/6") + # Append more extra warning flags that only gcc 5.1+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) + # autotools always add the C flags with the CXX flags + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-5") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-error-5") + else () + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-noerror-5") endif () + endif () - # Append more extra warning flags that only gcc 7.x+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXxFLAGS2 "${HDF5_SOURCE_DIR}/config/gnu-warnings/7") - if (HDF5_ENABLE_DEV_WARNINGS) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-7") - #else () - # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-7") - endif () - endif () + # Append more extra warning flags that only gcc 6.x+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/6") + endif () - # Append more extra warning flags that only gcc 8.x+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/8") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") - else () - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/noerror-8") - endif () - if (HDF5_ENABLE_DEV_WARNINGS) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-8") - else () - # autotools always add the C flags with the CXX flags - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-8") - endif () + # Append more extra warning flags that only gcc 7.x+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXxFLAGS2 "${HDF5_SOURCE_DIR}/config/gnu-warnings/7") + if (HDF5_ENABLE_DEV_WARNINGS) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-7") + #else () + # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-7") endif () + endif () - # Append more extra warning flags that only gcc 9.x+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) + # Append more extra warning flags that only gcc 8.x+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/8") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") + else () + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/noerror-8") + endif () + if (HDF5_ENABLE_DEV_WARNINGS) # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-9") + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-8") + else () + # autotools always add the C flags with the CXX flags + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-8") endif () + endif () - # Append more extra warning flags that only gcc 9.3+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.3) - # do not use C warnings, gnu-warnings 9.3, no cxx warniings - # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9.3") - endif () + # Append more extra warning flags that only gcc 9.x+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/cxx-9") + endif () - # Append more extra warning flags that only gcc 10.x+ knows about - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0) - if (HDF5_ENABLE_DEV_WARNINGS) - # Use the C warnings as CXX warnings are the same - ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-10") - #else () - # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-10") - endif () + # Append more extra warning flags that only gcc 9.3+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.3) + # do not use C warnings, gnu-warnings 9.3, no cxx warniings + # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9.3") + endif () + + # Append more extra warning flags that only gcc 10.x+ knows about + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0) + if (HDF5_ENABLE_DEV_WARNINGS) + # Use the C warnings as CXX warnings are the same + ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-10") + #else () + # ADD_H5_FLAGS (H5_CXXFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-10") endif () endif () endif () @@ -269,17 +305,17 @@ endif () # This option will force/override the default setting for all configurations #----------------------------------------------------------------------------- if (HDF5_ENABLE_SYMBOLS MATCHES "YES") - if(CMAKE_CXX_COMPILER_LOADED) - if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + if (CMAKE_CXX_COMPILER_LOADED) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel" AND NOT _INTEL_WINDOWS) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") endif () endif () elseif (HDF5_ENABLE_SYMBOLS MATCHES "NO") - if(CMAKE_CXX_COMPILER_LOADED) - if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") - set (CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wl,-s") + if (CMAKE_CXX_COMPILER_LOADED) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel" AND NOT _INTEL_WINDOWS) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-s") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s") endif () @@ -291,7 +327,7 @@ endif () # This option will force/override the default setting for all configurations #----------------------------------------------------------------------------- if (HDF5_ENABLE_PROFILING) - if(CMAKE_CXX_COMPILER_LOADED) + if (CMAKE_CXX_COMPILER_LOADED) list (APPEND HDF5_CMAKE_CXX_FLAGS "${PROFILE_CXXFLAGS}") endif () endif () @@ -301,7 +337,7 @@ endif () # This option will force/override the default setting for all configurations #----------------------------------------------------------------------------- if (HDF5_ENABLE_OPTIMIZATION) - if(CMAKE_CXX_COMPILER_LOADED) + if (CMAKE_CXX_COMPILER_LOADED) list (APPEND HDF5_CMAKE_CXX_FLAGS "${OPTIMIZE_CXXFLAGS}") endif () endif () diff --git a/config/cmake/HDFCompilerFlags.cmake b/config/cmake/HDFCompilerFlags.cmake index e38a92b..de5b563 100644 --- a/config/cmake/HDFCompilerFlags.cmake +++ b/config/cmake/HDFCompilerFlags.cmake @@ -14,14 +14,43 @@ set(CMAKE_C_STANDARD_REQUIRED TRUE) set (CMAKE_C_FLAGS "${CMAKE_C99_STANDARD_COMPILE_OPTION} ${CMAKE_C_FLAGS}") set (CMAKE_C_FLAGS "${CMAKE_C_SANITIZER_FLAGS} ${CMAKE_C_FLAGS}") -set (CMAKE_CXX_FLAGS "${CMAKE_CXX_SANITIZER_FLAGS} ${CMAKE_CXX_FLAGS}") - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "Warnings Configuration: default: ${CMAKE_C_FLAGS} : ${CMAKE_CXX_FLAGS}") + message (VERBOSE "Warnings Configuration: C default: ${CMAKE_C_FLAGS}") endif () #----------------------------------------------------------------------------- # Compiler specific flags : Shouldn't there be compiler tests for these #----------------------------------------------------------------------------- +if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Intel") + set(_INTEL_WINDOWS 1) +endif() + +if(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "Clang" + AND "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") + set(_CLANG_MSVC_WINDOWS 1) +endif() + +# Disable deprecation warnings for standard C functions. +# really only needed for newer versions of VS, but should +# not hurt other versions, and this will work into the +# future +if(MSVC OR _INTEL_WINDOWS OR _CLANG_MSVC_WINDOWS) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE) +else() +endif() + +if(MSVC) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stack:10000000") +endif() + +# MSVC 14.28 enables C5105, but the Windows SDK 10.0.18362.0 triggers it. +if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 19.28) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -wd5105") +endif() + +if(_CLANG_MSVC_WINDOWS AND "x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Xlinker -stack:20000000") +endif() + if (CMAKE_COMPILER_IS_GNUCC) set (CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}") if (${HDF_CFG_NAME} MATCHES "Debug") @@ -81,33 +110,37 @@ endif () # HDF5 library compile options #----------------------------------------------------------------------------- -if (NOT MSVC AND NOT MINGW) - #----------------------------------------------------------------------------- - # Option to allow the user to interpret certain warnings as errors - # - # This should NOT be on by default as it can cause a lot of conflicts with - # new operating systems and compiler versions. Header files that are out of - # our control (MPI, HDFS, etc.) can also raise warnings. - #----------------------------------------------------------------------------- - option (HDF5_ENABLE_WARNINGS_AS_ERRORS "Interpret some warnings as errors" OFF) - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - message (STATUS "...some warnings will be interpreted as errors") - endif () +#----------------------------------------------------------------------------- +# Option to allow the user to interpret certain warnings as errors +# +# This should NOT be on by default as it can cause a lot of conflicts with +# new operating systems and compiler versions. Header files that are out of +# our control (MPI, HDFS, etc.) can also raise warnings. +#----------------------------------------------------------------------------- +option (HDF5_ENABLE_WARNINGS_AS_ERRORS "Interpret some warnings as errors" OFF) +if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + message (STATUS "...some warnings will be interpreted as errors") +endif () - if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") - list (APPEND HDF5_CMAKE_C_FLAGS "-erroff=%none -DBSD_COMP") - else () - # General flags - # - # Note that some of the flags listed here really should be developer - # flags (listed in a separate variable, below) but we put them here - # because they are not raised by the current code and we'd like to - # know if they do start showing up. - # - # NOTE: Don't add -Wpadded here since we can't/won't fix the (many) - # warnings that are emitted. If you need it, add it at configure time. - if (CMAKE_C_COMPILER_ID STREQUAL "Intel") +if (${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + list (APPEND HDF5_CMAKE_C_FLAGS "-erroff=%none -DBSD_COMP") +else () + # General flags + # + # Note that some of the flags listed here really should be developer + # flags (listed in a separate variable, below) but we put them here + # because they are not raised by the current code and we'd like to + # know if they do start showing up. + # + # NOTE: Don't add -Wpadded here since we can't/won't fix the (many) + # warnings that are emitted. If you need it, add it at configure time. + if (CMAKE_C_COMPILER_ID STREQUAL "Intel") + if (_INTEL_WINDOWS) + ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/win-general") + else () ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/general") + endif() + if (NOT _INTEL_WINDOWS) if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 15.0) ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/15") endif() @@ -116,133 +149,137 @@ if (NOT MSVC AND NOT MINGW) if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 18.0) ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/18") endif() - elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") - # Add general CFlags for GCC versions 4.8 and above - if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/general") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-general") - else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/noerror-general") - endif () - endif () - # gcc automatically inlines based on the optimization level - # this is just a failsafe - list (APPEND H5_CFLAGS "-finline-functions") - elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") - ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/general") + endif() + elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") + # Add general CFlags for GCC versions 4.8 and above + if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/general") if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/error-general") + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-general") else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/noerror-general") + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/noerror-general") endif () - elseif (CMAKE_C_COMPILER_ID STREQUAL "PGI") - list (APPEND HDF5_CMAKE_C_FLAGS "-Minform=inform") endif () - if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") - message (VERBOSE "CMAKE_C_FLAGS_GENERAL=${HDF5_CMAKE_C_FLAGS}") + # gcc automatically inlines based on the optimization level + # this is just a failsafe + list (APPEND H5_CFLAGS "-finline-functions") + elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") + ADD_H5_FLAGS (HDF5_CMAKE_C_FLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/general") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/error-general") + else () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/noerror-general") endif () + elseif (CMAKE_C_COMPILER_ID STREQUAL "PGI") + list (APPEND HDF5_CMAKE_C_FLAGS "-Minform=inform") endif () + if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15.0") + message (VERBOSE "CMAKE_C_FLAGS_GENERAL=${HDF5_CMAKE_C_FLAGS}") + endif () +endif () - #----------------------------------------------------------------------------- - # Option to allow the user to enable developer warnings - # Developer warnings (suggestions from gcc, not code problems) - #----------------------------------------------------------------------------- - option (HDF5_ENABLE_DEV_WARNINGS "Enable HDF5 developer group warnings" OFF) - if (HDF5_ENABLE_DEV_WARNINGS) - message (STATUS "....HDF5 developer group warnings are enabled") - if (CMAKE_C_COMPILER_ID STREQUAL "Intel") +#----------------------------------------------------------------------------- +# Option to allow the user to enable developer warnings +# Developer warnings (suggestions from gcc, not code problems) +#----------------------------------------------------------------------------- +option (HDF5_ENABLE_DEV_WARNINGS "Enable HDF5 developer group warnings" OFF) +if (HDF5_ENABLE_DEV_WARNINGS) + message (STATUS "....HDF5 developer group warnings are enabled") + if (CMAKE_C_COMPILER_ID STREQUAL "Intel") + if (_INTEL_WINDOWS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/win-developer-general") + else () ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/intel-warnings/developer-general") - elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-general") - elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/developer-general") - endif () - else () - if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-general") - elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/no-developer-general") endif () + elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-general") + elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/developer-general") endif () +else () + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-general") + elseif (CMAKE_C_COMPILER_ID MATCHES "[Cc]lang") + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/clang-warnings/no-developer-general") + endif () +endif () - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - # Technically, variable-length arrays are part of the C99 standard, but - # we should approach them a bit cautiously... Only needed for gcc 4.X - if (CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0 AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8-4.last") - endif () +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + # Technically, variable-length arrays are part of the C99 standard, but + # we should approach them a bit cautiously... Only needed for gcc 4.X + if (CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0 AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8-4.last") + endif () - # Append more extra warning flags that only gcc 4.8+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8") - if (HDF5_ENABLE_DEV_WARNINGS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-4.8") - else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-4.8") - endif () + # Append more extra warning flags that only gcc 4.8+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.8") + if (HDF5_ENABLE_DEV_WARNINGS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-4.8") + else () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-4.8") endif () + endif () - # Append more extra warning flags that only gcc 4.9+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.9") - endif () + # Append more extra warning flags that only gcc 4.9+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/4.9") + endif () - # Append more extra warning flags that only gcc 5.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/5") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-5") - else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-5") - endif () + # Append more extra warning flags that only gcc 5.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/5") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-5") + else () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-5") endif () + endif () - # Append more extra warning flags that only gcc 6.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/6") - endif () + # Append more extra warning flags that only gcc 6.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/6") + endif () - # Append more extra warning flags that only gcc 7.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/7") - if (HDF5_ENABLE_DEV_WARNINGS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-7") - #else () - # ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-7") - endif () + # Append more extra warning flags that only gcc 7.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/7") + if (HDF5_ENABLE_DEV_WARNINGS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-7") + #else () + # ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-7") endif () + endif () - # Append more extra warning flags that only gcc 8.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/8") - if (HDF5_ENABLE_WARNINGS_AS_ERRORS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") - endif () - if (HDF5_ENABLE_DEV_WARNINGS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-8") - else () - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-8") - endif () + # Append more extra warning flags that only gcc 8.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/8") + if (HDF5_ENABLE_WARNINGS_AS_ERRORS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/error-8") endif () - - # Append more extra warning flags that only gcc 9.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9") + if (HDF5_ENABLE_DEV_WARNINGS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-8") + else () + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-8") endif () + endif () - # Append more extra warning flags that only gcc 9.3+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.3) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9.3") - endif () + # Append more extra warning flags that only gcc 9.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9") + endif () - # Append more extra warning flags that only gcc 10.x+ knows about - if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) - if (HDF5_ENABLE_DEV_WARNINGS) - ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-10") - #else () - # ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-10") - endif () + # Append more extra warning flags that only gcc 9.3+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.3) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/9.3") + endif () + + # Append more extra warning flags that only gcc 10.x+ knows about + if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.0) + if (HDF5_ENABLE_DEV_WARNINGS) + ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/developer-10") + #else () + # ADD_H5_FLAGS (H5_CFLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/no-developer-10") endif () endif () endif () @@ -297,13 +334,13 @@ MARK_AS_ADVANCED (HDF5_ENABLE_ASSERTS) set (HDF5_ENABLE_SYMBOLS "OFF" CACHE STRING "Add debug symbols to the library independent of the build mode and optimization level (OFF NO YES)") set_property (CACHE HDF5_ENABLE_SYMBOLS PROPERTY STRINGS OFF NO YES) if (HDF5_ENABLE_SYMBOLS MATCHES "YES") - if (CMAKE_C_COMPILER_ID STREQUAL "Intel") + if (CMAKE_C_COMPILER_ID STREQUAL "Intel" AND NOT _INTEL_WINDOWS) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g") elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -fno-omit-frame-pointer") endif () elseif (HDF5_ENABLE_SYMBOLS MATCHES "NO") - if (CMAKE_C_COMPILER_ID STREQUAL "Intel") + if (CMAKE_C_COMPILER_ID STREQUAL "Intel" AND NOT _INTEL_WINDOWS) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-s") elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s") diff --git a/config/cmake/HDFFortranCompilerFlags.cmake b/config/cmake/HDFFortranCompilerFlags.cmake index 18ab621..94c40aa 100644 --- a/config/cmake/HDFFortranCompilerFlags.cmake +++ b/config/cmake/HDFFortranCompilerFlags.cmake @@ -91,9 +91,10 @@ if (NOT MSVC AND NOT MINGW) #endif () # Append more extra warning flags that only gcc 5.x+ knows about - if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 5.0) - ADD_H5_FLAGS (HDF5_CMAKE_Fortran_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/gfort-5") - endif () + # do not include -Wuse-without-only + #if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 5.0) + # ADD_H5_FLAGS (HDF5_CMAKE_Fortran_FLAGS "${HDF5_SOURCE_DIR}/config/gnu-warnings/gfort-5") + #endif () # Append more extra warning flags that only gcc 6.x+ knows about if (NOT CMAKE_Fortran_COMPILER_VERSION VERSION_LESS 6.0) diff --git a/config/cmake/README.txt.cmake.in b/config/cmake/README.txt.cmake.in index f621515..9289870 100644 --- a/config/cmake/README.txt.cmake.in +++ b/config/cmake/README.txt.cmake.in @@ -75,6 +75,6 @@ For more information see USING_CMake_Examples.txt in the install folder. =========================================================================== Documentation for this release can be found at the following URL: - https://portal.hdfgroup.org/display/support + https://portal.hdfgroup.org/display/HDF5/HDF5 Bugs should be reported to help@hdfgroup.org. diff --git a/config/cmake/UseJava.cmake b/config/cmake/UseJava.cmake index 375004e..2351ce8 100644 --- a/config/cmake/UseJava.cmake +++ b/config/cmake/UseJava.cmake @@ -4,369 +4,516 @@ UseJava ------- -Use Module for Java - -This file provides functions for Java. It is assumed that +This file provides support for ``Java``. It is assumed that :module:`FindJava` has already been loaded. See :module:`FindJava` for -information on how to load Java into your CMake project. +information on how to load Java into your ``CMake`` project. + +Synopsis +^^^^^^^^ + +.. parsed-literal:: + + `Creating and Installing JARS`_ + `add_jar`_ ( [SOURCES] [...] ...) + `install_jar`_ ( DESTINATION [COMPONENT ]) + `install_jni_symlink`_ ( DESTINATION [COMPONENT ]) + + `Header Generation`_ + `create_javah`_ ((TARGET | GENERATED_FILES ) CLASSES ... ...) + + `Exporting JAR Targets`_ + `install_jar_exports`_ (TARGETS ... FILE DESTINATION ...) + `export_jars`_ (TARGETS ... [NAMESPACE ] FILE ) + + `Finding JARs`_ + `find_jar`_ ( NAMES [...] [PATHS [... ENV ]] ...) + + `Creating Java Documentation`_ + `create_javadoc`_ ( (PACKAGES [...] | FILES [...]) ...) Creating And Installing JARs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. code-block:: cmake +.. _add_jar: - add_jar( - [SOURCES] [...] [...] - [INCLUDE_JARS [...]] - [ENTRY_POINT ] - [VERSION ] - [OUTPUT_NAME ] - [OUTPUT_DIR ] - [GENERATE_NATIVE_HEADERS [DESTINATION ]] - ) +.. command:: add_jar -This command creates a ``.jar``. It compiles the given -```` files and adds the given ```` files to -the jar file. Source files can be java files or listing files -(prefixed by ``@``). If only resource files are given then just a jar file -is created. The list of ``INCLUDE_JARS`` are added to the classpath when -compiling the java sources and also to the dependencies of the target. -``INCLUDE_JARS`` also accepts other target names created by ``add_jar()``. -For backwards compatibility, jar files listed as sources are ignored (as -they have been since the first version of this module). + Creates a jar file containing java objects and, optionally, resources:: -The default ``OUTPUT_DIR`` can also be changed by setting the variable -``CMAKE_JAVA_TARGET_OUTPUT_DIR``. + add_jar( + [SOURCES] [...] [...] + [INCLUDE_JARS [...]] + [ENTRY_POINT ] + [VERSION ] + [MANIFEST ] + [OUTPUT_NAME ] + [OUTPUT_DIR ] + [GENERATE_NATIVE_HEADERS + [DESTINATION (|INSTALL [BUILD ])]] + ) -Optionally, using option ``GENERATE_NATIVE_HEADERS``, native header files can -be generated for methods declared as native. These files provide the -connective glue that allow your Java and C code to interact. An INTERFACE -target will be created for an easy usage of generated files. Sub-option -``DESTINATION`` can be used to specify the output directory for generated -header files. + This command creates a ``.jar``. It compiles the given + ```` files and adds the given ```` files to + the jar file. Source files can be java files or listing files + (prefixed by ``@``). If only resource files are given then just a jar file + is created. -``GENERATE_NATIVE_HEADERS`` option requires, at least, version 1.8 of the JDK. + ``SOURCES`` + Compiles the specified source files and adds the result in the jar file. -The ``add_jar()`` function sets the following target properties on -````: + .. versionadded:: 3.4 + Support for response files, prefixed by ``@``. -``INSTALL_FILES`` - The files which should be installed. This is used by ``install_jar()``. -``JNI_SYMLINK`` - The JNI symlink which should be installed. This is used by - ``install_jni_symlink()``. -``JAR_FILE`` - The location of the jar file so that you can include it. -``CLASSDIR`` - The directory where the class files can be found. For example to use them - with ``javah``. + ``INCLUDE_JARS`` + The list of jars are added to the classpath when compiling the java sources + and also to the dependencies of the target. ``INCLUDE_JARS`` also accepts + other target names created by ``add_jar()``. For backwards compatibility, + jar files listed as sources are ignored (as they have been since the first + version of this module). -.. code-block:: cmake + ``ENTRY_POINT`` + Defines an entry point in the jar file. - install_jar( ) - install_jar( DESTINATION [COMPONENT ]) + ``VERSION`` + Adds a version to the target output name. -This command installs the ```` files to the given -````. It should be called in the same scope as ``add_jar()`` or -it will fail. + The following example will create a jar file with the name + ``shibboleet-1.2.0.jar`` and will create a symlink ``shibboleet.jar`` + pointing to the jar with the version information. -The ``install_jar()`` function sets the ``INSTALL_DESTINATION`` target -property on jars so installed. This property holds the ```` as -described above, and is used by ``install_jar_exports()``. You can get this -information with :command:`get_property` and the ``INSTALL_DESTINATION`` -property key. + .. code-block:: cmake -.. code-block:: cmake + add_jar(shibboleet shibbotleet.java VERSION 1.2.0) - install_jni_symlink( ) - install_jni_symlink( DESTINATION [COMPONENT ]) + ``MANIFEST`` + Defines a custom manifest for the jar. -This command installs the ```` JNI symlinks to the given -````. It should be called in the same scope as ``add_jar()`` or -it will fail. + ``OUTPUT_NAME`` + Specify a different output name for the target. -.. code-block:: cmake + ``OUTPUT_DIR`` + Sets the directory where the jar file will be generated. If not specified, + :variable:`CMAKE_CURRENT_BINARY_DIR` is used as the output directory. - install_jar_exports(TARGETS ... - [NAMESPACE ] - FILE - DESTINATION [COMPONENT ]) + ``GENERATE_NATIVE_HEADERS`` + .. versionadded:: 3.11 -This command installs a target export file ```` for the named jar -targets to the given ```` directory. Its function is similar to -that of :command:`install(EXPORTS)`. + Generates native header files for methods declared as native. These files + provide the connective glue that allow your Java and C code to interact. + An INTERFACE target will be created for an easy usage of generated files. + Sub-option ``DESTINATION`` can be used to specify the output directory for + generated header files. -.. code-block:: cmake + This option requires, at least, version 1.8 of the JDK. - export_jars(TARGETS ... - [NAMESPACE ] - FILE ) + For an optimum usage of this option, it is recommended to include module + JNI before any call to ``add_jar()``. The produced target for native + headers can then be used to compile C/C++ sources with the + :command:`target_link_libraries` command. -This command writes a target export file ```` for the named ```` -targets. Its function is similar to that of :command:`export`. + .. code-block:: cmake + find_package(JNI) + add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native) + add_library(bar bar.cpp) + target_link_libraries(bar PRIVATE foo-native) -Examples -"""""""" + .. versionadded:: 3.20 + ``DESTINATION`` sub-option now supports the possibility to specify + different output directories for ``BUILD`` and ``INSTALL`` steps. If + ``BUILD`` directory is not specified, a default directory will be used. -To add compile flags to the target you can set these flags with the following -variable: + To export the interface target generated by ``GENERATE_NATIVE_HEADERS`` + option, sub-option ``INSTALL`` of ``DESTINATION`` is required: -.. code-block:: cmake + .. code-block:: cmake - set(CMAKE_JAVA_COMPILE_FLAGS -nowarn) + add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native + DESTINATION INSTALL include) + install(TARGETS foo-native EXPORT native) + install(DIRECTORY "$/" + DESTINATION include) + install(EXPORT native DESTINATION /to/export NAMESPACE foo) + Some variables can be set to customize the behavior of ``add_jar()`` as well + as the java compiler: -To add a path or a jar file to the class path you can do this with the -``CMAKE_JAVA_INCLUDE_PATH`` variable. + ``CMAKE_JAVA_COMPILE_FLAGS`` + Specify additional flags to java compiler. -.. code-block:: cmake + ``CMAKE_JAVA_INCLUDE_PATH`` + Specify additional paths to the class path. - set(CMAKE_JAVA_INCLUDE_PATH /usr/share/java/shibboleet.jar) + ``CMAKE_JNI_TARGET`` + If the target is a JNI library, sets this boolean variable to ``TRUE`` to + enable creation of a JNI symbolic link (see also + :ref:`install_jni_symlink() `). -To use a different output name for the target you can set it with: + ``CMAKE_JAR_CLASSES_PREFIX`` + If multiple jars should be produced from the same java source filetree, + to prevent the accumulation of duplicate class files in subsequent jars, + set/reset ``CMAKE_JAR_CLASSES_PREFIX`` prior to calling the ``add_jar()``: -.. code-block:: cmake + .. code-block:: cmake - add_jar(foobar foobar.java OUTPUT_NAME shibboleet.jar) + set(CMAKE_JAR_CLASSES_PREFIX com/redhat/foo) + add_jar(foo foo.java) -To use a different output directory than ``CMAKE_CURRENT_BINARY_DIR`` you can -set it with: + set(CMAKE_JAR_CLASSES_PREFIX com/redhat/bar) + add_jar(bar bar.java) -.. code-block:: cmake + The ``add_jar()`` function sets the following target properties on + ````: - add_jar(foobar foobar.java OUTPUT_DIR ${PROJECT_BINARY_DIR}/bin) + ``INSTALL_FILES`` + The files which should be installed. This is used by + :ref:`install_jar() `. + ``JNI_SYMLINK`` + The JNI symlink which should be installed. This is used by + :ref:`install_jni_symlink() `. + ``JAR_FILE`` + The location of the jar file so that you can include it. + ``CLASSDIR`` + The directory where the class files can be found. For example to use them + with ``javah``. + ``NATIVE_HEADERS_DIRECTORY`` + .. versionadded:: 3.20 -To define an entry point in your jar you can set it with the ``ENTRY_POINT`` -named argument: + The directory where native headers are generated. Defined when option + ``GENERATE_NATIVE_HEADERS`` is specified. -.. code-block:: cmake +.. _install_jar: - add_jar(example ENTRY_POINT com/examples/MyProject/Main) +.. command:: install_jar -To define a custom manifest for the jar, you can set it with the ``MANIFEST`` -named argument: + This command installs the jar file to the given destination:: -.. code-block:: cmake + install_jar( ) + install_jar( DESTINATION [COMPONENT ]) - add_jar(example MANIFEST /path/to/manifest) + This command installs the ```` file to the given + ````. It should be called in the same scope as + :ref:`add_jar() ` or it will fail. -To add a version to the target output name you can set it using the ``VERSION`` -named argument to ``add_jar()``. The following example will create a jar file -with the name ``shibboleet-1.0.0.jar`` and will create a symlink -``shibboleet.jar`` pointing to the jar with the version information. + .. versionadded:: 3.4 + The second signature with ``DESTINATION`` and ``COMPONENT`` options. -.. code-block:: cmake + ``DESTINATION`` + Specify the directory on disk to which a file will be installed. - add_jar(shibboleet shibbotleet.java VERSION 1.2.0) + ``COMPONENT`` + Specify an installation component name with which the install rule is + associated, such as "runtime" or "development". -If the target is a JNI library, utilize the following commands to -create a JNI symbolic link: + The ``install_jar()`` command sets the following target properties + on ````: -.. code-block:: cmake + ``INSTALL_DESTINATION`` + Holds the ```` as described above, and is used by + :ref:`install_jar_exports() `. - set(CMAKE_JNI_TARGET TRUE) - add_jar(shibboleet shibbotleet.java VERSION 1.2.0) - install_jar(shibboleet ${LIB_INSTALL_DIR}/shibboleet) - install_jni_symlink(shibboleet ${JAVA_LIB_INSTALL_DIR}) +.. _install_jni_symlink: -If a single target needs to produce more than one jar from its -java source code, to prevent the accumulation of duplicate class -files in subsequent jars, set/reset ``CMAKE_JAR_CLASSES_PREFIX`` prior -to calling the ``add_jar()`` function: +.. command:: install_jni_symlink -.. code-block:: cmake + Installs JNI symlinks for target generated by :ref:`add_jar() `:: - set(CMAKE_JAR_CLASSES_PREFIX com/redhat/foo) - add_jar(foo foo.java) + install_jni_symlink( ) + install_jni_symlink( DESTINATION [COMPONENT ]) - set(CMAKE_JAR_CLASSES_PREFIX com/redhat/bar) - add_jar(bar bar.java) + This command installs the ```` JNI symlinks to the given + ````. It should be called in the same scope as + :ref:`add_jar() ` or it will fail. -For an optimum usage of option ``GENERATE_NATIVE_HEADERS``, it is recommended to -include module JNI before any call to ``add_jar()``. The produced target for -native headers can then be used to compile C/C++ sources with the -:command:`target_link_libraries` command. + .. versionadded:: 3.4 + The second signature with ``DESTINATION`` and ``COMPONENT`` options. -.. code-block:: cmake + ``DESTINATION`` + Specify the directory on disk to which a file will be installed. - find_package(JNI) - add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native) - add_library(bar bar.cpp) - target_link_libraries(bar PRIVATE foo-native) + ``COMPONENT`` + Specify an installation component name with which the install rule is + associated, such as "runtime" or "development". + Utilize the following commands to create a JNI symbolic link: -Finding JARs -^^^^^^^^^^^^ + .. code-block:: cmake -.. code-block:: cmake - - find_jar( - | NAMES [...] - [PATHS [... ENV ]] - [VERSIONS []] - [DOC "cache documentation string"] - ) - -This command is used to find a full path to the named jar. A cache -entry named by ```` is created to store the result of this command. -If the full path to a jar is found the result is stored in the -variable and the search will not repeated unless the variable is -cleared. If nothing is found, the result will be ``-NOTFOUND``, and -the search will be attempted again next time ``find_jar()`` is invoked with -the same variable. The name of the full path to a file that is -searched for is specified by the names listed after ``NAMES`` argument. -Additional search locations can be specified after the ``PATHS`` argument. -If you require special a version of a jar file you can specify it with -the ``VERSIONS`` argument. The argument after ``DOC`` will be used for the -documentation string in the cache. - - -Javadoc -^^^^^^^ - -The ``create_javadoc()`` command can be used to create java documentation -based on files or packages. For more details please read the javadoc manpage. - -There are two main signatures for ``create_javadoc()``. The first signature -works with package names on a path with source files. - -.. code-block:: cmake - - create_javadoc( - PACKAGES [...] - [SOURCEPATH ] - [CLASSPATH ] - [INSTALLPATH ] - [DOCTITLE "the documentation title"] - [WINDOWTITLE "the title of the document"] - [AUTHOR TRUE|FALSE] - [USE TRUE|FALSE] - [VERSION TRUE|FALSE] - ) + set(CMAKE_JNI_TARGET TRUE) + add_jar(shibboleet shibbotleet.java VERSION 1.2.0) + install_jar(shibboleet ${LIB_INSTALL_DIR}/shibboleet) + install_jni_symlink(shibboleet ${JAVA_LIB_INSTALL_DIR}) + +Header Generation +^^^^^^^^^^^^^^^^^ + +.. _create_javah: + +.. command:: create_javah -For example: - -.. code-block:: cmake - - create_javadoc(my_example_doc - PACKAGES com.example.foo com.example.bar - SOURCEPATH "${CMAKE_CURRENT_SOURCE_DIR}" - CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH} - WINDOWTITLE "My example" - DOCTITLE "

My example

" - AUTHOR TRUE - USE TRUE - VERSION TRUE - ) - -The second signature for ``create_javadoc()`` works on a given list of -files. - -.. code-block:: cmake - - create_javadoc( - FILES [...] - [CLASSPATH ] - [INSTALLPATH ] - [DOCTITLE "the documentation title"] - [WINDOWTITLE "the title of the document"] - [AUTHOR TRUE|FALSE] - [USE TRUE|FALSE] - [VERSION TRUE|FALSE] + .. versionadded:: 3.4 + + Generates C header files for java classes:: + + create_javah(TARGET | GENERATED_FILES + CLASSES ... + [CLASSPATH ...] + [DEPENDS ...] + [OUTPUT_NAME |OUTPUT_DIR ] ) -For example: + .. deprecated:: 3.11 + This command will no longer be supported starting with version 10 of the JDK + due to the `suppression of javah tool `_. + The :ref:`add_jar(GENERATE_NATIVE_HEADERS) ` command should be + used instead. + + Create C header files from java classes. These files provide the connective + glue that allow your Java and C code to interact. + + There are two main signatures for ``create_javah()``. The first signature + returns generated files through variable specified by the ``GENERATED_FILES`` + option. For example: -.. code-block:: cmake + .. code-block:: cmake - create_javadoc(my_example_doc - FILES ${example_SRCS} - CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH} - WINDOWTITLE "My example" - DOCTITLE "

My example

" - AUTHOR TRUE - USE TRUE - VERSION TRUE - ) + create_javah(GENERATED_FILES files_headers + CLASSES org.cmake.HelloWorld + CLASSPATH hello.jar + ) -Both signatures share most of the options. These options are the same -as what you can find in the javadoc manpage. Please look at the -manpage for ``CLASSPATH``, ``DOCTITLE``, ``WINDOWTITLE``, ``AUTHOR``, ``USE`` -and ``VERSION``. + The second signature for ``create_javah()`` creates a target which + encapsulates header files generation. E.g. -If you don't set the ``INSTALLPATH``, then by default the documentation will -be installed to : + .. code-block:: cmake -:: + create_javah(TARGET target_headers + CLASSES org.cmake.HelloWorld + CLASSPATH hello.jar + ) - ${CMAKE_INSTALL_PREFIX}/share/javadoc/ + Both signatures share same options. + ``CLASSES`` + Specifies Java classes used to generate headers. -Header Generation -^^^^^^^^^^^^^^^^^ + ``CLASSPATH`` + Specifies various paths to look up classes. Here ``.class`` files, jar + files or targets created by command add_jar can be used. + + ``DEPENDS`` + Targets on which the javah target depends. + + ``OUTPUT_NAME`` + Concatenates the resulting header files for all the classes listed by + option ``CLASSES`` into ````. Same behavior as option ``-o`` of + ``javah`` tool. + + ``OUTPUT_DIR`` + Sets the directory where the header files will be generated. Same behavior + as option ``-d`` of ``javah`` tool. If not specified, + :variable:`CMAKE_CURRENT_BINARY_DIR` is used as the output directory. + +Exporting JAR Targets +^^^^^^^^^^^^^^^^^^^^^ + +.. _install_jar_exports: + +.. command:: install_jar_exports + + .. versionadded:: 3.7 + + Installs a target export file:: -.. code-block:: cmake + install_jar_exports(TARGETS ... + [NAMESPACE ] + FILE + DESTINATION [COMPONENT ]) - create_javah(TARGET | GENERATED_FILES - CLASSES ... - [CLASSPATH ...] - [DEPENDS ...] - [OUTPUT_NAME |OUTPUT_DIR ] - ) + This command installs a target export file ```` for the named jar + targets to the given ```` directory. Its function is similar to + that of :command:`install(EXPORT)`. -Create C header files from java classes. These files provide the connective glue -that allow your Java and C code to interact. + ``TARGETS`` + List of targets created by :ref:`add_jar() ` command. -.. deprecated:: 3.11 + ``NAMESPACE`` + .. versionadded:: 3.9 -.. note:: + The ```` value will be prepend to the target names as they are + written to the import file. - This command will no longer be supported starting with version 10 of the JDK - due to the `suppression of javah tool `_. - The ``add_jar(GENERATE_NATIVE_HEADERS)`` command should be used instead. + ``FILE`` + Specify name of the export file. -There are two main signatures for ``create_javah()``. The first signature -returns generated files through variable specified by the ``GENERATED_FILES`` -option. For example: -.. code-block:: cmake + ``DESTINATION`` + Specify the directory on disk to which a file will be installed. - create_javah(GENERATED_FILES files_headers - CLASSES org.cmake.HelloWorld - CLASSPATH hello.jar - ) + ``COMPONENT`` + Specify an installation component name with which the install rule is + associated, such as "runtime" or "development". -The second signature for ``create_javah()`` creates a target which encapsulates -header files generation. E.g. +.. _export_jars: -.. code-block:: cmake +.. command:: export_jars - create_javah(TARGET target_headers - CLASSES org.cmake.HelloWorld - CLASSPATH hello.jar - ) + .. versionadded:: 3.7 -Both signatures share same options. + Writes a target export file:: -``CLASSES ...`` - Specifies Java classes used to generate headers. + export_jars(TARGETS ... + [NAMESPACE ] + FILE ) -``CLASSPATH ...`` - Specifies various paths to look up classes. Here .class files, jar files or - targets created by command add_jar can be used. + This command writes a target export file ```` for the named ```` + targets. Its function is similar to that of :command:`export`. -``DEPENDS ...`` - Targets on which the javah target depends. + ``TARGETS`` + List of targets created by :ref:`add_jar() ` command. -``OUTPUT_NAME `` - Concatenates the resulting header files for all the classes listed by option - ``CLASSES`` into ````. Same behavior as option ``-o`` of javah tool. + ``NAMESPACE`` + .. versionadded:: 3.9 -``OUTPUT_DIR `` - Sets the directory where the header files will be generated. Same behavior - as option ``-d`` of javah tool. If not specified, - :variable:`CMAKE_CURRENT_BINARY_DIR` is used as the output directory. + The ```` value will be prepend to the target names as they are + written to the import file. + + ``FILE`` + Specify name of the export file. + +Finding JARs +^^^^^^^^^^^^ + +.. _find_jar: + +.. command:: find_jar + + Finds the specified jar file:: + + find_jar( + | NAMES [...] + [PATHS [... ENV ]] + [VERSIONS []] + [DOC "cache documentation string"] + ) + + This command is used to find a full path to the named jar. A cache + entry named by ```` is created to store the result of this command. + If the full path to a jar is found the result is stored in the + variable and the search will not repeated unless the variable is + cleared. If nothing is found, the result will be ``-NOTFOUND``, and + the search will be attempted again next time ``find_jar()`` is invoked with + the same variable. + + ``NAMES`` + Specify one or more possible names for the jar file. + + ``PATHS`` + Specify directories to search in addition to the default locations. + The ``ENV`` var sub-option reads paths from a system environment variable. + + ``VERSIONS`` + Specify jar versions. + + ``DOC`` + Specify the documentation string for the ```` cache entry. + +Creating Java Documentation +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _create_javadoc: + +.. command:: create_javadoc + + Creates java documentation based on files and packages:: + + create_javadoc( + (PACKAGES [...] | FILES [...]) + [SOURCEPATH ] + [CLASSPATH ] + [INSTALLPATH ] + [DOCTITLE ] + [WINDOWTITLE ] + [AUTHOR (TRUE|FALSE)] + [USE (TRUE|FALSE)] + [VERSION (TRUE|FALSE)] + ) + + The ``create_javadoc()`` command can be used to create java documentation. + There are two main signatures for ``create_javadoc()``. + + The first signature works with package names on a path with source files: + + .. code-block:: cmake + + create_javadoc(my_example_doc + PACKAGES com.example.foo com.example.bar + SOURCEPATH "${CMAKE_CURRENT_SOURCE_DIR}" + CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH} + WINDOWTITLE "My example" + DOCTITLE "

My example

" + AUTHOR TRUE + USE TRUE + VERSION TRUE + ) + + The second signature for ``create_javadoc()`` works on a given list of files: + + .. code-block:: cmake + + create_javadoc(my_example_doc + FILES java/A.java java/B.java + CLASSPATH ${CMAKE_JAVA_INCLUDE_PATH} + WINDOWTITLE "My example" + DOCTITLE "

My example

" + AUTHOR TRUE + USE TRUE + VERSION TRUE + ) + + Both signatures share most of the options. For more details please read the + javadoc manpage. + + ``PACKAGES`` + Specify java packages. + + ``FILES`` + Specify java source files. If relative paths are specified, they are + relative to :variable:`CMAKE_CURRENT_SOURCE_DIR`. + + ``SOURCEPATH`` + Specify the directory where to look for packages. By default, + :variable:`CMAKE_CURRENT_SOURCE_DIR` directory is used. + + ``CLASSPATH`` + Specify where to find user class files. Same behavior as option + ``-classpath`` of ``javadoc`` tool. + + ``INSTALLPATH`` + Specify where to install the java documentation. If you specified, the + documentation will be installed to + ``${CMAKE_INSTALL_PREFIX}/share/javadoc/``. + + ``DOCTITLE`` + Specify the title to place near the top of the overview summary file. + Same behavior as option ``-doctitle`` of ``javadoc`` tool. + + ``WINDOWTITLE`` + Specify the title to be placed in the HTML ```` tag. Same behavior + as option ``-windowtitle`` of ``javadoc`` tool. + + ``AUTHOR`` + When value ``TRUE`` is specified, includes the ``@author`` text in the + generated docs. Same behavior as option ``-author`` of ``javadoc`` tool. + + ``USE`` + When value ``TRUE`` is specified, creates class and package usage pages. + Includes one Use page for each documented class and package. Same behavior + as option ``-use`` of ``javadoc`` tool. + + ``VERSION`` + When value ``TRUE`` is specified, includes the version text in the + generated docs. Same behavior as option ``-version`` of ``javadoc`` tool. #]=======================================================================] include(CMakeParseArguments) @@ -378,7 +525,8 @@ function (__java_copy_file src dest comment) ARGS ${src} ${dest} DEPENDS ${src} - COMMENT ${comment}) + COMMENT ${comment} + ) endfunction () function(__java_lcat VAR) @@ -409,6 +557,12 @@ set(_JAVA_EXPORT_TARGETS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/javaTargets.cmake.in) set(_JAVA_CLASS_FILELIST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaClassFilelist.cmake) set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake) +if (CMAKE_HOST_WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + set(_UseJava_PATH_SEP "$<SEMICOLON>") +else () + set(_UseJava_PATH_SEP ":") +endif() + function(add_jar _TARGET_NAME) cmake_parse_arguments(_add_jar @@ -440,6 +594,9 @@ function(add_jar _TARGET_NAME) set(_add_jar_ENTRY_POINT "${CMAKE_JAVA_JAR_ENTRY_POINT}") endif() + # This *should* still work if <resources1>... are included without a + # named RESOURCES argument. In that case, the old behavior of potentially + # misplacing the within the Jar will behave as previously (incorrectly) set(_JAVA_SOURCE_FILES ${_add_jar_SOURCES} ${_add_jar_UNPARSED_ARGUMENTS}) if (NOT DEFINED _add_jar_OUTPUT_DIR) @@ -467,7 +624,10 @@ function(add_jar _TARGET_NAME) if (Java_VERSION VERSION_LESS 1.8) message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS is not supported with this version of Java.") endif() - cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS "" "DESTINATION" "" ${_add_jar_GENERATE_NATIVE_HEADERS}) + + unset (_GENERATE_NATIVE_HEADERS_OUTPUT_DESC) + + cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS "" "" "DESTINATION" ${_add_jar_GENERATE_NATIVE_HEADERS}) if (NOT _add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS) message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: missing required argument.") endif() @@ -478,11 +638,30 @@ function(add_jar _TARGET_NAME) endif() if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION) set (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers") + else() + list (LENGTH _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION length) + if (NOT length EQUAL 1) + cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "" "BUILD;INSTALL" "" "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION}") + if (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_UNPARSED_ARGUMENTS) + message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: DESTINATION: ${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_UNPARSED_ARGUMENTS}: unexpected argument(s).") + endif() + if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_INSTALL) + message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: DESTINATION: INSTALL sub-option is required.") + endif() + if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD) + set(_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers") + endif() + set(_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD}") + set(_GENERATE_NATIVE_HEADERS_OUTPUT_DESC "$<BUILD_INTERFACE:${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD}>" "$<INSTALL_INTERFACE:${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_INSTALL}>") + endif() endif() set (_GENERATE_NATIVE_HEADERS_TARGET ${_add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS}) set (_GENERATE_NATIVE_HEADERS_OUTPUT_DIR "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION}") set (_GENERATE_NATIVE_HEADERS -h "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}") + if(NOT _GENERATE_NATIVE_HEADERS_OUTPUT_DESC) + set(_GENERATE_NATIVE_HEADERS_OUTPUT_DESC "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}") + endif() endif() if (LIBRARY_OUTPUT_PATH) @@ -498,14 +677,8 @@ function(add_jar _TARGET_NAME) ${CMAKE_JAVA_LIBRARY_OUTPUT_PATH} ) - if (CMAKE_HOST_WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") - set(CMAKE_JAVA_INCLUDE_FLAG_SEP ";") - else () - set(CMAKE_JAVA_INCLUDE_FLAG_SEP ":") - endif() - foreach (JAVA_INCLUDE_DIR IN LISTS CMAKE_JAVA_INCLUDE_PATH) - string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${JAVA_INCLUDE_DIR}") + string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${JAVA_INCLUDE_DIR}") endforeach() set(CMAKE_JAVA_CLASS_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir") @@ -536,7 +709,7 @@ function(add_jar _TARGET_NAME) if (_JAVA_SOURCE_FILE MATCHES "^@(.+)$") get_filename_component(_JAVA_FULL ${CMAKE_MATCH_1} ABSOLUTE) - list (APPEND _JAVA_COMPILE_FILELISTS ${_JAVA_FULL}) + list(APPEND _JAVA_COMPILE_FILELISTS ${_JAVA_FULL}) elseif (_JAVA_EXT MATCHES ".java") file(RELATIVE_PATH _JAVA_REL_BINARY_PATH ${CMAKE_CURRENT_BINARY_DIR} ${_JAVA_FULL}) @@ -550,7 +723,7 @@ function(add_jar _TARGET_NAME) endif () get_filename_component(_JAVA_REL_PATH ${_JAVA_REL_PATH} PATH) - list (APPEND _JAVA_COMPILE_FILES ${_JAVA_SOURCE_FILE}) + list(APPEND _JAVA_COMPILE_FILES ${_JAVA_SOURCE_FILE}) set(_JAVA_CLASS_FILE "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_REL_PATH}/${_JAVA_FILE}.class") set(_JAVA_CLASS_FILES ${_JAVA_CLASS_FILES} ${_JAVA_CLASS_FILE}) @@ -561,15 +734,15 @@ function(add_jar _TARGET_NAME) # Ignored for backward compatibility elseif (_JAVA_EXT STREQUAL "") - list (APPEND CMAKE_JAVA_INCLUDE_PATH ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}} ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}_CLASSPATH}) - list (APPEND _JAVA_DEPENDS ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}}) + list(APPEND CMAKE_JAVA_INCLUDE_PATH ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}} ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}_CLASSPATH}) + list(APPEND _JAVA_DEPENDS ${JAVA_JAR_TARGET_${_JAVA_SOURCE_FILE}}) else () __java_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/${_JAVA_SOURCE_FILE} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_SOURCE_FILE} "Copying ${_JAVA_SOURCE_FILE} to the build directory") - list (APPEND _JAVA_RESOURCE_FILES ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_SOURCE_FILE}) - list (APPEND _JAVA_RESOURCE_FILES_RELATIVE ${_JAVA_SOURCE_FILE}) + list(APPEND _JAVA_RESOURCE_FILES ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${_JAVA_SOURCE_FILE}) + list(APPEND _JAVA_RESOURCE_FILES_RELATIVE ${_JAVA_SOURCE_FILE}) endif () endforeach() @@ -577,18 +750,18 @@ function(add_jar _TARGET_NAME) if (TARGET ${_JAVA_INCLUDE_JAR}) get_target_property(_JAVA_JAR_PATH ${_JAVA_INCLUDE_JAR} JAR_FILE) if (_JAVA_JAR_PATH) - string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${_JAVA_JAR_PATH}") - list (APPEND CMAKE_JAVA_INCLUDE_PATH ${_JAVA_JAR_PATH}) - list (APPEND _JAVA_DEPENDS ${_JAVA_INCLUDE_JAR}) - list (APPEND _JAVA_COMPILE_DEPENDS ${_JAVA_JAR_PATH}) + string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${_JAVA_JAR_PATH}") + list(APPEND CMAKE_JAVA_INCLUDE_PATH ${_JAVA_JAR_PATH}) + list(APPEND _JAVA_DEPENDS ${_JAVA_INCLUDE_JAR}) + list(APPEND _JAVA_COMPILE_DEPENDS ${_JAVA_JAR_PATH}) else () message(SEND_ERROR "add_jar: INCLUDE_JARS target ${_JAVA_INCLUDE_JAR} is not a jar") endif () else () - string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${_JAVA_INCLUDE_JAR}") - list (APPEND CMAKE_JAVA_INCLUDE_PATH "${_JAVA_INCLUDE_JAR}") - list (APPEND _JAVA_DEPENDS "${_JAVA_INCLUDE_JAR}") - list (APPEND _JAVA_COMPILE_DEPENDS "${_JAVA_INCLUDE_JAR}") + string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${_JAVA_INCLUDE_JAR}") + list(APPEND CMAKE_JAVA_INCLUDE_PATH "${_JAVA_INCLUDE_JAR}") + list(APPEND _JAVA_DEPENDS "${_JAVA_INCLUDE_JAR}") + list(APPEND _JAVA_COMPILE_DEPENDS "${_JAVA_INCLUDE_JAR}") endif () endforeach() @@ -627,14 +800,14 @@ function(add_jar _TARGET_NAME) OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist COMMAND ${CMAKE_COMMAND} -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH} - -DCMAKE_JAR_CLASSES_PREFIX="${CMAKE_JAR_CLASSES_PREFIX}" + -DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX} -P ${_JAVA_CLASS_FILELIST_SCRIPT} DEPENDS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) else () # create an empty java_class_filelist - if (NOT EXISTS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist") + if (NOT EXISTS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist) file(WRITE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist "") endif() endif () @@ -731,8 +904,9 @@ function(add_jar _TARGET_NAME) # create an INTERFACE library encapsulating include directory for generated headers add_library (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE) target_include_directories (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE - "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}" + "${_GENERATE_NATIVE_HEADERS_OUTPUT_DESC}" ${JNI_INCLUDE_DIRS}) + set_property(TARGET ${_GENERATE_NATIVE_HEADERS_TARGET} PROPERTY NATIVE_HEADERS_DIRECTORY "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}") # this INTERFACE library depends on jar generation add_dependencies (${_GENERATE_NATIVE_HEADERS_TARGET} ${_TARGET_NAME}) @@ -985,7 +1159,7 @@ function(create_javadoc _target) elseif (arg STREQUAL "VERSION") set(_state "version") else () - list (APPEND _javadoc_packages ${arg}) + list(APPEND _javadoc_packages ${arg}) endif () elseif (_state STREQUAL "files") if (arg STREQUAL "PACKAGES") @@ -1009,7 +1183,7 @@ function(create_javadoc _target) elseif (arg STREQUAL "VERSION") set(_state "version") else () - list (APPEND _javadoc_files ${arg}) + list(APPEND _javadoc_files ${arg}) endif () elseif (_state STREQUAL "sourcepath") if (arg STREQUAL "PACKAGES") @@ -1033,7 +1207,7 @@ function(create_javadoc _target) elseif (arg STREQUAL "VERSION") set(_state "version") else () - list (APPEND _javadoc_sourcepath ${arg}) + list(APPEND _javadoc_sourcepath ${arg}) endif () elseif (_state STREQUAL "classpath") if (arg STREQUAL "PACKAGES") @@ -1057,7 +1231,7 @@ function(create_javadoc _target) elseif (arg STREQUAL "VERSION") set(_state "version") else () - list (APPEND _javadoc_classpath ${arg}) + list(APPEND _javadoc_classpath ${arg}) endif () elseif (_state STREQUAL "installpath") if (arg STREQUAL "PACKAGES") @@ -1238,68 +1412,45 @@ function(create_javadoc _target) set(_javadoc_options -d ${_javadoc_builddir}) if (_javadoc_sourcepath) - set(_start TRUE) - foreach(_path IN LISTS _javadoc_sourcepath) - if (_start) - set(_sourcepath ${_path}) - set(_start FALSE) - else () - set(_sourcepath ${_sourcepath}:${_path}) - endif () - endforeach() - set(_javadoc_options ${_javadoc_options} -sourcepath ${_sourcepath}) + list(JOIN _javadoc_sourcepath "${_UseJava_PATH_SEP}" _javadoc_sourcepath) + list(APPEND _javadoc_options -sourcepath "\"${_javadoc_sourcepath}\"") endif () if (_javadoc_overview) - set(_start TRUE) - foreach(_path IN LISTS _javadoc_overview) - if (_start) - set(_overview ${_path}) - set(_start FALSE) - else () - set(_overview ${_overview}:${_path}) - endif () - endforeach () - set(_javadoc_options ${_javadoc_options} -overview ${_overview}) + list(JOIN _javadoc_overview "${_UseJava_PATH_SEP}" _javadoc_overview) + list(APPEND _javadoc_options -overview "\"${_javadoc_overview}\"") endif () if (_javadoc_classpath) - set(_start TRUE) - foreach(_path IN LISTS _javadoc_classpath) - if (_start) - set(_classpath ${_path}) - set(_start FALSE) - else () - set(_classpath ${_classpath}:${_path}) - endif () - endforeach() - set(_javadoc_options ${_javadoc_options} -classpath "${_classpath}") + list(JOIN _javadoc_classpath "${_UseJava_PATH_SEP}" _javadoc_classpath) + list(APPEND _javadoc_options -classpath "\"${_javadoc_classpath}\"") endif () if (_javadoc_doctitle) - set(_javadoc_options ${_javadoc_options} -doctitle '${_javadoc_doctitle}') + list(APPEND _javadoc_options -doctitle '${_javadoc_doctitle}') endif () if (_javadoc_windowtitle) - set(_javadoc_options ${_javadoc_options} -windowtitle '${_javadoc_windowtitle}') + list(APPEND _javadoc_options -windowtitle '${_javadoc_windowtitle}') endif () if (_javadoc_author) - set(_javadoc_options ${_javadoc_options} -author) + list(APPEND _javadoc_options -author) endif () if (_javadoc_use) - set(_javadoc_options ${_javadoc_options} -use) + list(APPEND _javadoc_options -use) endif () if (_javadoc_version) - set(_javadoc_options ${_javadoc_options} -version) + list(APPEND _javadoc_options -version) endif () add_custom_target(${_target}_javadoc ALL - COMMAND ${Java_JAVADOC_EXECUTABLE} ${_javadoc_options} - ${_javadoc_files} - ${_javadoc_packages} + COMMAND ${Java_JAVADOC_EXECUTABLE} + ${_javadoc_options} + ${_javadoc_files} + ${_javadoc_packages} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) @@ -1335,11 +1486,6 @@ function (create_javah) endif() set (_output_files) - if (WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") - set(_classpath_sep "$<SEMICOLON>") - else () - set(_classpath_sep ":") - endif() # handle javah options set (_javah_options) @@ -1365,7 +1511,7 @@ function (create_javah) message(SEND_ERROR "create_javah: CLASSPATH entry ${_path} does not exist.") endif() endforeach() - string (REPLACE ";" "${_classpath_sep}" _classpath "${_classpath}") + string (REPLACE ";" "${_UseJava_PATH_SEP}" _classpath "${_classpath}") list (APPEND _javah_options -classpath "${_classpath}") endif() diff --git a/config/cmake/UseJavaClassFilelist.cmake b/config/cmake/UseJavaClassFilelist.cmake index 8348e4c..d90ca48 100644 --- a/config/cmake/UseJavaClassFilelist.cmake +++ b/config/cmake/UseJavaClassFilelist.cmake @@ -1,17 +1,8 @@ # Distributed under the OSI-approved BSD 3-Clause License. See https://cmake.org/licensing for details. -#[=======================================================================[.rst: -UseJavaClassFilelist --------------------- - - - - - -This script create a list of compiled Java class files to be added to -a jar file. This avoids including cmake files which get created in -the binary directory. -#]=======================================================================] +# This script creates a list of compiled Java class files to be added to +# a jar file. This avoids including cmake files which get created in +# the binary directory. if (CMAKE_JAVA_CLASS_OUTPUT_PATH) if (EXISTS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}") @@ -23,7 +14,7 @@ if (CMAKE_JAVA_CLASS_OUTPUT_PATH) file(GLOB_RECURSE _JAVA_GLOBBED_TMP_FILES "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/${JAR_CLASS_PREFIX}/*.class") if (_JAVA_GLOBBED_TMP_FILES) - list (APPEND _JAVA_GLOBBED_FILES ${_JAVA_GLOBBED_TMP_FILES}) + list(APPEND _JAVA_GLOBBED_FILES ${_JAVA_GLOBBED_TMP_FILES}) endif () endforeach() else() diff --git a/config/cmake/UseJavaSymlinks.cmake b/config/cmake/UseJavaSymlinks.cmake index a4db5c1..cb2e282 100644 --- a/config/cmake/UseJavaSymlinks.cmake +++ b/config/cmake/UseJavaSymlinks.cmake @@ -1,15 +1,6 @@ # Distributed under the OSI-approved BSD 3-Clause License. See https://cmake.org/licensing for details. -#[=======================================================================[.rst: -UseJavaSymlinks ---------------- - - - - - -Helper script for UseJava.cmake -#]=======================================================================] +# Helper script for UseJava.cmake if (UNIX AND _JAVA_TARGET_OUTPUT_LINK) if (_JAVA_TARGET_OUTPUT_NAME) diff --git a/config/cmake/hdf5-config.cmake.in b/config/cmake/hdf5-config.cmake.in index 4d02c9c..8faa2fe 100644 --- a/config/cmake/hdf5-config.cmake.in +++ b/config/cmake/hdf5-config.cmake.in @@ -38,6 +38,7 @@ set (${HDF5_PACKAGE_NAME}_BUILD_CPP_LIB @HDF5_BUILD_CPP_LIB@) set (${HDF5_PACKAGE_NAME}_BUILD_JAVA @HDF5_BUILD_JAVA@) set (${HDF5_PACKAGE_NAME}_BUILD_TOOLS @HDF5_BUILD_TOOLS@) set (${HDF5_PACKAGE_NAME}_BUILD_HL_LIB @HDF5_BUILD_HL_LIB@) +set (${HDF5_PACKAGE_NAME}_BUILD_HL_TOOLS @HDF5_BUILD_HL_TOOLS@) set (${HDF5_PACKAGE_NAME}_ENABLE_THREADSAFE @HDF5_ENABLE_THREADSAFE@) set (${HDF5_PACKAGE_NAME}_ENABLE_PLUGIN_SUPPORT @HDF5_ENABLE_PLUGIN_SUPPORT@) set (${HDF5_PACKAGE_NAME}_ENABLE_Z_LIB_SUPPORT @HDF5_ENABLE_Z_LIB_SUPPORT@) diff --git a/config/cmake/javaTargets.cmake.in b/config/cmake/javaTargets.cmake.in new file mode 100644 index 0000000..6e14256 --- /dev/null +++ b/config/cmake/javaTargets.cmake.in @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 2.8.12) +cmake_policy(PUSH) +cmake_policy(VERSION 2.8) + +#---------------------------------------------------------------- +# Generated CMake Java target import file. +#---------------------------------------------------------------- + +# Protect against multiple inclusion, which would fail when already imported targets are added once more. +set(_targetsDefined) +set(_targetsNotDefined) +set(_expectedTargets) +foreach(_expectedTarget @__targets__@) + list(APPEND _expectedTargets ${_expectedTarget}) + if(TARGET ${_expectedTarget}) + list(APPEND _targetsDefined ${_expectedTarget}) + else() + list(APPEND _targetsNotDefined ${_expectedTarget}) + endif() +endforeach() +if("%${_targetsDefined}" STREQUAL "%${_expectedTargets}") + unset(_targetsDefined) + unset(_targetsNotDefined) + unset(_expectedTargets) + cmake_policy(POP) + return() +endif() +if(NOT "${_targetsDefined}" STREQUAL "") + message(FATAL_ERROR + "Some (but not all) targets in this export set were already defined.\n" + "Targets Defined: ${_targetsDefined}\n" + "Targets not yet defined: ${_targetsNotDefined}\n") +endif() +unset(_targetsDefined) +unset(_targetsNotDefined) +unset(_expectedTargets) + +@__targetdefs__@ +cmake_policy(POP) diff --git a/config/cmake/libh5cc.in b/config/cmake/libh5cc.in index c98d9ca..ecdd13e 100644 --- a/config/cmake/libh5cc.in +++ b/config/cmake/libh5cc.in @@ -29,4 +29,4 @@ printf 'dir is %s\n' "$dir" export PKG_CONFIG_PATH=$dir/lib/pkgconfig -@_PKG_CONFIG_COMPILER@ `pkg-config --define-variable=prefix=$dir --cflags --libs @_PKG_CONFIG_LIBNAME@` $@ +@_PKG_CONFIG_COMPILER@ $@ `pkg-config --define-variable=prefix=$dir --cflags --libs @_PKG_CONFIG_LIBNAME@` diff --git a/config/cmake/libhdf5.settings.cmake.in b/config/cmake/libhdf5.settings.cmake.in index ebcbd61..eb83c3a 100644 --- a/config/cmake/libhdf5.settings.cmake.in +++ b/config/cmake/libhdf5.settings.cmake.in @@ -70,6 +70,7 @@ Parallel Filtered Dataset Writes: @PARALLEL_FILTERED_WRITES@ High-level library: @HDF5_BUILD_HL_LIB@ Build HDF5 Tests: @BUILD_TESTING@ Build HDF5 Tools: @HDF5_BUILD_TOOLS@ + Build High-level HDF5 Tools: @HDF5_BUILD_HL_TOOLS@ Threadsafety: @HDF5_ENABLE_THREADSAFE@ Default API mapping: @DEFAULT_API_VERSION@ With deprecated public symbols: @HDF5_ENABLE_DEPRECATED_SYMBOLS@ diff --git a/config/cmake/scripts/HDF5config.cmake b/config/cmake/scripts/HDF5config.cmake index 08e38e8..8df7dd4 100644 --- a/config/cmake/scripts/HDF5config.cmake +++ b/config/cmake/scripts/HDF5config.cmake @@ -11,7 +11,7 @@ # ############################################################################################# ### ${CTEST_SCRIPT_ARG} is of the form OPTION=VALUE ### -### BUILD_GENERATOR required [Unix, VS2017, VS201764, VS2015, VS201564, VS2013, VS201364] ### +### BUILD_GENERATOR required [Unix, VS2019, VS201964, VS2017, VS201764, VS2015, VS201564] ### ### ctest -S HDF5config.cmake,BUILD_GENERATOR=VS201764 -C Release -VV -O hdf5.log ### ############################################################################################# @@ -68,7 +68,7 @@ endif () # build generator must be defined if (NOT DEFINED BUILD_GENERATOR) - message (FATAL_ERROR "BUILD_GENERATOR must be defined - Unix, VS2017, or VS201764, VS2015, VS201564, VS2013, VS201364") + message (FATAL_ERROR "BUILD_GENERATOR must be defined - Unix, VS2019, VS201964, VS2017, or VS201764, VS2015, VS201564") endif () ################################################################### @@ -163,7 +163,7 @@ if (NOT DEFINED HPC) set (SITE_COMPILER_NAME "vs2012") set (SITE_COMPILER_VERSION "11") else () - message (FATAL_ERROR "Invalid BUILD_GENERATOR must be - Unix, VS2017, or VS201764, VS2015, VS201564, VS2013, VS201364") + message (FATAL_ERROR "Invalid BUILD_GENERATOR must be - Unix, VS2019, VS201964, VS2017, or VS201764, VS2015, VS201564") endif () ## Set the following to unique id your computer ## set (CTEST_SITE "WIN7${BUILD_GENERATOR}.XXXX") diff --git a/config/cmake/scripts/HDF5options.cmake b/config/cmake/scripts/HDF5options.cmake index 7133e6c..136f55d 100644 --- a/config/cmake/scripts/HDF5options.cmake +++ b/config/cmake/scripts/HDF5options.cmake @@ -69,7 +69,7 @@ set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF5_ALLOW_EXTERNAL_SUPPORT:STRIN #set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF5_ENABLE_SZIP_ENCODING:BOOL=OFF") #### package examples #### -#set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF5_PACK_EXAMPLES:BOOL=ON -DHDF5_EXAMPLES_COMPRESSED:STRING=HDF5Examples-1.14.1-Source.tar.gz -DHDF5_EXAMPLES_COMPRESSED_DIR:PATH=${CTEST_SCRIPT_DIRECTORY}") +#set (ADD_BUILD_OPTIONS "${ADD_BUILD_OPTIONS} -DHDF5_PACK_EXAMPLES:BOOL=ON -DHDF5_EXAMPLES_COMPRESSED:STRING=HDF5Examples-1.14.4-Source.tar.gz -DHDF5_EXAMPLES_COMPRESSED_DIR:PATH=${CTEST_SCRIPT_DIRECTORY}") ############################################################################################# ### enable parallel builds diff --git a/config/cmake_ext_mod/ConfigureChecks.cmake b/config/cmake_ext_mod/ConfigureChecks.cmake index 61cec8b..53cc2d1 100644 --- a/config/cmake_ext_mod/ConfigureChecks.cmake +++ b/config/cmake_ext_mod/ConfigureChecks.cmake @@ -115,7 +115,7 @@ CHECK_INCLUDE_FILE_CONCAT ("sys/types.h" ${HDF_PREFIX}_HAVE_SYS_TYPES_H) CHECK_INCLUDE_FILE_CONCAT ("features.h" ${HDF_PREFIX}_HAVE_FEATURES_H) CHECK_INCLUDE_FILE_CONCAT ("dirent.h" ${HDF_PREFIX}_HAVE_DIRENT_H) CHECK_INCLUDE_FILE_CONCAT ("unistd.h" ${HDF_PREFIX}_HAVE_UNISTD_H) - +CHECK_INCLUDE_FILE_CONCAT ("pwd.h" ${HDF_PREFIX}_HAVE_PWD_H) CHECK_INCLUDE_FILE_CONCAT ("globus/common.h" ${HDF_PREFIX}_HAVE_GLOBUS_COMMON_H) CHECK_INCLUDE_FILE_CONCAT ("pdb.h" ${HDF_PREFIX}_HAVE_PDB_H) CHECK_INCLUDE_FILE_CONCAT ("pthread.h" ${HDF_PREFIX}_HAVE_PTHREAD_H) diff --git a/config/gnu-fflags b/config/gnu-fflags index ec4fcab..ce12561 100644 --- a/config/gnu-fflags +++ b/config/gnu-fflags @@ -161,10 +161,10 @@ if test "X-gfortran" = "X-$f9x_vendor"; then # gfortran 4.9 (nothing new) - # gfortran >= 5 - if test $f9x_vers_major -ge 5; then - H5_FCFLAGS="$H5_FCFLAGS $(load_gnu_arguments gfort-5)" - fi + # gfortran >= 5 (do not include -Wuse-without-only) + #if test $f9x_vers_major -ge 5; then + # H5_FCFLAGS="$H5_FCFLAGS $(load_gnu_arguments gfort-5)" + #fi # gfortran >= 6 if test $f9x_vers_major -ge 6; then diff --git a/config/intel-warnings/18 b/config/intel-warnings/18 index 565b47a..02bcdea 100644 --- a/config/intel-warnings/18 +++ b/config/intel-warnings/18 @@ -1,8 +1,2 @@ --Wextra-tokens --Wformat --Wformat-security -Wic-pointer --Wshadow -Wsign-compare --Wtrigraphs --Wwrite-strings diff --git a/config/intel-warnings/general-19 b/config/intel-warnings/general-19 deleted file mode 100644 index e35af30..0000000 --- a/config/intel-warnings/general-19 +++ /dev/null @@ -1,2 +0,0 @@ -# this is only available before oneapi versions --Wcheck diff --git a/config/intel-warnings/win-developer-general b/config/intel-warnings/win-developer-general new file mode 100644 index 0000000..6cd7ed7 --- /dev/null +++ b/config/intel-warnings/win-developer-general @@ -0,0 +1 @@ +/Wport diff --git a/config/intel-warnings/win-general b/config/intel-warnings/win-general new file mode 100644 index 0000000..ef54b2b --- /dev/null +++ b/config/intel-warnings/win-general @@ -0,0 +1 @@ +/Wall diff --git a/config/sanitizer/sanitizers.cmake b/config/sanitizer/sanitizers.cmake index 0803279..58c4050 100644 --- a/config/sanitizer/sanitizers.cmake +++ b/config/sanitizer/sanitizers.cmake @@ -33,10 +33,10 @@ if(USE_SANITIZER) if(INTEL_CLANG OR "${CMAKE_C_COMPILER_ID}" MATCHES "Clang") set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - append("-fno-omit-frame-pointer" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS) - message(STATUS "Building with sanitize, base flags=${CMAKE_C_SANITIZER_FLAGS}") - if(UNIX) + append("-fno-omit-frame-pointer" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS) + message(STATUS "Building with sanitize, base flags=${CMAKE_C_SANITIZER_FLAGS}") + if(uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") append("-O1" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS) endif() @@ -83,7 +83,7 @@ if(USE_SANITIZER) elseif(MSVC) if(USE_SANITIZER MATCHES "([Aa]ddress)") message(STATUS "Building with Address sanitizer") - append("-fsanitize=address" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS) + append("/fsanitize=address" CMAKE_C_SANITIZER_FLAGS CMAKE_CXX_SANITIZER_FLAGS) else() message(FATAL_ERROR "This sanitizer not yet supported in the MSVC environment: ${USE_SANITIZER}") endif() diff --git a/config/toolchain/clang.cmake b/config/toolchain/clang.cmake index 5e3b13a..af176aa 100644 --- a/config/toolchain/clang.cmake +++ b/config/toolchain/clang.cmake @@ -3,8 +3,13 @@ set(CMAKE_COMPILER_VENDOR "clang") -set(CMAKE_C_COMPILER clang) -set(CMAKE_CXX_COMPILER clang++) +if(WIN32) + set(CMAKE_C_COMPILER clang-cl) + set(CMAKE_CXX_COMPILER clang-cl) +else() + set(CMAKE_C_COMPILER clang) + set(CMAKE_CXX_COMPILER clang++) +endif() set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # the following is used if cross-compiling diff --git a/configure.ac b/configure.ac index a7366eb..3290de4 100644 --- a/configure.ac +++ b/configure.ac @@ -786,6 +786,7 @@ AC_LANG_POP(C++) ## This needs to be exposed for the library info file even if the HL ## library is disabled. AC_SUBST([HDF5_HL]) +AC_SUBST([HDF5_HL_TOOLS]) ## The high-level library is enabled unless the build mode is clean. if test "X-$BUILD_MODE" = "X-clean" ; then @@ -802,6 +803,9 @@ HL="" ## Fortran high-level library AC_SUBST(HL_FOR) HL_FOR="" +## Tools high-level library +AC_SUBST(HL_TOOLS) +HL_TOOLS="" AC_MSG_CHECKING([if the high-level library is enabled]) AC_ARG_ENABLE([hl], @@ -820,6 +824,21 @@ else AC_MSG_RESULT([no]) fi +AC_MSG_CHECKING([if the high-level tools are enabled]) +AC_ARG_ENABLE([hltools], + [AS_HELP_STRING([--enable-hltools], + [Enable the high-level tools. + [default=yes)] + ])], + [HDF5_HL_TOOLS=$enableval]) + +if test "X${HDF5_HL}" = "Xyes" -a "X-$HDF5_HL_TOOLS" = "X-yes"; then + AC_MSG_RESULT([yes]) + HL_TOOLS="tools" +else + AC_MSG_RESULT([no]) +fi + ## ---------------------------------------------------------------------- ## Check which archiving tool to use. This needs to be done before @@ -1102,29 +1121,35 @@ if test "X$HDF5_DOXYGEN" = "Xyes"; then AC_SUBST([DOXYGEN_HTML_FOOTER]) AC_SUBST([DOXYGEN_HTML_EXTRA_STYLESHEET]) AC_SUBST([DOXYGEN_HTML_EXTRA_FILES]) + AC_SUBST([DOXYGEN_TAG_FILE]) AC_SUBST([DOXYGEN_SERVER_BASED_SEARCH]) AC_SUBST([DOXYGEN_EXTERNAL_SEARCH]) AC_SUBST([DOXYGEN_SEARCHENGINE_URL]) + AC_SUBST([DOXYGEN_STRIP_FROM_PATH]) + AC_SUBST([DOXYGEN_PREDEFINED]) # SRCDIR Environment variables used inside doxygen macro for the source location: DOXYGEN_PACKAGE=${PACKAGE_NAME} DOXYGEN_VERSION_STRING=${PACKAGE_VERSION} DOXYGEN_INCLUDE_ALIASES='$(SRCDIR)/doxygen/aliases' DOXYGEN_PROJECT_LOGO='$(SRCDIR)/doxygen/img/HDFG-logo.png' - DOXYGEN_PROJECT_BRIEF= + DOXYGEN_PROJECT_BRIEF='C-API Reference' DOXYGEN_INPUT_DIRECTORY='$(SRCDIR) $(SRCDIR)/doxygen/dox' DOXYGEN_OPTIMIZE_OUTPUT_FOR_C=YES DOXYGEN_MACRO_EXPANSION=YES DOXYGEN_OUTPUT_DIRECTORY=hdf5lib_docs - DOXYGEN_EXAMPLES_DIRECTORY='$(SRCDIR)/doxygen/examples $(SRCDIR)/src $(SRCDIR)/examples $(SRCDIR)/test' + DOXYGEN_EXAMPLES_DIRECTORY='$(SRCDIR)/doxygen/dox/cookbook $(SRCDIR)/doxygen/examples $(SRCDIR)/src $(SRCDIR)/examples $(SRCDIR)/test' DOXYGEN_LAYOUT_FILE='$(SRCDIR)/doxygen/hdf5doxy_layout.xml' DOXYGEN_HTML_HEADER='$(SRCDIR)/doxygen/hdf5_header.html' DOXYGEN_HTML_FOOTER='$(SRCDIR)/doxygen/hdf5_footer.html' DOXYGEN_HTML_EXTRA_STYLESHEET='$(SRCDIR)/doxygen/hdf5doxy.css' DOXYGEN_HTML_EXTRA_FILES='$(SRCDIR)/doxygen/hdf5_navtree_hacks.js $(SRCDIR)/doxygen/img/ftv2node.png $(SRCDIR)/doxygen/img/ftv2pnode.png' + DOXYGEN_TAG_FILE=hdf5.tag DOXYGEN_SERVER_BASED_SEARCH=NO DOXYGEN_EXTERNAL_SEARCH=NO DOXYGEN_SEARCHENGINE_URL= + DOXYGEN_STRIP_FROM_PATH='$(SRCDIR)' + DOXYGEN_PREDEFINED='H5_HAVE_DIRECT H5_HAVE_LIBHDFS H5_HAVE_MAP_API H5_HAVE_PARALLEL H5_HAVE_ROS3_VFD' DX_INIT_DOXYGEN([HDF5], [./doxygen/Doxyfile], [hdf5lib_docs]) @@ -1225,7 +1250,7 @@ AC_CHECK_LIB([dl], [dlopen]) ## ## Unix -AC_CHECK_HEADERS([dirent.h features.h unistd.h]) +AC_CHECK_HEADERS([dirent.h features.h pwd.h unistd.h]) AC_CHECK_HEADERS([sys/file.h sys/ioctl.h sys/resource.h]) AC_CHECK_HEADERS([sys/stat.h sys/time.h sys/types.h]) @@ -1240,8 +1265,6 @@ case $host_os in esac ## Windows -## The winsock header is needed for gethostname -AC_CHECK_HEADERS([winsock2.h]) case "`uname`" in MINGW*) AC_HAVE_LIBRARY([ws2_32]) @@ -3868,6 +3891,7 @@ AM_CONDITIONAL([BUILD_HDF5_HL_CONDITIONAL], [test "X$HDF5_HL" = "Xyes"]) AM_CONDITIONAL([BUILD_TESTS_CONDITIONAL], [test "X$HDF5_TESTS" = "Xyes"]) AM_CONDITIONAL([BUILD_TESTS_PARALLEL_CONDITIONAL], [test -n "$TESTPARALLEL"]) AM_CONDITIONAL([BUILD_TOOLS_CONDITIONAL], [test "X$HDF5_TOOLS" = "Xyes"]) +AM_CONDITIONAL([BUILD_TOOLS_HL_CONDITIONAL], [test "X$HDF5_HL_TOOLS" = "Xyes"]) AM_CONDITIONAL([BUILD_DOXYGEN_CONDITIONAL], [test "X$HDF5_DOXYGEN" = "Xyes"]) ## ---------------------------------------------------------------------- @@ -4044,6 +4068,7 @@ AC_CONFIG_FILES([src/libhdf5.settings tools/test/misc/vds/Makefile tools/test/h5stat/Makefile tools/test/h5stat/testh5stat.sh + tools/src/h5perf/Makefile tools/test/perform/Makefile examples/Makefile examples/run-c-ex.sh diff --git a/doc/contributing.md b/doc/contributing.md index 7f9e8d3..d32ab4d 100644 --- a/doc/contributing.md +++ b/doc/contributing.md @@ -1,10 +1,10 @@ # How to contribute to HDF5 -The HDF Group encourages community members to contribute to the HDF5 project. We accept and are very grateful for any contributions, +The HDF Group encourages community members to contribute to the HDF5 project. We accept and are very grateful for any contributions, from minor typos and bug fixes to new features. The HDF Group is committed to work with the code contributors and make contribution process enjoyable and straightforward. -This document describes guiding principles for the HDF5 code contributors and does not pretend to address any possible -contribution. If in doubt, please do not hesitate to ask us for guidance. +This document describes guiding principles for the HDF5 code contributors and does not pretend to address any possible +contribution. If in doubt, please do not hesitate to ask us for guidance. ***Note that no contribution may be accepted unless the donor agrees with the HDF Group software license terms found in the COPYING file in every branch's top source directory.*** @@ -23,38 +23,38 @@ The process for contributing code to HDF5 is as follows: * Open an issue on [HDF5 GitHub](https://github.com/HDFGroup/hdf5/issues). -> This step is ***required*** unless the change is minor (e.g., typo fix). +> This step is ***required*** unless the change is minor (e.g., typo fix). * Fork the [HDF5](https://github.com/HDFGroup/hdf5) repository. * Make the desired changes to the HDF5 software. * New features should always go to _develop_ branch first and later should be merged to the appropriate maintenance branches. - * Bug fixes should go to all appropriate branches (_develop_ and maintenance). + * Bug fixes should go to all appropriate branches (_develop_ and maintenance). * Build and test your changes. Detailed instructions on building and testing HDF5 can be found in the `INSTALL*` files in the `release_docs` directory. * Push your changes to GitHub. * Issue a pull request and address any code formatting and testing issues reported. Once a pull request is correctly formatted and passes **ALL** CI tests, it will be reviewed and evaluated by The HDF Group developers and HDF5 community members who can approve pull requests. -The HDF Group developers will work with you to ensure that the pull request satisfies the acceptance criteria described in the next section. +The HDF Group developers will work with you to ensure that the pull request satisfies the acceptance criteria described in the next section. # Acceptance criteria for a pull request <A NAME="criteria"></A> We appreciate every contribution we receive, but we may not accept them all. Those that we *do* satisfy the following criteria: -* **The pull request has a clear purpose** - What does the pull request address? How does it benefit the HDF5 community? -If the pull request does not have a clear purpose and benefits, it will not be accepted. +* **The pull request has a clear purpose** - What does the pull request address? How does it benefit the HDF5 community? +If the pull request does not have a clear purpose and benefits, it will not be accepted. * **The pull request is documented** - The HDF5 developers must understand not only *what* a change is doing, but *how* it is doing it. - Documenting the code makes it easier for us to understand your patch and maintain the code in the future. + Documenting the code makes it easier for us to understand your patch and maintain the code in the future. -* **The pull request passes HDF5 regression testing** - Any issue fixed or functionality added should be accompanied by the corresponding -tests and pass HDF5 regression testing run by The HDF Group. We do not expect you to perform comprehensive testing across multiple platforms -before we accept the pull request. If the pull request does not pass regression testing after the merge, The HDF Group developers will work with you on the fixes. +* **The pull request passes HDF5 regression testing** - Any issue fixed or functionality added should be accompanied by the corresponding +tests and pass HDF5 regression testing run by The HDF Group. We do not expect you to perform comprehensive testing across multiple platforms +before we accept the pull request. If the pull request does not pass regression testing after the merge, The HDF Group developers will work with you on the fixes. -* **The pull request does not compromise the principles behind HDF5** - HDF5 has a 100% commitment to backward compatibility. +* **The pull request does not compromise the principles behind HDF5** - HDF5 has a 100% commitment to backward compatibility. * Any file ever created with HDF5 must be readable by any future version of HDF5. If your patch's purpose is to modify the HDF5 data model or file format, - **please** discuss this with us first. File format changes and features required by those changes can be introduced only in a new major release. - * HDF5 has a commitment to remaining *machine-independent*; data created on one platform/environment/architecture **must** remain readable by HDF5 on any other. + **please** discuss this with us first. File format changes and features required by those changes can be introduced only in a new major release. + * HDF5 has a commitment to remaining *machine-independent*; data created on one platform/environment/architecture **must** remain readable by HDF5 on any other. * For binary compatibility, no changes are allowed to public APIs and data structures in the maintenance releases; new APIs can be added. * **New features are documented** - Any new features should have proper documentation; talk to us if you have any questions. @@ -64,7 +64,7 @@ before we accept the pull request. If the pull request does not pass regression Please make sure that you check the items applicable to your pull request: -* Code +* Code * [ ] Does the pull request have a corresponding GitHub issue and clear purpose? * [ ] Does the pull request follow HDF5 best practices (naming conventions, code portability, code structure, etc.)? <<TODO: link to the document>> * [ ] If changes were done to Autotools build, were they added to CMake and vice versa? @@ -74,7 +74,7 @@ Please make sure that you check the items applicable to your pull request: * Documentation * [ ] Was the change described in the release_docs/RELEASE.txt file? * [ ] Was MANIFEST updated if new files had been added to the source? - * [ ] Was the new function documented in the corresponding public header file using Doxygen? <<TODO: link to Doxygen instructions>> + * [ ] Was the new function documented in the corresponding public header file using [Doxygen](https://docs.hdfgroup.org/hdf5/develop/_r_m_t.html)? * [ ] Was new functionality documented for the HDF5 community (the level of documentation depends on the feature; ask us what would be appropriate) * Testing * [ ] Does the pull request have tests? @@ -83,4 +83,3 @@ Please make sure that you check the items applicable to your pull request: We want as many contributions as we can get, and we are here to help. Feel free to reach out to us if you have any questions Thank you for your contribution! - diff --git a/doxygen/CMakeLists.txt b/doxygen/CMakeLists.txt new file mode 100644 index 0000000..36ce590 --- /dev/null +++ b/doxygen/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required (VERSION 3.12) +project (HDF5_DOXYGEN C) + +#----------------------------------------------------------------------------- +# Option to build documentation +#----------------------------------------------------------------------------- +if (DOXYGEN_FOUND) + set (DOXYGEN_PACKAGE ${HDF5_PACKAGE_NAME}) + set (DOXYGEN_VERSION_STRING ${HDF5_PACKAGE_VERSION_STRING}) + set (DOXYGEN_INCLUDE_ALIASES_PATH ${HDF5_DOXYGEN_DIR}) + set (DOXYGEN_INCLUDE_ALIASES aliases) + set (DOXYGEN_VERBATIM_VARS DOXYGEN_INCLUDE_ALIASES) + set (DOXYGEN_PROJECT_LOGO ${HDF5_DOXYGEN_DIR}/img/HDFG-logo.png) + set (DOXYGEN_PROJECT_BRIEF "C-API Reference") + set (DOXYGEN_INPUT_DIRECTORY "${HDF5_SOURCE_DIR} ${HDF5_DOXYGEN_DIR}/dox ${HDF5_GENERATED_SOURCE_DIR}") + set (DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES) + set (DOXYGEN_MACRO_EXPANSION YES) + set (DOXYGEN_OUTPUT_DIRECTORY ${HDF5_BINARY_DIR}/hdf5lib_docs) + set (DOXYGEN_EXAMPLES_DIRECTORY "${HDF5_DOXYGEN_DIR}/dox/cookbook ${HDF5_DOXYGEN_DIR}/examples ${HDF5_SRC_DIR} ${HDF5_SOURCE_DIR}/examples ${HDF5_TEST_SRC_DIR}") + set (DOXYGEN_LAYOUT_FILE ${HDF5_DOXYGEN_DIR}/hdf5doxy_layout.xml) + set (DOXYGEN_HTML_HEADER ${HDF5_DOXYGEN_DIR}/hdf5_header.html) + set (DOXYGEN_HTML_FOOTER ${HDF5_DOXYGEN_DIR}/hdf5_footer.html) + set (DOXYGEN_HTML_EXTRA_STYLESHEET ${HDF5_DOXYGEN_DIR}/hdf5doxy.css) + set (DOXYGEN_HTML_EXTRA_FILES "${HDF5_DOXYGEN_DIR}/hdf5_navtree_hacks.js ${HDF5_DOXYGEN_DIR}/img/ftv2node.png ${HDF5_DOXYGEN_DIR}/img/ftv2pnode.png") + set (DOXYGEN_TAG_FILE ${HDF5_BINARY_DIR}/hdf5.tag) + set (DOXYGEN_SERVER_BASED_SEARCH NO) + set (DOXYGEN_EXTERNAL_SEARCH NO) + set (DOXYGEN_SEARCHENGINE_URL) + set (DOXYGEN_STRIP_FROM_PATH ${HDF5_SOURCE_DIR}) + set (DOXYGEN_PREDEFINED "H5_HAVE_DIRECT H5_HAVE_LIBHDFS H5_HAVE_MAP_API H5_HAVE_PARALLEL H5_HAVE_ROS3_VFD") + +# This configure and individual custom targets work together + # Replace variables inside @@ with the current values + configure_file (${HDF5_DOXYGEN_DIR}/Doxyfile.in ${HDF5_BINARY_DIR}/Doxyfile @ONLY) + + install ( + DIRECTORY ${HDF5_BINARY_DIR}/hdf5lib_docs/html + DESTINATION ${HDF5_INSTALL_DATA_DIR} + COMPONENT Documents + ) + + if (NOT TARGET doxygen) + add_custom_target (doxygen) + endif () + +endif () diff --git a/doxygen/Doxyfile.in b/doxygen/Doxyfile.in index 29f3028..44d9974 100644 --- a/doxygen/Doxyfile.in +++ b/doxygen/Doxyfile.in @@ -170,7 +170,7 @@ FULL_PATH_NAMES = YES # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = +STRIP_FROM_PATH = @DOXYGEN_STRIP_FROM_PATH@ # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which @@ -858,16 +858,21 @@ FILE_PATTERNS = H5*public.h \ H5FDcore.h \ H5FDdirect.h \ H5FDfamily.h \ + H5FDhdfs.h \ H5FDlog.h \ + H5FDmirror.h \ H5FDmpi.h \ H5FDmpio.h \ H5FDmulti.h \ + H5FDros3.h \ H5FDsec2.h \ + H5FDsplitter.h \ H5FDstdio.h \ H5FDwindows.h \ H5VLconnector.h \ H5VLconnector_passthru.h \ H5VLnative.h \ + H5Zdevelop.h \ H5version.h \ *.dox @@ -1121,13 +1126,6 @@ CLANG_DATABASE_PATH = ALPHABETICAL_INDEX = YES -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored @@ -2177,7 +2175,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = H5_HAVE_PARALLEL +PREDEFINED = @DOXYGEN_PREDEFINED@ # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2221,7 +2219,7 @@ TAGFILES = # tag file that is based on the input files it reads. See section "Linking to # external documentation" for more information about the usage of tag files. -GENERATE_TAGFILE = +GENERATE_TAGFILE = @DOXYGEN_TAG_FILE@ # If the ALLEXTERNALS tag is set to YES, all external class will be listed in # the class index. If set to NO, only the inherited external classes will be diff --git a/doxygen/aliases b/doxygen/aliases index af43902..06c3445 100644 --- a/doxygen/aliases +++ b/doxygen/aliases @@ -16,11 +16,17 @@ ALIASES += success{1}="\Bold{Success:} \1" ALIASES += failure{1}="\Bold{Failure:} \1" ALIASES += herr_t="Returns a non-negative value if successful; otherwise returns a negative value." +ALIASES += herr_t_iter="\li Zero causes the iterator to continue, returning zero when the iteration is complete. \li A positive value causes the iterator to immediately return that positive value, indicating short-circuit success. \li A negative value causes the iterator to immediately return that value, indicating failure." ALIASES += hid_t{1}="Returns a \1 identifier if successful; otherwise returns #H5I_INVALID_HID. " ALIASES += hid_ti{1}="Returns an \1 identifier if successful; otherwise returns #H5I_INVALID_HID. " ALIASES += hid_tv{1}="Returns an \1 identifier if successful; otherwise returns a negative value. " ALIASES += htri_t="Returns zero (false), a positive (true) or a negative (failure) value." +ALIASES += api_vers_2{3}="\1() is a macro that is mapped to either \2() or \3().\n\see \ref api-compat-macros" +ALIASES += api_vers_3{4}="\1() is a macro that is mapped to either \2() or \3() or \4().\n\see \ref api-compat-macros" + +ALIASES += deprecation_note{1}="\deprecated Superseded by \1." + ################################################################################ # General ################################################################################ @@ -131,6 +137,8 @@ ALIASES += map_id{1}="\param[in] \1 Map identifier" # Property lists ################################################################################ +ALIASES += plist_unused{1}="\note The \p \1 parameter is currently not used; specify #H5P_DEFAULT." + ALIASES += aapl_id="\param[in] aapl_id Attribute access property list identifier" ALIASES += aapl_id{1}="\param[in] \1 Attribute access property list identifier" @@ -217,9 +225,8 @@ ALIASES += es_id{1}="\param[in] \1 Event set identifier" # Others ################################################################################ -ALIASES += estack_id="\param[in] estack_id Error stack identifier" -ALIASES += estack_id{1}="\param[in] \1 Error stack identifier" ALIASES += cpp_c_api_note="\attention \Bold{C++ Developers using HDF5 C-API functions beware:}\n Several functions in this C-API take function pointers or callbacks as arguments. Examples include H5Pset_elink_cb(), H5Pset_type_conv_cb(), H5Tconvert(), and H5Ewalk2(). Application code must ensure that those callback functions return normally such to allow the HDF5 to manage its resources and maintain a consistent state. For instance, those functions must not use the C \c setjmp / \c longjmp mechanism to leave those callback functions. Within the context of C++, any exceptions thrown within the callback function must be caught, such as with a \Code{catch(…)} statement. Any exception state can be placed within the provided user data function call arguments, and may be thrown again once the calling function has returned. Exceptions raised and not handled inside the callback are not supported as it might leave the HDF5 library in an inconsistent state. Similarly, using C++20 coroutines cannot be used as callbacks, since they do not support plain return statements. If a callback function yields execution to another C++20 coroutine calling HDF5 functions as well, this may lead to undefined behavior." +ALIASES += par_compr_note="\attention If you are planning to use compression with parallel HDF5, ensure that calls to H5Dwrite() occur in collective mode. In other words, all MPI ranks (in the relevant communicator) call H5Dwrite() and pass a dataset transfer property list with the MPI-IO collective option property set to #H5FD_MPIO_COLLECTIVE_IO.\n Note that data transformations are currently \Bold{not} supported when writing to datasets in parallel and with compression enabled." ALIASES += sa_metadata_ops="\sa \li H5Pget_all_coll_metadata_ops() \li H5Pget_coll_metadata_write() \li H5Pset_all_coll_metadata_ops() \li H5Pset_coll_metadata_write() \li \ref maybe_metadata_reads" ################################################################################ @@ -241,6 +248,95 @@ ALIASES += ref_vlen_strings="\Emph{Creating variable-length string datatypes}" ALIASES += ref_vol_doc="VOL documentation" ################################################################################ +# RFCs +################################################################################ + +ALIASES += ref_rfc20210528="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_multi_thread.pdf\">Multi-Thread HDF5</a>" +ALIASES += ref_rfc20190923="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2019-09-23-RFC_VOL_feature_flags.pdf\">Virtual Object Layer (VOL) API Compatibility</a>" +ALIASES += ref_rfc20190410="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_VFD_Plugin.docx.pdf\">A Plugin Interface for HDF5 Virtual File Drivers</a>" +ALIASES += ref_rfc20181231="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Min_Obj_Headers_181231.pdf\">Dataset Object Header Size</a>" +ALIASES += ref_rfc20181220="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/3.2.1_3.2.2_deliverable_181220_v4.pdf\">MS 3.2 – Addressing Scalability: Scalability of open, close, flush CASE STUDY: CGNS Hotspot analysis of CGNS cgp_open</a>" +ALIASES += ref_rfc20180620="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Chunking%20Functions-2018-06-20-v3.docx.pdf\">Chunk query functionality in HDF5</a>" +ALIASES += ref_rfc20180610="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/VFD_SWMR_RFC_200916.pdf\">VFD SWMR</a>" +ALIASES += ref_rfc20180321="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-API_Contexts-2018-03-21.docx.pdf\">API Contexts</a>" +ALIASES += ref_rfc20180125="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/enhance_h5clear.docx.pdf\">Enhancement to the tool <tt>h5clear</tt></a>" +ALIASES += ref_rfc20170707="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/H5Sencode_format.docx.pdf\"><tt>H5Sencode/H5Sdecode</tt> Format Change</a>" +ALIASES += ref_rfc20160105="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-bounds.pdf\">Setting Bounds for Object Creation in HDF5 1.10.0</a>" +ALIASES += ref_rfc20150915="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2015-09-28-RFC-HDF5-1.10.0-File-Format-Superblock-Changes-EP.docx.pdf\">File Format Changes in HDF5 1.10.0</a>" +ALIASES += ref_rfc20150709="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Page_Buffering.pdf\">Page Buffering</a>" +ALIASES += ref_rfc20150615="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/cache_image_RFC_150929-QAK.docx.pdf\">Metadata Cache Image</a>" +ALIASES += ref_rfc20150429="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/new_datatypes.pdf\">New Datatypes</a>" +ALIASES += ref_rfc20150424="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-CollectiveMetadataWrites.pdf\">Collective Metadata Writes</a>" +ALIASES += ref_rfc20150423="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-CollectiveMetadataReads.pdf\">Enabling Collective Metadata Reads</a>" +ALIASES += ref_rfc20150301="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/sent_RFC_format_convert-v3.docx.pdf\">The Tool to Handle HDF5 File Format Compatibility for Chunked Datasets</a>" +ALIASES += ref_rfc20150212="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_H5LTget_hardlinkds.docx.pdf\"><tt>H5LTget_hardlinks</tt> – High-level API to list all the hard links to an object</a>" +ALIASES += ref_rfc20150205="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_F2003_v6.docx.pdf\">HDF5 Fortran Wrappers Maintenance: Dropping Support for Non-Fortran 2003 Standard Compliant Compilers</a>" +ALIASES += ref_rfc20150202="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20New%20Autotools%20Behavior.docx.pdf\">New Autotools Behavior</a>" +ALIASES += ref_rfc20141210="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/HDF5-VDS-requirements-use-cases-2014-12-10.pdf\">HDF5 Virtual Dataset</a>" +ALIASES += ref_rfc20141201="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20filter%20memory%20issues%20on%20Windows.docx.pdf\">Allocate/Free Mismatches in HDF5 Filter Code on Windows</a>" +ALIASES += ref_rfc20140916="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_VOL.pdf\">Virtual Object Layer</a>" +ALIASES += ref_rfc20140827="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/CompressNChunk_RFC.pdf\">Chunking and Compression Performance Tool Requirements</a>" +ALIASES += ref_rfc20140729="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/h5fis_accessible.pdf\">Replacing H5Fis_hdf5() with H5Fis_accessible()</a>" +ALIASES += ref_rfc20140722="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/64bit_hid_t-v1.docx.pdf\">Switching to a 64-bit <tt>hid_t</tt> Space in HDF5</a>" +ALIASES += ref_rfc20140717="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/analysis_ext.pdf\">Data Analysis Extensions</a>" +ALIASES += ref_rfc20140707="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2014-08-28-RFC_VOL.pdf\">Virtual Object Layer</a>" +ALIASES += ref_rfc20140524="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Why%20does%20not%20compression%20work-GH-EP.docx.pdf\">HDF5 Compression Demystified</a>" +ALIASES += ref_rfc20140318="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20H5free_memory%20v2.pdf\">Freeing Memory Allocated by the HDF5 Library</a>" +ALIASES += ref_rfc20140313="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Compat-Tool-v2.docx.pdf\">Options to handle compatibility issues for HDF5 files</a>" +ALIASES += ref_rfc20140224="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/Design-MetadataCache-Logging-THG20140224-v4.pdf\">Design: Metadata Cache Logging</a>" +ALIASES += ref_rfc20131211="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20H5Ocork%20v5%20new%20fxn%20names.pdf\">Fine-Grained Control of Metadata Cache Flushes</a>" +ALIASES += ref_rfc20130930="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Read-Attempts-for-Metadata-with-Checksum-v3.pdf\">Read Attempts for Metadata with Checksum</a>" +ALIASES += ref_rfc20130919="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/core%20CFD%20paging%20v5.docx.pdf\">Core VFD Backing Store Paged Writes</a>" +ALIASES += ref_rfc20130630="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/Design-HDF5-FlushDependencyTesting-20130630-v1.1.pdf\">Flush Dependency Testing</a>" +ALIASES += ref_rfc20130316="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/HDF5DynamicallyLoadedFilters.pdf\">HDF5 Dynamically Loaded Filters</a>" +ALIASES += ref_rfc20121114="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/DECTRIS%20Integration%20RFC%202012-11-29.pdf\">Direct Chunk Write</a>" +ALIASES += ref_rfc20121024="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/FileSpaceManagement.pdf\">HDF5 File Space Management</a>" +ALIASES += ref_rfc20120828="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/H5HPC_MultiDset_RW_IO_RFC_v4_20130320.docx.pdf\">New HDF5 API Routines for HPC Applications</a>" +ALIASES += ref_rfc20120523="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/paged_aggregation.pdf\">HDF5 File Space Management: Paged Aggregation</a>" +ALIASES += ref_rfc20120501="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/HDF5FileImageOperations.pdf\">HDF5 File Image Operations</a>" +ALIASES += ref_rfc20120305="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20PHDF5%20Consistency%20Semantics%20MC%20120328.docx.pdf\">Enabling a Strict Consistency Semantics Model in Parallel HDF5</a>" +ALIASES += ref_rfc20120220="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/h5repack_improve_hyperslab_over_chunked_dataset_v1.pdf\"><tt>h5repack</tt>: Improved Hyperslab selections for Large Chunked Datasets</a>" +ALIASES += ref_rfc20120120="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2012-1-25-Maintainers-guide-for-datatype.docx.pdf\">A Maintainer’s Guide for the Datatype Module in HDF5 Library</a>" +ALIASES += ref_rfc20120104="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_actual_io_v4-1_done.docx.pdf\">Actual I/O Mode</a>" +ALIASES += ref_rfc20111119="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-H5Ocompare-review_v6.pdf\">New public functions to handle comparison</a>" +ALIASES += ref_rfc20110825="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/2011-08-31-RFC_H5Ocopy_Named_DT_v2.docx.pdf\">Merging Named Datatypes in H5Ocopy()</a>" +ALIASES += ref_rfc20110811="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Enhancement_Hyperslab_Selection-1.4.docx.pdf\">Expanding the HDF5 Hyperslab Selection Interface</a>" +ALIASES += ref_rfc20110726="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/metadata_aggregation_RFC_v03.docx.pdf\">HDF5 File Space Allocation and Aggregation</a>" +ALIASES += ref_rfc20110614="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_h5dump_refactor_v3.docx.pdf\"> Refactor <tt>h5dump</tt> to Improve Maintenance</a>" +ALIASES += ref_rfc20110329="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Tools_Extlink_Cache_v3_r2.docx.pdf\">Support External Link Open File Cache in HDF5 Tools</a>" +ALIASES += ref_rfc20110118="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC%20for%20h5diff%20Attribute%20Comparisons_v7.docx.pdf\"><tt>h5diff</tt> Attribute Comparisons</a>" +ALIASES += ref_rfc20101122="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_swmr_timeouts_v2.docx.pdf\">SWMR Timeouts</a>" +ALIASES += ref_rfc20101104="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/CacheExternalLinkFileOpens.pdf\">Caching Files Opened Through External Links</a>" +ALIASES += ref_rfc20101018="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/HDF5-comparisons_v3-RFC-2011-08-03.pdf\">HDF5 File and Object Comparison Specification</a>" +ALIASES += ref_rfc20100902="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/H5edit-RFC-Draft-v5.pdf\"><tt>h5edit</tt> – An HDF5 File Editing Tool</a>" +ALIASES += ref_rfc20100727="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_HDF5_reservedCharacters-v2.pdf\">Reserved Characters for HDF5 Applications</a>" +ALIASES += ref_rfc20100726="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/H5HPC_RFC-2010-09-28.pdf\">High-Level HDF5 API routines for HPC Applications</a>" +ALIASES += ref_rfc20100511="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_h5diff_exclude_obj_v1_3.pdf\"><tt>h5diff</tt> – Exclude Object(s) from Comparison</a>" +ALIASES += ref_rfc20100422="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_gen_attribute_tool_v2_f.pdf\">Generating attributes into an object with a tool</a>" +ALIASES += ref_rfc20100312="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Support_HDF518_in_Tools.pdf\">Supporting HDF5 1.8 in HDF5 Command Line Tools</a>" +ALIASES += ref_rfc20091218="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RCF_h5diff_link_v1.2.docx.pdf\">Supporting soft-link and external-link for <tt>h5diff</tt></a>" +ALIASES += ref_rfc20090907="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_Tools_Lib_v2.pdf\">HDF5 Tools Library Functions</a>" +ALIASES += ref_rfc20090612="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_h5diff_default_epsilon.pdf\">Default EPSILON values for comparing floating point data</a>" +ALIASES += ref_rfc20081218="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_h5diff_NonComparable.pdf\">Reporting of Non-Comparable Datasets by <tt>h5diff</tt></a>" +ALIASES += ref_rfc20080915="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/FileFreeSpacePerformance.pdf\">Performance Report for Free-space Manager</a>" +ALIASES += ref_rfc20080904="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/ExternalLinkFileAccessProperty.pdf\">Setting File Access Property List for accessing External Link</a>" +ALIASES += ref_rfc20080301="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/DynamicTransformations_RFC.pdf\">Dynamic Transformations to HDF5 Data</a>" +ALIASES += ref_rfc20080209="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-Using-SVN-branching-Feb9.pdf\">Using SVN branching to improve software development process at THG</a>" +ALIASES += ref_rfc20080206="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC-HIS-REL-1.8_Feb6.pdf\">Maintaining the <tt>HISTORY.txt</tt> and <tt>RELEASE.txt</tt> files in HDF5</a>" +ALIASES += ref_rfc20071111="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/AURA-corruption-2007-11-12.pdf\">Addressing HDF5 file corruption issue</a>" +ALIASES += ref_rfc20071018="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/RFC_NaNsHDF5.pdf\"><tt>NaN</tt> detection in HDF5</a>" +ALIASES += ref_rfc20070801="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/Metadata_Journaling_RFC.pdf\">Metadata Journaling to Improve Crash Survivability</a>" +ALIASES += ref_rfc20070413="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/API_Compatibility_RFC.txt.pdf\">API Compatibility Strategies for HDF5</a>" +ALIASES += ref_rfc20070115="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/PrivateHeap.pdf\">A 'Private' Heap for HDF5</a>" +ALIASES += ref_rfc20060623="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/coll_ind_dd6.pdf\">Performance Comparison of Collective I/O and Independent I/O with Derived Datatypes</a>" +ALIASES += ref_rfc20060604="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/h5stat_spec_v3_2006-06-04.pdf\"><tt>h5stat</tt> tool</a>" +ALIASES += ref_rfc20060505="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/Simple%20Performance%20Test%20on%20Fletcher32%20Filter.pdf\">Simple Performance Test on Fletcher32 Filter</a>" +ALIASES += ref_rfc20060410="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/h5chk_Requirements.pdf\">Requirement Specifications of an HDF5 File Format Validation Tool</a>" +ALIASES += ref_rfc20060317="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/sec2driver-RFC.pdf\">Proposed changes to the <tt>sec2</tt> driver </a>" +ALIASES += ref_rfc20060124="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/FITS%20to%20HDF5%20mapping.pdf\">Mapping FITS data to HDF5</a>" +ALIASES += ref_rfc20040811="<a href=\"https://docs.hdfgroup.org/hdf5/rfc/text-dtype.htm.pdf\">Conversion Between Text and Datatype</a>" + +################################################################################ # The Usual Suspects ################################################################################ diff --git a/doxygen/dox/APIVersions.dox b/doxygen/dox/APIVersions.dox new file mode 100644 index 0000000..3658f06 --- /dev/null +++ b/doxygen/dox/APIVersions.dox @@ -0,0 +1,173 @@ +/** + * \ingroup H5A + * \def H5Acreate + * \api_vers_2{H5Acreate,H5Acreate1,H5Acreate2} + */ + +/** + * \ingroup H5A + * \def H5Aiterate + * \api_vers_2{H5Aiterate,H5Aiterate1,H5Aiterate2} + */ + +/** + * \ingroup H5D + * \def H5Dcreate + * \api_vers_2{H5Dcreate,H5Dcreate1,H5Dcreate2} + */ + +/** + * \ingroup H5E + * \def H5Eget_auto + * \api_vers_2{H5Eget_auto,H5Eget_auto1,H5Eget_auto2} + */ + +/** + * \ingroup H5E + * \def H5Eprint + * \api_vers_2{H5Eprint,H5Eprint1,H5Eprint2} + */ + +/** + * \ingroup H5E + * \def H5Epush + * \api_vers_2{H5Epush,H5Epush1,H5Epush2} + */ + +/** + * \ingroup H5E + * \def H5Eset_auto + * \api_vers_2{H5Eset_auto,H5Eset_auto1,H5Eset_auto2} + */ + +/** + * \ingroup H5E + * \def H5Ewalk + * \api_vers_2{H5Ewalk,H5Ewalk1,H5Ewalk2} + */ + +/** + * \ingroup H5F + * \def H5Fget_info + * \api_vers_2{H5Fget_info,H5Fget_info1,H5Fget_info2} + */ + +/** + * \ingroup H5G + * \def H5Gcreate + * \api_vers_2{H5Gcreate,H5Gcreate1,H5Gcreate2} + */ + +/** + * \ingroup H5G + * \def H5Gopen + * \api_vers_2{H5Gopen,H5Gopen1,H5Gopen2} + */ + +/** + * \ingroup H5L + * \def H5Lget_info + * \api_vers_2{H5Lget_info,H5Lget_info1,H5Lget_info2} + */ + +/** + * \ingroup H5L + * \def H5Lget_info_by_idx + * \api_vers_2{H5Lget_info_by_idx,H5Lget_info_by_idx1,H5Lget_info_by_idx2} + */ + +/** + * \ingroup TRAV + * \def H5Literate + * \api_vers_2{H5Literate,H5Literate1,H5Literate2} + */ + +/** + * \ingroup TRAV + * \def H5Literate_by_name + * \api_vers_2{H5Literate_by_name,H5Literate_by_name1,H5Literate_by_name2} + */ + +/** + * \ingroup TRAV + * \def H5Lvisit + * \api_vers_2{H5Lvisit,H5Lvisit1,H5Lvisit2} + */ + +/** + * \ingroup TRAV + * \def H5Lvisit_by_name + * \api_vers_2{H5Lvisit_by_name,H5Lvisit_by_name1,H5Lvisit_by_name2} + */ + +/** + * \ingroup H5O + * \def H5Oget_info + * \api_vers_3{H5Oget_info,H5Oget_info1,H5Oget_info2,H5Oget_info3} + */ + +/** + * \ingroup H5O + * \def H5Oget_info_by_idx + * \api_vers_3{H5Oget_info_by_idx,H5Oget_info_by_idx1,H5Oget_info_by_idx2,H5Oget_info_by_idx3} + */ + +/** + * \ingroup H5O + * \def H5Oget_info_by_name + * \api_vers_3{H5Oget_info_by_name,H5Oget_info_by_name1,H5Oget_info_by_name2,H5Oget_info_by_name3} + */ + +/** + * \ingroup H5O + * \def H5Ovisit + * \api_vers_3{H5Ovisit,H5Ovisit1,H5Ovisit2,H5Ovisit3} + */ + +/** + * \ingroup H5O + * \def H5Ovisit_by_name + * \api_vers_3{H5Ovisit_by_name,H5Ovisit_by_name1,H5Ovisit_by_name2,H5Ovisit_by_name3} + */ + +/** + * \ingroup H5R + * \def H5Rdereference + * \api_vers_2{H5Rdereference,H5Rdereference1,H5Rdereference2} + */ + +/** + * \ingroup H5R + * \def H5Rget_obj_type + * \api_vers_3{H5Rget_obj_type,H5Rget_obj_type1,H5Rget_obj_type2,H5R_get_obj_type3} + */ + +/** + * \ingroup H5S + * \def H5Sencode + * \api_vers_2{H5Sencode,H5Sencode1,H5Sencode2} + */ + +/** + * \ingroup H5T + * \def H5Tcommit + * \api_vers_2{H5Tcommit,H5Tcommit1,H5Tcommit2} + */ + +/** + * \ingroup H5T + * \def H5Topen + * \api_vers_2{H5Topen,H5Topen1,H5Topen2} + */ + +/** + * \ingroup ARRAY + * \def H5Tarray_create + * \api_vers_2{H5Tarray_create,H5Tarray_create1,H5Tarray_create2} + */ + +/** + * \ingroup ARRAY + * \def H5Tget_array_dims + * \api_vers_2{H5Tget_array_dims,H5Tget_array_dims1,H5Tget_array_dims2} + */ diff --git a/doxygen/dox/About.dox b/doxygen/dox/About.dox index 3be9202..d315566 100644 --- a/doxygen/dox/About.dox +++ b/doxygen/dox/About.dox @@ -1,5 +1,7 @@ /** \page About About +\section about_history History + The implementation of this documentation set is based on the fantastic work of the <a href="https://eigen.tuxfamily.org/index.php?title=Main_Page">Eigen project</a>. Please refer to their <a href="https://gitlab.com/libeigen/eigen">GitLab repository</a> @@ -8,4 +10,14 @@ and the online version of their Not only does Eigen set a standard as a piece of software, but also as an example of <em>documentation done right</em>. -*/ \ No newline at end of file +\section about_documentation Documentation about Documentation + +\li \todo Describe how to add a reference or a new RFC +\li \todo Describe how to add an example +\li \todo Describe how to include plain HTML +\li \todo Describe how to add an API macro +\li \todo Describe the custom commands +\li \todo Describe the S3 bucket layout and update routine +\li \todo Link the RM template + +*/ diff --git a/doxygen/dox/Cookbook.dox b/doxygen/dox/Cookbook.dox index 4abc896..666cfa1 100644 --- a/doxygen/dox/Cookbook.dox +++ b/doxygen/dox/Cookbook.dox @@ -2,4 +2,18 @@ Healthy, everyday recipes for every taste and budget... - */ \ No newline at end of file +\ref Files +\li \ref CB_FreeSpace +\li \ref CB_RemoveUnusedSpace +\li \ref CB_UserBlock + +\ref Attributes +\li \ref CB_LargeAttributes + +\ref Accessibility +\li \ref CB_MaintainCompat + +\ref Performance +\li \ref CB_MDCPerf + + */ diff --git a/doxygen/dox/H5Acreate.dox b/doxygen/dox/H5Acreate.dox deleted file mode 100644 index 18d648f..0000000 --- a/doxygen/dox/H5Acreate.dox +++ /dev/null @@ -1,9 +0,0 @@ -/** - * \ingroup H5A - * \def H5Acreate() - * H5Acreate() is a macro that is mapped to either H5Acreate1() or - * H5Acreate2(). - * - * - * \todo Standardize the way we describe these macros! - */ diff --git a/doxygen/dox/H5Aiterate.dox b/doxygen/dox/H5Aiterate.dox deleted file mode 100644 index 46b9bb4..0000000 --- a/doxygen/dox/H5Aiterate.dox +++ /dev/null @@ -1,9 +0,0 @@ -/** - * \ingroup H5A - * \def H5Aiterate() - * H5Aiterate() is a macro that is mapped to either H5Aiterate1() or - * H5Aiterate2(). - * - * - * \todo Standardize the way we describe these macros! - */ diff --git a/doxygen/dox/H5Fget_info.dox b/doxygen/dox/H5Fget_info.dox deleted file mode 100644 index 9b02752..0000000 --- a/doxygen/dox/H5Fget_info.dox +++ /dev/null @@ -1,44 +0,0 @@ -/** - * \ingroup H5F - * \def H5Fget_info() - * H5Fget_info() is a macro that is mapped to either H5Fget_info1() - * or H5Fget_info2(), depending on the needs of the application. - * Similarly, the macro for the \ref H5F_info_t struct is mapped to either - * H5F_info1_t or H5F_info2_t. - * - * Such macros are provided to facilitate application compatibility. - * Their use and mappings are fully described in \ref api-compat-macros. - * - * When both the HDF5 library and the application are built and installed with - * no specific compatibility flags, H5Fget_info() is mapped to the most recent - * version of the function, currently H5Fget_info2(). If the library and/or - * application is compiled for Release 1.8 emulation, H5Fget_info() will be - * mapped to H5Fget_info1(). Since there was no H5Fget_info() function in - * Release 1.6, if the library and/or application is compiled for Release 1.6 - * emulation, H5Fget_info() will be mapped to the most recent version of the - * function, currently H5Fget_info2(). Function-specific flags are available to - * override these settings on a function-by-function basis when the application - * is compiled. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * - * \Bold{Global settings}\n - * \li No compatibility flag: H5Fget_info2() and H5F_info2_t - * \li Enable deprecated symbols: H5Fget_info2() and H5F_info2_t - * \li Disable deprecated symbols: H5Fget_info2() and H5F_info2_t - * \li Emulate Release 1.6 interface: H5Fget_info2() and H5F_info2_t - * \li Emulate Release 1.8 interface: H5Fget_info1() and H5F_info1_t - * - * \Bold{Function- and struct-level macros}\n - * \li \Code{H5Fget_info_vers=2}: H5Fget_info2() - * \li \Code{H5Fget_info_vers=1}: H5Fget_info1() - * \li \Code{H5F_info_t_vers=2}: H5F_info2_t - * \li \Code{H5F_info_t_vers=1}: H5F_info1_t - * - * \version 1.10.0 The C function H5Fget_info() and H5F_info_t renamed to - * H5Fget_info1() and H5F_info1_t, respectively, and deprecated - * in this release. The C macro #H5Fget_info, the C function - * H5Fget_info2(), and the struct H5F_info2_t introduced in this - * release. - */ diff --git a/doxygen/dox/H5Lget_info.dox b/doxygen/dox/H5Lget_info.dox deleted file mode 100644 index 2c0971e..0000000 --- a/doxygen/dox/H5Lget_info.dox +++ /dev/null @@ -1,17 +0,0 @@ - /** - * \ingroup LMGT - * \def H5Lget_info() - * H5Lget_info() is a macro that is mapped to either H5Lget_info1() - * or H5Lget_info2() Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in \ref api-compat-macros. - * If the library and/or application is compiled for Release - * 1.12 emulation, H5Lget_info() will be mapped to H5Lget_info2() and - * H5Lget_info1() is deprecated. With earlier versions, H5Lget_info() is mapped to - * H5Lget_info1(). Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * \li No compatibility flag: H5Lget_info2() (using 1.12 source) H5Lget_info1() - * (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Lget_info2() - * \li Emulate Release 1.8 or 1.10 interface: H5Lget_info1() - * - */ diff --git a/doxygen/dox/H5Lget_info_by_idx.dox b/doxygen/dox/H5Lget_info_by_idx.dox deleted file mode 100644 index bf76822..0000000 --- a/doxygen/dox/H5Lget_info_by_idx.dox +++ /dev/null @@ -1,17 +0,0 @@ - /** - * \ingroup LMGT - * \def H5Lget_info_by_idx() - * H5Lget_info_by_idx() is a macro that is mapped to either H5Lget_info_by_idx1() - * or H5Lget_info_by_idx2() Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in \ref api-compat-macros. - * If the library and/or application is compiled for Release - * 1.12 emulation, H5Lget_info_by_idx() will be mapped to H5Lget_info_by_idx2() and - * H5Lget_info_by_idx1() is deprecated. With earlier versions, H5Lget_infoby_idx() is mapped to - * H5Lget_info_by_idx1(). Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * \li No compatibility flag: H5Lget_info_by_idx2() (using 1.12 source) H5Lget_info_by_idx1() - * (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Lget_info_by_idx2() - * \li Emulate Release 1.8 or 1.10 interface: H5Lget_info_by_idx1() - * - */ diff --git a/doxygen/dox/H5Literate.dox b/doxygen/dox/H5Literate.dox deleted file mode 100644 index eaaf2fe..0000000 --- a/doxygen/dox/H5Literate.dox +++ /dev/null @@ -1,20 +0,0 @@ -/** - * \ingroup TRAV - * \def H5Literate() - * H5Literate() is a macro that is mapped to either H5Literate1() or - * H5Literate2() Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * \ref api-compat-macros. If the library and/or application is - * compiled for Release 1.12 emulation, H5Literate() will be mapped to - * H5Literate2() and H5Literate1() is deprecated. With earlier versions, - * H5Literate() is mapped to H5Literate1(). Specific compile-time compatibility - * flags and the resulting mappings are as follows: - * \li No compatibility flag: H5Literate2() (using 1.12 source) H5Literate1() - * (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Literate2() - * \li Emulate Release 1.8 or 1.10 interface: H5Literate1() - * - * \version 1.12.0 The function H5Literate() was renamed to H5Literate1() and - * deprecated in this release. The macro H5Literate() and the - * function H5Literate2() were introduced in this release. - */ diff --git a/doxygen/dox/H5Literate_by_name.dox b/doxygen/dox/H5Literate_by_name.dox deleted file mode 100644 index 5ffd7c6..0000000 --- a/doxygen/dox/H5Literate_by_name.dox +++ /dev/null @@ -1,21 +0,0 @@ -/** - * \ingroup TRAV - * \def H5Literate_by_name() - * H5Literate_by_name() is a macro that is mapped to either - * H5Literate_by_name1() or H5Literate_by_name2() Such macros are provided to - * facilitate application compatibility. Their use and mappings are fully - * described in \ref api-compat-macros. If the library and/or application is - * compiled for Release 1.12 emulation, H5Literate_by_name() will be mapped to - * H5Literate_by_name2() and H5Literate_by_name1() is deprecated. With earlier - * versions, H5Literate_by_name() is mapped to H5Literate_by_name1(). - * Specific compile-time compatibility flags and the resulting mappings are as - * follows: - * \li No compatibility flag: H5Literate_by_name2() (using 1.12 source) - * H5Literate_by_name1() (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Literate_by_name2() - * \li Emulate Release 1.8 or 1.10 interface: H5Literate_by_name1() - * - * \version 1.12.0 The function H5Literate_by_name() was renamed to H5Literate_by_name1() and - * deprecated in this release. The macro H5Literate_by_name() and the - * function H5Literate_by_name2() were introduced in this release. - */ diff --git a/doxygen/dox/H5Lvisit.dox b/doxygen/dox/H5Lvisit.dox deleted file mode 100644 index 2dc547f..0000000 --- a/doxygen/dox/H5Lvisit.dox +++ /dev/null @@ -1,20 +0,0 @@ -/** - * \ingroup TRAV - * \def H5Lvisit() - * H5Lvisit() is a macro that is mapped to either H5Lvisit1() or - * H5Lvisit2() Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * \ref api-compat-macros. If the library and/or application is - * compiled for Release 1.12 emulation, H5Lvisit() will be mapped to - * H5Lvisit2() and H5Lvisit1() is deprecated. With earlier versions, - * H5Lvisit() is mapped to H5Lvisit1(). Specific compile-time compatibility - * flags and the resulting mappings are as follows: - * \li No compatibility flag: H5Lvisit2() (using 1.12 source) H5Lvisit1() - * (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Lvisit2() - * \li Emulate Release 1.8 or 1.10 interface: H5Lvisit1() - * - * \version 1.12.0 The function H5Lvisit() was renamed to H5Lvisit1() and - * deprecated in this release. The macro H5Lvisit() and the - * function H5Lvisit2() were introduced in this release. - */ diff --git a/doxygen/dox/H5Lvisit_by_name.dox b/doxygen/dox/H5Lvisit_by_name.dox deleted file mode 100644 index 691787f..0000000 --- a/doxygen/dox/H5Lvisit_by_name.dox +++ /dev/null @@ -1,20 +0,0 @@ -/** - * \ingroup TRAV - * \def H5Lvisit_by_name() - * H5Lvisit_by_name() is a macro that is mapped to either H5Lvisit_by_name1() or - * H5Lvisit_by_name2() Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * \ref api-compat-macros. If the library and/or application is - * compiled for Release 1.12 emulation, H5Lvisit_by_name() will be mapped to - * H5Lvisit_by_name2() and H5Lvisit_by_name1() is deprecated. With earlier versions, - * H5Lvisit_by_name() is mapped to H5Lvisit_by_name1(). Specific compile-time - * compatibility flags and the resulting mappings are as follows: - * \li No compatibility flag: H5Lvisit_by_name2() (using 1.12 source) H5Lvisit_by_name1() - * (using 1.10 or 1.8 source) - * \li Emulate Release 1.12: H5Lvisit_by_name2() - * \li Emulate Release 1.8 or 1.10 interface: H5Lvisit_by_name1() - * - * \version 1.12.0 The function H5Lvisit_by_name() was renamed to H5Lvisit_by_name1() and - * deprecated in this release. The macro H5Lvisit_by_name() and the - * function H5Lvisit_by_name2() were introduced in this release. - */ diff --git a/doxygen/dox/H5Oget_info.dox b/doxygen/dox/H5Oget_info.dox deleted file mode 100644 index ee4cd1c..0000000 --- a/doxygen/dox/H5Oget_info.dox +++ /dev/null @@ -1,72 +0,0 @@ -/** - * \ingroup H5O - * \def H5Oget_info - * - * #H5Oget_info is a macro that is mapped to: - * \li #H5Oget_info3 - * \li #H5Oget_info1 - * - * \details Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * API Compatibility Macros in HDF5; we urge you to read that - * document closely. - * - * In HDF5 versions 1.12 and after, #H5Oget_info is mapped to - * #H5Oget_info3 and #H5Oget_info1 is deprecated. - * In version 1.10 #H5Oget_info is identical to #H5Oget_info1. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * \par - * <table> - * <tr> - * <th>Compatibility setting</th> - * <th>H5Oget_info</th> - * </tr> - * <tr> - * <td>No compatibility flag \n  </td> - * <td>#H5Oget_info3 (in release 1.12) \n - * #H5Oget_info1 (in 1.8 or 1.10)</td> - * </tr> - * <tr> - * <td>Emulate Release 1.12</td> - * <td>#H5Oget_info3</td> - * </tr> - * <tr> - * <td>Emulate Release 1.10/1.8 interface</td> - * <td>#H5Oget_info1</td> - * </tr> - * </table> - * - * \note If you are iterating through a lot of different objects to - * retrieve information via the #H5Oget_info family of routines, - * you may see memory building up. This can be due to memory - * allocation for metadata such as object headers and messages - * when the iterated objects are put into the metadata cache. - * \note - * If the memory buildup is not desirable, you can configure a - * smaller cache via #H5Fset_mdc_config or set the file access - * property list via #H5Pset_mdc_config. A smaller sized cache - * will force metadata entries to be evicted from the cache, - * thus freeing the memory associated with the entries. - * - * \version 1.12.0 The macro #H5Oget_info and the function #H5Oget_info3 - * were added, and #H5Oget_info1 was deprecated. - * \version 1.10.5 The macro #H5Oget_info was removed. The functions - * #H5Oget_info1 and #H5Oget_info are identical - * in this release. This change was added to restore the - * broken API compatibility introduced in HDF5-1.10.3. - * \version 1.10.3 The function #H5Oget_info was renamed - * #H5Oget_info1. The macro #H5Oget_info and the function - * #H5Oget_info2 were introduced in this release. - * \version 1.8.15 Added a note about the valid values for the \c version field - * in the H5O_hdr_info_t structure. - * \version 1.8.11 Fortran subroutine introduced in this release. - * \version 1.8.10 Added #H5O_type_t structure to the Description section. - * Separated H5O_hdr_info_t structure from - * #H5O_info_t in the Description section. Clarified the - * definition and implementation of the time fields. - * - * \since 1.8.0 - * - */ diff --git a/doxygen/dox/H5Oget_info_by_idx.dox b/doxygen/dox/H5Oget_info_by_idx.dox deleted file mode 100644 index 49b8031..0000000 --- a/doxygen/dox/H5Oget_info_by_idx.dox +++ /dev/null @@ -1,55 +0,0 @@ -/** - * \ingroup H5O - * \def H5Oget_info_by_idx - * - * #H5Oget_info_by_idx is a macro that is mapped to: - * \li #H5Oget_info_by_idx3 - * \li #H5Oget_info_by_idx1 - * - * \details Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * API Compatibility Macros in HDF5; we urge you to read that - * document closely. - * - * In HDF5 versions 1.12 and after, #H5Oget_info_by_idx is mapped to - * #H5Oget_info_by_idx3 and #H5Oget_info_by_idx1 is deprecated. - * In version 1.10 #H5Oget_info_by_idx is identical to #H5Oget_info_by_idx1. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * - * \par - * <table> - * <tr> - * <th>Compatibility setting</th> - * <th>H5Oget_info_by_idx</th> - * </tr> - * <tr> - * <td>No compatibility flag \n  </td> - * <td>#H5Oget_info_by_idx3 for 1.12 \n - * #H5Oget_info_by_idx1 for 1.8/1.10</td> - * </tr> - * <tr> - * <td>Emulate Release 1.12</td> - * <td>#H5Oget_info_by_idx3</td> - * </tr> - * <tr> - * <td>Emulate Release 1.10/1.8 interface</td> - * <td>#H5Oget_info_by_idx1</td> - * </tr> - * </table> - * - * \version 1.12.0 The macro #H5Oget_info_by_idx and function #H5Oget_info_by_idx3 were added, - * and #H5Oget_info_by_idx1 was deprecated. - * \version 1.10.5 The macro #H5Oget_info_by_idx was removed. The functions - * #H5Oget_info_by_idx and #H5Oget_info_by_idx1 are - * identical in this release. This change was added to restore the - * broken API compatibility introduced in HDF5-1.10.3. - * \version 1.10.3 The function #H5Oget_info_by_idx was renamed #H5Oget_info_by_idx1. - * The macro #H5Oget_info_by_idx and the function #H5Oget_info_by_idx2 - * were introduced in this release. - * \version 1.8.11 Fortran subroutine introduced in this release. - * - * \since 1.8.0 - * - */ diff --git a/doxygen/dox/H5Oget_info_by_name.dox b/doxygen/dox/H5Oget_info_by_name.dox deleted file mode 100644 index 18f7d28..0000000 --- a/doxygen/dox/H5Oget_info_by_name.dox +++ /dev/null @@ -1,58 +0,0 @@ -/** - * \ingroup H5O - * \def H5Oget_info_by_name - * - * #H5Oget_info_by_name is a macro that is mapped to: - * \li #H5Oget_info_by_name3 - * \li #H5Oget_info_by_name1 - * - * \details Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * API Compatibility Macros in HDF5; we urge you to read that - * document closely. - * - * In HDF5 versions 1.12 and after, #H5Oget_info_by_name is mapped to - * #H5Oget_info_by_name3. In version 1.10 #H5Oget_info_by_name is - * identical to #H5Oget_info_by_name1. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * - * \par - * <table> - * <tr> - * <th>Compatibility setting</th> - * <th>H5Oget_info_by_name</th> - * </tr> - * <tr> - * <td>No compatibility flag \n  </td> - * <td>#H5Oget_info_by_name3 for 1.12 and above \n - * #H5Oget_info_by_name1 for 1.8 or 1.10</td> - * </tr> - * <tr> - * <td>Emulate Release 1.12</td> - * <td>#H5Oget_info_by_name3</td> - * </tr> - * <tr> - * <td>Emulate Release 1.10 or 1.8 interface</td> - * <td>#H5Oget_info_by_name1</td> - * </tr> - * </table> - * - * \version 1.12.0 The macro #H5Oget_info_by_name and function - * #H5Oget_info_by_name3 were added and - * #H5Oget_info_by_name1 was deprecated. - * \version 1.10.5 The macro #H5Oget_info_by_name was removed. The functions - * #H5Oget_info_by_name and #H5Oget_info_by_name1 are - * identical in this release. This change was added to restore - * the broken API compatibility introduced in HDF5-1.10.3. - * \version 1.10.3 The function #H5Oget_info_by_name was renamed - * to #H5Oget_info_by_name1. The macro #H5Oget_info_by_name - * and the function #H5Oget_info_by_name2 were introduced - * in this release. - * \version 1.8.8 Fortran 2003 subroutine and \c h5o_info_t derived - * type introduced in this release.</td> - * - * \since 1.8.0 - * - */ diff --git a/doxygen/dox/H5Ovisit.dox b/doxygen/dox/H5Ovisit.dox deleted file mode 100644 index 1e2a3ea..0000000 --- a/doxygen/dox/H5Ovisit.dox +++ /dev/null @@ -1,55 +0,0 @@ -/** - * \ingroup H5O - * \def H5Ovisit - * - * #H5Ovisit is a macro that is mapped to one of the following: - * \li #H5Ovisit3 - * \li #H5Ovisit1 - * - * \details Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * API Compatibility Macros in HDF5; we urge you to read that - * document closely. - * - * In HDF5 versions 1.12 and after, #H5Ovisit is mapped to - * #H5Ovisit3. In version 1.10, #H5Ovisit is identical - * to #H5Ovisit1. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * - * \par - * <table> - * <tr> - * <th>Compatibility settings</th> - * <th>H5Ovisit</th> - * </tr> - * <tr> - * <td>No compatibility flag \n  </td> - * <td>#H5Ovisit3 in 1.12 or after \n - * #H5Ovisit1 for 1.8 and 1.10</td> - * </tr> - * <tr> - * <td>Emulate Release 1.12</td> - * <td>#H5Ovisit3</td> - * </tr> - * <tr> - * <td>Emulate Release 1.10 or 1.8 interface</td> - * <td>#H5Ovisit1</td> - * </tr> - * </table> - * - * \version 1.12.0 The macro #H5Ovisit and function #H5Ovisit3 were added, - * and #H5Ovisit1 was deprecated. - * \version 1.10.5 The macro #H5Ovisit was removed. The functions - * #H5Ovisit and #H5Ovisit1 are identical in this release. - * This change was added to restore the broken API compatibility - * introduced in HDF5-1.10.3. - * \version 1.10.3 The function #H5Ovisit was renamed to #H5Ovisit1. - * The macro #H5Ovisit and the function #H5Ovisit2 were - * introduced in this release. - * \version 1.8.8 Fortran subroutine and data structure added. - * - * \since 1.8.0 - * - */ diff --git a/doxygen/dox/H5Ovisit_by_name.dox b/doxygen/dox/H5Ovisit_by_name.dox deleted file mode 100644 index 2ba4846..0000000 --- a/doxygen/dox/H5Ovisit_by_name.dox +++ /dev/null @@ -1,54 +0,0 @@ -/** - * \ingroup H5O - * \def H5Ovisit_by_name - * - * #H5Ovisit_by_name is a macro that is mapped to one of the following: - * \li #H5Ovisit_by_name3 - * \li #H5Ovisit_by_name1 - * - * \details Such macros are provided to facilitate application - * compatibility. Their use and mappings are fully described in - * API Compatibility Macros in HDF5; we urge you to read that - * document closely. - * - * In HDF5 versions 1.12 and after, #H5Ovisit_by_name is mapped to - * #H5Ovisit_by_name3. In version 1.10, #H5Ovisit_by_name - * is identical to #H5Ovisit_by_name1. - * - * Specific compile-time compatibility flags and the resulting - * mappings are as follows: - * - * \par - * <table> - * <tr> - * <th>Compatibility settings</th> - * <th>H5Ovisit_by_name</th> - * </tr> - * <tr> - * <td>No compatibility flag \n  </td> - * <td>#H5Ovisit_by_name3 for 1.12 and above \n - * #H5Ovisit_by_name1 for 1.10 or 1.8</td> - * </tr> - * <tr> - * <td>Emulate Release 1.12 interface</td> - * <td>#H5Ovisit_by_name3</td> - * </tr> - * <tr> - * <td>Emulate Release 1.10 or 1.8 interface</td> - * <td>#H5Ovisit_by_name1</td> - * </tr> - * </table> - * - * \version 1.12.0 The macro #H5Ovisit_by_name and function #H5Ovisit_by_name3 were added. - * \version 1.10.5 The macro #H5Ovisit_by_name was removed. The functions - * #H5Ovisit_by_name and #H5Ovisit_by_name1 are identical - * in this release. This change was added to restore the - * broken API compatibility introduced in HDF5-1.10.3. - * \version 1.10.3 The function #H5Ovisit_by_name was renamed to #H5Ovisit_by_name1. - * The macro #H5Ovisit_by_name and the function #H5Ovisit_by_name2 - * were introduced in this release. - * \version 1.8.8 Fortran subroutine introduced in this release. - * - * \since 1.8.0 - * - */ diff --git a/doxygen/dox/H5Sencode.dox b/doxygen/dox/H5Sencode.dox deleted file mode 100644 index fe0995c..0000000 --- a/doxygen/dox/H5Sencode.dox +++ /dev/null @@ -1,5 +0,0 @@ -/** - * \ingroup H5S - * \def H5Sencode() - * H5Sencode() is a macro that is mapped to either H5Sencode1() or H5Sencode2(). -*/ diff --git a/doxygen/dox/MetadataCachingInHDF5.dox b/doxygen/dox/MetadataCachingInHDF5.dox index 9ba0fab..9b8e446 100644 --- a/doxygen/dox/MetadataCachingInHDF5.dox +++ b/doxygen/dox/MetadataCachingInHDF5.dox @@ -668,7 +668,7 @@ reduction. With the hit rate threshold cache size decrement algorithm, the remaining fields in the section are ignored. -\subsubsection acsr Ageout Cache Size Reduction +\subsubsection dacsr Ageout Cache Size Reduction If \ref H5AC_cache_config_t.decr_mode "decr_mode" is #H5C_decr__age_out the cache size is decreased by the ageout algorithm, and the remaining fields of the @@ -692,7 +692,7 @@ The \ref H5AC_cache_config_t.decrement "decrement" and \ref H5AC_cache_config_t.upper_hr_threshold "upper_hr_threshold" fields are ignored in this case. -\subsubsection awhrtcsr Ageout With Hit Rate Threshold Cache Size Reduction +\subsubsection dawhrtcsr Ageout With Hit Rate Threshold Cache Size Reduction If \ref H5AC_cache_config_t.decr_mode "decr_mode" is #H5C_decr__age_out_with_threshold, the cache size is decreased by the ageout @@ -1017,4 +1017,4 @@ and the average successful and unsuccessful search depths in the hash table. If these latter figures are significantly above 1, you should increase the size of the hash table. - */ \ No newline at end of file + */ diff --git a/doxygen/dox/RFC.dox b/doxygen/dox/RFC.dox new file mode 100644 index 0000000..c16dcea --- /dev/null +++ b/doxygen/dox/RFC.dox @@ -0,0 +1,91 @@ +/** \page RFC RFCs + +<table> +<tr><th>RFC ID</th><th>Title</th><th>Comments</th></tr> +<tr> <td>2021-05-28</td> <td>\ref_rfc20210528</td> <td></td></tr> +<tr> <td>2019-09-23</td> <td>\ref_rfc20190923</td> <td></td></tr> +<tr> <td>2019-04-10</td> <td>\ref_rfc20190410</td> <td></td> </tr> +<tr> <td>2018-12-31</td> <td>\ref_rfc20181231</td> <td></td> </tr> +<tr> <td>2018-12-20</td> <td>\ref_rfc20181220</td> <td></td> </tr> +<tr> <td>2018-06-20</td> <td>\ref_rfc20180620</td> <td></td> </tr> +<tr> <td>2018-06-10</td> <td>\ref_rfc20180610</td> <td></td> </tr> +<tr> <td>2018-03-21</td> <td>\ref_rfc20180321</td> <td></td> </tr> +<tr> <td>2018-01-25</td> <td>\ref_rfc20180125</td> <td></td> </tr> +<tr> <td>2017-07-07</td> <td>\ref_rfc20170707</td> <td></td> </tr> +<tr> <td>2016-01-05</td> <td>\ref_rfc20160105</td> <td></td> </tr> +<tr> <td>2015-09-15</td> <td>\ref_rfc20150915</td> <td></td> </tr> +<tr> <td>2015-07-09</td> <td>\ref_rfc20150709</td> <td></td> </tr> +<tr> <td>2015-06-15</td> <td>\ref_rfc20150615</td> <td></td> </tr> +<tr> <td>2015-04-29</td> <td>\ref_rfc20150429</td> <td></td> </tr> +<tr> <td>2015-04-24</td> <td>\ref_rfc20150424</td> <td></td> </tr> +<tr> <td>2015-04-23</td> <td>\ref_rfc20150423</td> <td></td> </tr> +<tr> <td>2015-03-01</td> <td>\ref_rfc20150301</td> <td></td> </tr> +<tr> <td>2015-02-12</td> <td>\ref_rfc20150212</td> <td></td> </tr> +<tr> <td>2015-02-05</td> <td>\ref_rfc20150205</td> <td></td> </tr> +<tr> <td>2015-02-02</td> <td>\ref_rfc20150202</td> <td></td> </tr> +<tr> <td>2014-12-10</td> <td>\ref_rfc20141210</td> <td></td> </tr> +<tr> <td>2014-12-01</td> <td>\ref_rfc20141201</td> <td></td> </tr> +<tr> <td>2014-09-16</td> <td>\ref_rfc20140916</td> <td></td> </tr> +<tr> <td>2014-08-27</td> <td>\ref_rfc20140827</td> <td></td> </tr> +<tr> <td>2014-07-29</td> <td>\ref_rfc20140729</td> <td></td> </tr> +<tr> <td>2014-07-22</td> <td>\ref_rfc20140722</td> <td></td> </tr> +<tr> <td>2014-07-17</td> <td>\ref_rfc20140717</td> <td></td> </tr> +<tr> <td>2014-07-07</td> <td>\ref_rfc20140707</td> <td></td> </tr> +<tr> <td>2014-05-24</td> <td>\ref_rfc20140524</td> <td></td> </tr> +<tr> <td>2014-03-18</td> <td>\ref_rfc20140318</td> <td></td> </tr> +<tr> <td>2014-03-13</td> <td>\ref_rfc20140313</td> <td></td> </tr> +<tr> <td>2014-02-24</td> <td>\ref_rfc20140224</td> <td></td> </tr> +<tr> <td>2013-12-11</td> <td>\ref_rfc20131211</td> <td></td> </tr> +<tr> <td>2013-09-30</td> <td>\ref_rfc20130930</td> <td></td> </tr> +<tr> <td>2013-09-19</td> <td>\ref_rfc20130919</td> <td></td> </tr> +<tr> <td>2013-06-30</td> <td>\ref_rfc20130630</td> <td></td> </tr> +<tr> <td>2013-03-16</td> <td>\ref_rfc20130316</td> <td></td> </tr> +<tr> <td>2012-11-14</td> <td>\ref_rfc20121114</td> <td></td> </tr> +<tr> <td>2012-10-24</td> <td>\ref_rfc20121024</td> <td></td> </tr> +<tr> <td>2012-08-28</td> <td>\ref_rfc20120828</td> <td></td> </tr> +<tr> <td>2012-05-23</td> <td>\ref_rfc20120523</td> <td></td> </tr> +<tr> <td>2012-05-01</td> <td>\ref_rfc20120501</td> <td></td> </tr> +<tr> <td>2012-03-05</td> <td>\ref_rfc20120305</td> <td></td> </tr> +<tr> <td>2012-02-20</td> <td>\ref_rfc20120220</td> <td></td> </tr> +<tr> <td>2012-01-20</td> <td>\ref_rfc20120120</td> <td></td> </tr> +<tr> <td>2012-01-04</td> <td>\ref_rfc20120104</td> <td></td> </tr> +<tr> <td>2011-11-19</td> <td>\ref_rfc20111119</td> <td></td> </tr> +<tr> <td>2011-08-25</td> <td>\ref_rfc20110825</td> <td></td> </tr> +<tr> <td>2011-08-11</td> <td>\ref_rfc20110811</td> <td></td> </tr> +<tr> <td>2011-07-26</td> <td>\ref_rfc20110726</td> <td></td> </tr> +<tr> <td>2011-06-14</td> <td>\ref_rfc20110614</td> <td></td> </tr> +<tr> <td>2011-03-29</td> <td>\ref_rfc20110329</td> <td></td> </tr> +<tr> <td>2011-01-18</td> <td>\ref_rfc20110118</td> <td></td> </tr> +<tr> <td>2010-11-22</td> <td>\ref_rfc20101122</td> <td></td> </tr> +<tr> <td>2010-11-04</td> <td>\ref_rfc20101104</td> <td></td> </tr> +<tr> <td>2010-10-18</td> <td>\ref_rfc20101018</td> <td></td> </tr> +<tr> <td>2010-09-02</td> <td>\ref_rfc20100902</td> <td></td> </tr> +<tr> <td>2010-07-27</td> <td>\ref_rfc20100727</td> <td></td> </tr> +<tr> <td>2010-07-26</td> <td>\ref_rfc20100726</td> <td></td> </tr> +<tr> <td>2010-05-11</td> <td>\ref_rfc20100511</td> <td></td> </tr> +<tr> <td>2010-04-22</td> <td>\ref_rfc20100422</td> <td></td> </tr> +<tr> <td>2010-03-12</td> <td>\ref_rfc20100312</td> <td></td> </tr> +<tr> <td>2009-12-18</td> <td>\ref_rfc20091218</td> <td></td> </tr> +<tr> <td>2009-09-07</td> <td>\ref_rfc20090907</td> <td></td> </tr> +<tr> <td>2009-06-12</td> <td>\ref_rfc20090612</td> <td></td> </tr> +<tr> <td>2008-12-18</td> <td>\ref_rfc20081218</td> <td></td> </tr> +<tr> <td>2008-09-15</td> <td>\ref_rfc20080915</td> <td></td> </tr> +<tr> <td>2008-09-04</td> <td>\ref_rfc20080904</td> <td></td> </tr> +<tr> <td>2008-03-01</td> <td>\ref_rfc20080301</td> <td></td> </tr> +<tr> <td>2008-02-09</td> <td>\ref_rfc20080209</td> <td></td> </tr> +<tr> <td>2008-02-06</td> <td>\ref_rfc20080206</td> <td></td> </tr> +<tr> <td>2007-11-11</td> <td>\ref_rfc20071111</td> <td></td> </tr> +<tr> <td>2007-10-18</td> <td>\ref_rfc20071018</td> <td></td> </tr> +<tr> <td>2007-08-01</td> <td>\ref_rfc20070801</td> <td></td> </tr> +<tr> <td>2007-04-13</td> <td>\ref_rfc20070413</td> <td></td> </tr> +<tr> <td>2007-01-15</td> <td>\ref_rfc20070115</td> <td></td> </tr> +<tr> <td>2006-06-23</td> <td>\ref_rfc20060623</td> <td></td> </tr> +<tr> <td>2006-06-04</td> <td>\ref_rfc20060604</td> <td></td> </tr> +<tr> <td>2006-05-05</td> <td>\ref_rfc20060505</td> <td></td> </tr> +<tr> <td>2006-04-10</td> <td>\ref_rfc20060410</td> <td></td> </tr> +<tr> <td>2006-03-17</td> <td>\ref_rfc20060317</td> <td></td> </tr> +<tr> <td>2006-01-24</td> <td>\ref_rfc20060124</td> <td></td> </tr> +<tr> <td>2004-08-11</td> <td>\ref_rfc20040811</td> <td></td> </tr> +</table> + +*/ \ No newline at end of file diff --git a/doxygen/dox/ReferenceManual.dox b/doxygen/dox/ReferenceManual.dox index 596a224..1de53f2 100644 --- a/doxygen/dox/ReferenceManual.dox +++ b/doxygen/dox/ReferenceManual.dox @@ -3,41 +3,87 @@ The functions provided by the HDF5 C-API are grouped into the following \Emph{modules}: -\li \ref H5A "Attributes" — Management of HDF5 attributes (\ref H5A) -\li \ref H5D "Datasets" — Management of HDF5 datasets (\ref H5D) -\li \ref H5S "Dataspaces" — Management of HDF5 dataspaces which describe the shape of datasets and attributes (\ref H5S) -\li \ref H5T "Datatypes" — Management of datatypes which describe elements of datasets and attributes (\ref H5T) -\li \ref H5E "Error Handling" — Functions for handling HDF5 errors (\ref H5E) -\li \ref H5ES "Event Sets" — Functions for handling HDF5 event sets (\ref H5ES) -\li \ref H5F "Files" — Management of HDF5 files (\ref H5F) -\li \ref H5Z "Filters" — Configuration of filters that process data during I/O operation (\ref H5Z) -\li \ref H5G "Groups" — Management of groups in HDF5 files (\ref H5G) -\li \ref H5I "Identifiers" — Management of object identifiers and object names (\ref H5I) -\li \ref H5 "Library" — General purpose library functions (\ref H5) -\li \ref H5L "Links" — Management of links in HDF5 groups (\ref H5L) -\li \ref H5M "Maps" — Management of HDF5 maps (\ref H5M) -\li \ref H5O "Objects" — Management of objects in HDF5 files (\ref H5O) -\li \ref H5PL "Plugins" — Programmatic control over dynamically loaded plugins (\ref H5PL) -\li \ref H5P "Property Lists" — Management of property lists to control HDF5 library behavior (\ref H5P) -\li \ref H5R "References" — Management of references to specific objects and data regions in an HDF5 file (\ref H5R) -\li \ref H5VL "Virtual Object Layer" — Management of the Virtual Object Layer (\ref H5VL) - -\par Asynchronous Functions - A subset of functions has \ref ASYNC "asynchronous variants". - -\par API Versioning - See \ref api-compat-macros - -\par Deprecated Functions and Types - A list of deprecated functions and types can be found - <a href="./deprecated.html">here</a>. - -\par Etiquette - Here are a few simple rules to follow: - \li \Bold{Handle discipline:} If you acquire a handle (by creation or copy), \Emph{you own it!} (..., i.e., you have to close it.) - \li \Bold{Dynamic memory allocation:} ... - \li \Bold{Use of locations:} Identifier + name combo +<table> +<tr><th>Modules</th></tr> +<tr valign="top"> +<td> + +<table> +<tr><td style="border: none;"> +\li \ref H5A "Attributes (H5A)" +\li \ref H5D "Datasets (H5D)" +\li \ref H5S "Dataspaces (H5S)" +\li \ref H5T "Datatypes (H5T)" +\li \ref H5E "Error Handling (H5E)" +\li \ref H5ES "Event Sets (H5ES)" +\li \ref H5F "Files (H5F)" +\li \ref H5Z "Filters (H5Z)" +\li \ref H5G "Groups (H5G)" +</td><td style="border: none;"> +\li \ref H5I "Identifiers (H5I)" +\li \ref H5 "Library General (H5)" +\li \ref H5L "Links (H5L)" +\li \ref H5M "Maps (H5M)" +\li \ref H5O "Objects (H5O)" +\li \ref H5P "Property Lists (H5P)" +\li \ref H5PL "Dynamically-loaded Plugins (H5PL)" +\li \ref H5R "References (H5R)" +\li \ref H5VL "Virtual Object Layer (H5VL)" +</td><td style="border: none;vertical-align: top;"> +\li Functions with \ref ASYNC "asynchronous variants" +\li \ref api-compat-macros +\li <a href="./deprecated.html">Deprecated functions</a> +\li High-level Extensions + <ul> + <li><a href="https://portal.hdfgroup.org/display/HDF5/Lite">\Bold{HDF5 Lite} (H5LT)</a></li> + <li><a href="https://portal.hdfgroup.org/display/HDF5/Images">\Bold{HDF5 Image} (H5IM)</a></li> + <li><a href="https://portal.hdfgroup.org/display/HDF5/Tables">\Bold{HDF5 Table} (H5TB)</a></li> + <li><a href="https://portal.hdfgroup.org/display/HDF5/Packet+Tables">\Bold{HDF5 Packet Table} (H5TB)</a></li> + <li><a href="https://portal.hdfgroup.org/display/HDF5/Dimension+Scales">\Bold{HDF5 Dimension Scale} (H5DS)</a></li> + </ul> +</td></tr> +<tr><td colspan="3" style="border: none;"> +\ref H5 \ref H5A \ref H5D \ref H5E \ref H5ES \ref H5F \ref H5G \ref H5I \ref H5L +\ref H5M \ref H5O \ref H5P \ref H5PL \ref H5R \ref H5S \ref H5T \ref H5VL \ref H5Z +</td></tr> +</table> + +</td></tr> +<tr><th>Mind the gap</th></tr> +<tr><td> +Follow these simple rules and stay out of trouble: + +\li \Bold{Handle discipline:} The HDF5 C-API is rife with handles or + identifiers, which you typically obtain by creating new HDF5 items, copying + items, or retrieving facets of items. \Emph{You acquire a handle, you own it!} + (Colin Powell) In other words, you are responsible for releasing the underlying + resources via the matching \Code{H5*close()} call, or deal with the consequences + of resource leakage. +\li \Bold{Closed means closed:} Do not pass identifiers that were previously + \Code{H5*close()}-d to other API functions! It will generate an error. +\li \Bold{Dynamic memory allocation:} The API contains a few functions in which the + HDF5 library dynamically allocates memory on the caller's behalf. The caller owns + this memory and eventually must free it by calling H5free_memory(). (\Bold{Not} + the `free` function \Emph{du jour}!) +\li \Bold{Be careful with that saw:} Do not modify the underlying collection when an + iteration is in progress! +\li \Bold{Use of locations:} Certain API functions, typically called \Code{H5***_by_name} + use a combination of identifiers and path names to refer to HDF5 objects. + If the identifier fully specifies the object in question, pass \Code{'.'} (a dot) + for the name! + +Break a leg! +</td> +</tr> +</table> \cpp_c_api_note -*/ \ No newline at end of file +\par Don't like what you see? - You can help to improve this Reference Manual + Complete the survey linked near the top of this page!\n + We treat documentation like code: Fork the + <a href="https://github.com/HDFGroup/hdf5">HDF5 repo</a>, make changes, and create a + <a href="https://github.com/HDFGroup/hdf5/pulls">pull request</a> !\n + See the \ref RMT for general guidance. + +*/ diff --git a/doxygen/dox/cookbook/Accessibility.c b/doxygen/dox/cookbook/Accessibility.c new file mode 100644 index 0000000..f4cc905 --- /dev/null +++ b/doxygen/dox/cookbook/Accessibility.c @@ -0,0 +1,48 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [set_libver_bounds] --> + { + __label__ fail_fapl, fail_file; + hid_t fapl, file, aspace, attr; + + if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_fapl; + } +#if H5_VERSION_GE(1, 10, 0) + if (H5Pset_libver_bounds(fapl, H5F_LIBVER_V18, H5F_LIBVER_V18) < 0) { +#elif H5_VERSION_GE(1, 8, 0) + if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) { +#else +#error Only HDF5 1.8.x and later supported. +#endif + ret_val = EXIT_FAILURE; + goto fail_file; + } + if ((file = H5Fcreate("set_libver_bounds.h5", H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + H5Fclose(file); +fail_file: + H5Pclose(fapl); +fail_fapl:; + } + //! <!-- [set_libver_bounds] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/dox/cookbook/Accessibility.dox b/doxygen/dox/cookbook/Accessibility.dox new file mode 100644 index 0000000..f100283 --- /dev/null +++ b/doxygen/dox/cookbook/Accessibility.dox @@ -0,0 +1,39 @@ +/** \page Accessibility + +\section Accessibility + +\subsection CB_MaintainCompat Maintaining Compatibility with other HDF5 Library Versions + +\par Problem +You want to ensure that the HDF5 files you produce or modify are accessible by all +releavnt tools and applications + +\par Solution +For HDF5 items (objects, attributes, etc.) that you would like to +create in new or existing HDF5 files, ascertain the supported range of HDF5 +library versions as lower and upper bounds. When creating new or opening +existing HDF5 files, use a file access property list and configure the supported +range via the H5Pset_libver_bounds() function.\n +In the example below, we restrict HDF5 item creation to the HDF5 1.8.x family of +library versions. +\snippet{lineno} Accessibility.c set_libver_bounds + +\par Discussion +See RFC \ref_rfc20160105 for a detailed and comprehensive account of HDF5 +versioning (library, file format spec., etc.) and the H5Pset_libver_bounds() +function.\n +The default range #H5F_LIBVER_EARLIEST (low) - #H5F_LIBVER_LATEST (high) offers the +widest compatibility range, but may not be suitable for certain (feature-)use +cases.\n +The HDF5 library comes with a \Emph{forward-} and \Emph{backward-compatibility} +guarantee: This means that the latest version of the library can always read +HDF5 files created by a version realesed earlier (backward compatibility). +It also means that a given release of the library can read the contents of +HDF5 files created with later versions of the library as long as the files +do not contain features introduced in later versions (forward compatibility). + +\par See Also +See the recipe \ref CB_LargeAttributes for an example where we use HDF5 +compatibility settings to enable the creation of large HDF5 attributes. + +*/ \ No newline at end of file diff --git a/doxygen/dox/cookbook/Attributes.c b/doxygen/dox/cookbook/Attributes.c new file mode 100644 index 0000000..f4e894f --- /dev/null +++ b/doxygen/dox/cookbook/Attributes.c @@ -0,0 +1,61 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [large_attribute] --> + { + __label__ fail_attr, fail_aspace, fail_fapl, fail_file; + hid_t fapl, file, aspace, attr; + + if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_fapl; + } +#if H5_VERSION_GE(1, 10, 0) + if (H5Pset_libver_bounds(fapl, H5F_LIBVER_V18, H5F_LIBVER_LATEST) < 0) { +#elif H5_VERSION_GE(1, 8, 0) + if (H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) { +#else +#error Only HDF5 1.8.x and later supported. +#endif + ret_val = EXIT_FAILURE; + goto fail_file; + } + if ((file = H5Fcreate("large_attribute.h5", H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + if ((aspace = H5Screate_simple(1, (hsize_t[]){1024 * 1024}, NULL)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_aspace; + } + if ((attr = H5Acreate(file, "4MiB", H5T_IEEE_F32LE, aspace, H5P_DEFAULT, H5P_DEFAULT)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_attr; + } + + H5Aclose(attr); +fail_attr: + H5Sclose(aspace); +fail_aspace: + H5Fclose(file); +fail_file: + H5Pclose(fapl); +fail_fapl:; + } + //! <!-- [large_attribute] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/dox/cookbook/Attributes.dox b/doxygen/dox/cookbook/Attributes.dox new file mode 100644 index 0000000..68fd159 --- /dev/null +++ b/doxygen/dox/cookbook/Attributes.dox @@ -0,0 +1,38 @@ +/** \page Attributes + +\section Attributes + +\subsection CB_LargeAttributes Creating "Large" HDF5 Attributes + +\par Problem +You would like to use HDF5 attributes the size of whose values +exceeds a few dozen kilobytes + +\par Solution +A file format change in the HDF5 1.8.x family of library releases made it +possible to have attributes larger than about 64 KiB. Ensure that the lower +library version bound for new HDF5 item creation is at least 1.8.x, and create +larger attributes as usual.\n +In the example below, we create an attribute whose value occupies 4 MiB. + +\note This feature is only supported in HDF5 1.8.x+ + +\snippet{lineno} Attributes.c large_attribute + +\par Discussion +Large attributes are supported only in HDF5 versions 1.8.x and higher. +This has implications for the accessibility of your HDF5 files and +is your call.\n +Since there are no size limitations for large attributes, it might +seem tempting to mistake them for dataset stand-ins. This is not the +case, for at least two reasons: +1. Attributes decorate HDF5 objects, have their own local namespace, + and can't be link targets. +2. Attribute I/O treats the attribute value as atomic, i.e., there + is no support for partial I/O. A large attribute will always be + read or written in its entirety. + +\par See Also +See \ref CB_MaintainCompat for HDF5 compatibility implications. + + */ \ No newline at end of file diff --git a/doxygen/dox/cookbook/Files.c b/doxygen/dox/cookbook/Files.c new file mode 100644 index 0000000..b824933 --- /dev/null +++ b/doxygen/dox/cookbook/Files.c @@ -0,0 +1,87 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [free_space] --> + { + __label__ fail_fcpl, fail_fapl, fail_file; + hid_t fcpl, fapl, file; + + if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_fcpl; + } +#if H5_VERSION_GE(1, 10, 1) + if (H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_FSM_AGGR, 1, 4096) < 0) { +#else +#error HDF5 1.10.1+ required +#endif + ret_val = EXIT_FAILURE; + goto fail_fapl; + } + + if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_fapl; + } +#if H5_VERSION_GE(1, 10, 1) + if (H5Pset_libver_bounds(fapl, H5F_LIBVER_V110, H5F_LIBVER_LATEST) < 0) { +#else +#error HDF5 1.10.x+ required +#endif + ret_val = EXIT_FAILURE; + goto fail_file; + } + + if ((file = H5Fcreate("free_space.h5", H5F_ACC_TRUNC, fcpl, fapl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + H5Fclose(file); + +fail_file: + H5Pclose(fapl); +fail_fapl: + H5Pclose(fcpl); +fail_fcpl:; + } + //! <!-- [free_space] --> + + //! <!-- [user_block] --> + { + __label__ fail_fcpl, fail_file; + hid_t fcpl, file; + + if ((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_fcpl; + } + if (H5Pset_userblock(fcpl, 8192 * 1024) < 0) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + if ((file = H5Fcreate("userblock.h5", H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + H5Fclose(file); + +fail_file: + H5Pclose(fcpl); +fail_fcpl:; + } + //! <!-- [user_block] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/dox/cookbook/Files.dox b/doxygen/dox/cookbook/Files.dox new file mode 100644 index 0000000..169d638 --- /dev/null +++ b/doxygen/dox/cookbook/Files.dox @@ -0,0 +1,71 @@ +/** \page Files + +\section Files + +\subsection CB_FreeSpace Tracking Free Space in HDF5 Files + +\par Problem +You sometimes delete objects in HDF5 files and don't have new content to use the +free space, but would like to reuse it in the future. + +\par Solution +At file creation time, set the file space management strategy and persistence of +free space tracking information via H5Pset_file_space_strategy(). + +\note This feature is only supported in HDF5 1.10.1+. + +\snippet{lineno} Files.c free_space + +\par Discussion +Free space tracking is supported only in HDF5 versions 1.10.x and higher. +This has implications for the accessibility of your HDF5 files and +should be considered carefully. If compatibility with previous versions of +HDF5 must be maintained, space reclamation via \Code{h5repack} might be an option.\n +The file space strategy #H5F_FSPACE_STRATEGY_FSM_AGGR is not the only option +that supports free-space tracking. #H5F_FSPACE_STRATEGY_PAGE is another option, +which adds paged allocation and is used most effectively with page buffering.\n +For an in-depth account of HDF5 file space management, paged-allocation, and +page buffering, see the following documents: +\li \ref_rfc20121024 +\li \ref_rfc20120523 +\li \ref_rfc20150709 + +\par See Also +See \ref CB_MaintainCompat for HDF5 compatibility implications. + + +\subsection CB_RemoveUnusedSpace Removing Unused Space from HDF5 Files + +\par Problem +Based on estimates or \Code{h5stat} output you know that a large portion +of an HDF5 file consists of free or unaccounted space, and you would like +to remove it. + + +\subsection CB_UserBlock Creating an HDF5 File User Block + +\par Problem +You would like to include certain ancillary, non-HDF5 content in an +HDF5 file such that it can be accessed without the HDF5 library. + +\par Solution +Use a file creation property list in which the user block size is set via +H5Pset_userblock(). In the example below, we create an 8 MiB user block. +\snippet{lineno} Files.c user_block + +\par Discussion +The user block begins at offset 0 and must be at least 512 bytes and a power +of 2. The HDF5 library ignores any content between the beginning of the +file and the end of the user block.\n +You can add or strip a user block to/from an existing HDF5 file with the +\Code{h5jam}/\Code{h5unjam} tool, respectively. +\warning +If you try to embed content into the user block for use by other applications, +pay close attention to how they handle space beyond the last used byte in the +user block or the user block in general. In the worst case, applications might +try to truncate the rest of the file and destroy the HDF5 portion of the file. + +\par See Also +References to related recipes + + */ \ No newline at end of file diff --git a/doxygen/dox/cookbook/Performance.dox b/doxygen/dox/cookbook/Performance.dox new file mode 100644 index 0000000..7ac3a18 --- /dev/null +++ b/doxygen/dox/cookbook/Performance.dox @@ -0,0 +1,21 @@ +/** \page Performance + +\section Performance + +\subsection CB_MDCPerf Assessing HDF5 Metadata Cache Performance + +\par Problem +You are trying to diagnose and improve the I/O performance of an application +and would like to understand if a simple metadata cache adjustment might +yield substantial performance gains + +\par Solution +The to-the-point solution, i.e., the solution w/o any background or explanation + +\par Discussion +A discussion of the fine points and variants of the solution + +\par See Also +References to related recipes + + */ \ No newline at end of file diff --git a/doxygen/dox/maybe_metadata_reads.dox b/doxygen/dox/maybe_metadata_reads.dox index 25c905f..1bb53e0 100644 --- a/doxygen/dox/maybe_metadata_reads.dox +++ b/doxygen/dox/maybe_metadata_reads.dox @@ -13,62 +13,30 @@ * The following is a list of those functions in the HDF5 library. This list is * integral to the discussion in the H5Pset_all_coll_metadata_ops() entry: * - * <pre> - * - * H5Awrite() - * H5Aread() - * H5Arename() - * H5Aiterate2() - * H5Adelete() - * H5Aexists() - * - * H5Dget_space_status() - * H5Dget_storage_size() - * H5Dset_extent() - * H5Ddebug() - * H5Dclose() - * H5Dget_create_plist() - * H5Dget_space() (when dataset is a virtual dataset) - * - * H5Gget_create_plist() - * H5Gget_info() - * H5Gclose() - * - * H5Literate() - * H5Lvisit() - * - * H5Rcreate() - * H5Rdereference2() (when reference is an object reference) - * H5Rget_region() - * H5Rget_obj_type2() - * H5Rget_name() - * - * H5Ocopy() - * H5Oopen_by_addr() - * H5Oincr_refcount() - * H5Odecr_refcount() - * H5Oget_info() - * H5Oset_comment() - * H5Ovisit() - * - * H5Fis_hdf5() - * H5Fflush() - * H5Fclose() - * H5Fget_file_image() - * H5Freopen() - * H5Fget_freespace() - * H5Fget_info2() - * H5Fget_free_sections() - * H5Fmount() + * H5Awrite(), H5Aread(), H5Arename(), H5Aiterate2(), H5Adelete(), H5Aexists() + * + * H5Dget_space_status(), H5Dget_storage_size(), H5Dset_extent(), H5Ddebug(), + * H5Dclose(), H5Dget_create_plist(), H5Dget_space() (for virtual datasets) + * + * H5Gget_create_plist(), H5Gget_info(), H5Gclose() + * + * H5Literate(), H5Lvisit() + * + * H5Rcreate(), H5Rdereference2() (for object references), + * H5Rget_region(), H5Rget_obj_type2(), H5Rget_name() + * + * H5Ocopy(), H5Oopen_by_addr(), H5Oincr_refcount(), H5Odecr_refcount(), + * H5Oget_info(), H5Oset_comment(), H5Ovisit() + * + * H5Fis_hdf5(), H5Fflush(), H5Fclose(), H5Fget_file_image(), H5Freopen(), + * H5Fget_freespace(), H5Fget_info2(), H5Fget_free_sections(), H5Fmount(), * H5Funmount() * * H5Iget_name() * - * H5Tget_create_plist() - * H5Tclose() + * H5Tget_create_plist(), H5Tclose() * * H5Zunregister() - * </pre> * * In addition, \b most deprecated functions fall into this category. * diff --git a/doxygen/dox/rm-template.dox b/doxygen/dox/rm-template.dox index 64e4770..070a0a1 100644 --- a/doxygen/dox/rm-template.dox +++ b/doxygen/dox/rm-template.dox @@ -1,72 +1,99 @@ -/**\ingroup H5XYZ - * - * \brief A synopsis of what H5XYZgreat_function does - * - * \param[in] name1 Description of IN parameter \p name1 - * \param[out] name2 Description of OUT parameter \p name2 - * \param[in,out] name3 Description of INOUT parameter \p name3 - * - * \return Returns what you always wanted - * - * \pre Describe preconditions for an entity. Can be repreated. - * - * \invariant Describe invariants for an entity. Can be repeated. - * - * \post Describe postconditions for an entity. Can be repreated. - * - * \deprecated This was my favorite function while it lasted. - * - * \details Describe the normal behavior flow of the function here. Try to be - * helpful! - * - * Make reference to other functions like this: H5Fopen(). - * - * Make reference to formal parameters like this: \p name1 - * - * Make reference to macros like this: #H5P_DEFAULT. - * - * Make reference to enumeration constants like this: #H5F_CLOSE_WEAK. - * - * Include code snippets like this: - * \snippet H5Zpublic.h H5Z_class2_t_snip - * - * Lists are supported: - * - mouse events - * -# mouse move event - * -# mouse click event\n - * More info about the click event. - * -# mouse double click event - * - keyboard events - * 1. key down event - * 2. key up event - * - * The distance between \f$(x_1,y_1)\f$ and \f$(x_2,y_2)\f$ is - * \f$\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}\f$.\n - * For tables, see - * <a href="https://www.doxygen.nl/manual/tables.html">this example</a>. - * - * This is an example of how to use the H5XYZgreat_function().\n - * The contents of the file hello_hdf5.c will be included. - * \include hello_hdf5.c - * - * \note Dear reader, ... - * - * \attention Colorless green ideas sleep furiously. - * - * \warning Don't do this at home! - * - * \author This function was written by an esteemed author. Repeat this - * command for multiple authors. - * - * \date Record the function's birthdate! - * - * \since 1.MAJOR.MINOR The 'since' command can also be used to record a - * function's introduction (via its initial release - * version). - * - * \version 1.MAJOR.MINOR An important event in the version history of this - * function. There can be multiple such events. - * - * \see H5XYZanother_great_function(), H5XYZnot_so_great_a_function() - * - */ +/** \page RMT Reference Manual (RM) Page Template + +We treat documentation like code and use +<a href="https://www.doxygen.nl/index.html">Doxygen</a> to +<a href="https://github.com/HDFGroup/hdf5/blob/develop/src/H5Fpublic.h">markup +comments in the code</a> or create +<a href="https://github.com/HDFGroup/hdf5/blob/develop/doxygen/dox/Overview.dox">stand-alone pages</a>. + +Every RM entry consists of a subset of the elements listed below. Not every RM +entry warrants the full set. More is better, and we can, perhaps, distinguish +minimal, typical, and great RM entries. + +A minimal RM entry must include elements 1-3, 8, 11, and 7 if applicable. + +A \Emph{typical} RM entry is a minimal RM entry that in addition has elements +9, 10, and 12. + +A \Bold{great} RM entry is a typical RM entry plus everything else. + +The current RM is a mixed bag. Take what's there with a pinch of salt and apply +the <a href="https://www.oreilly.com/library/view/97-things-every/9780596809515/ch08.html">Scout Rule</a>! + +\par RM entry elements + +1. Module indication + - Indicate the HDF5 module in which the function will appear. + \verbatim + * \ingroup H5XYZ + \endverbatim +2. Synopsis + - A phrase or sentence that summarizes the function's purpose + \verbatim + * \brief Simplifies your life + \endverbatim +3. Prototype (parameters and return value) + - A description of the function parameters and return value + \verbatim + * \param[in] name1 Description of IN parameter \p name1 + * \param[out] name2 Description of OUT parameter \p name2 + * \param[in,out] name3 Description of INOUT parameter \p name3 + * \return Returns what you always wanted + \endverbatim + - Clearly indicate the parameter direction as \c in, \c out, or + \Code{in,out} + - Make reference to other parameters using \Code{\\p} +4. Preconditions + - A set of preconditions that must be met. + \verbatim + * \pre The argmument supplied in parameter \p name2 must be even. + \endverbatim +5. Invariants + - A set of invariants. + \verbatim + * \invariant The mouse pointer will always be visible. + \endverbatim +6. Postconditions + - What will be true when the function returns. + \verbatim + * \post On error, the output parameters will be unmodified. + \endverbatim +7. Deprecation note + - If a function was deprecated, list the version in which the function was + deprecated (below), why it was deprecated, and which function(s) succeed it. + \verbatim + * \deprecated Deprecated in favor of another great function. + \endverbatim +8. Details + - A detailed description of the function's behavior + \verbatim + * \details This is the heart of the matter. Try to be helpful! + \endverbatim +9. Example + - The function in context and action, usually a (Doxygen) snippet. + \verbatim + * \par Example + * \snippet H5F_examples.c minimal + \endverbatim +10. Instruction (attention, note, warning) + - Behaviors, features, side-effects, etc. the user should be aware of + \verbatim + * \note Dear reader, ... + * + * \attention Colorless green ideas sleep furiously. + * + * \warning Don't do this at home! + \endverbatim +11. Since + - The HDF5 library version in which the function was introduced + \verbatim + * \since 1.MAJOR.MINOR + \endverbatim +12. Version + - Use this element to record a deprecation version, a change in parameter + types, changes in behavior, etc. + \verbatim + * \version 1.MAJOR.MINOR Function was deprecated in this release + \endverbatim + +*/ diff --git a/doxygen/examples/H5D_examples.c b/doxygen/examples/H5D_examples.c index aad057d..4e54c1d 100644 --- a/doxygen/examples/H5D_examples.c +++ b/doxygen/examples/H5D_examples.c @@ -5,6 +5,86 @@ #include <stdio.h> #include <stdlib.h> +//! <!-- [H5Dchunk_iter_cb] --> +int +chunk_cb(const hsize_t *offset, uint32_t filter_mask, haddr_t addr, uint32_t nbytes, void *op_data) +{ + // only print the allocated chunk size only + printf("%d\n", nbytes); + return EXIT_SUCCESS; +} +//! <!-- [H5Dchunk_iter_cb] --> + +//! <!-- [H5Ovisit_cb] --> +herr_t +H5Ovisit_cb(hid_t obj, const char *name, const H5O_info2_t *info, void *op_data) +{ + herr_t retval = 0; + char * base_path = (char *)op_data; + + if (info->type == H5O_TYPE_DATASET) // current object is a dataset + { + hid_t dset, dcpl; + if ((dset = H5Dopen(obj, name, H5P_DEFAULT)) == H5I_INVALID_HID) { + retval = -1; + goto func_leave; + } + if ((dcpl = H5Dget_create_plist(dset)) == H5I_INVALID_HID) { + retval = -1; + goto fail_dcpl; + } + if (H5Pget_layout(dcpl) == H5D_CHUNKED) // dataset is chunked + { + __label__ fail_dtype, fail_dspace, fail_shape; + hid_t dspace, dtype; + size_t size, i; + int rank; + hsize_t cdims[H5S_MAX_RANK]; + + // get resources + if ((dtype = H5Dget_type(dset)) < 0) { + retval = -1; + goto fail_dtype; + } + if ((dspace = H5Dget_space(dset)) < 0) { + retval = -1; + goto fail_dspace; + } + // get the shape + if ((size = H5Tget_size(dtype)) == 0 || (rank = H5Sget_simple_extent_ndims(dspace)) < 0 || + H5Pget_chunk(dcpl, H5S_MAX_RANK, cdims) < 0) { + retval = -1; + goto fail_shape; + } + // calculate the nominal chunk size + size = 1; + for (i = 0; i < (size_t)rank; ++i) + size *= cdims[i]; + // print dataset info + printf("%s%s : nominal chunk size %lu [B] \n", base_path, name, size); + // get the allocated chunk sizes + if (H5Dchunk_iter(dset, H5P_DEFAULT, &chunk_cb, NULL) < 0) { + retval = -1; + goto fail_fig; + } + +fail_shape: + H5Sclose(dspace); +fail_dspace: + H5Tclose(dtype); +fail_dtype:; + } + + H5Pclose(dcpl); +fail_dcpl: + H5Dclose(dset); + } + +func_leave: + return retval; +} +//! <!-- [H5Ovisit_cb] --> + int main(void) { @@ -166,7 +246,6 @@ fail_delete: H5Fclose(file); fail_file:; } - //! <!-- [delete] --> return ret_val; diff --git a/doxygen/examples/H5E_examples.c b/doxygen/examples/H5E_examples.c new file mode 100644 index 0000000..deea838 --- /dev/null +++ b/doxygen/examples/H5E_examples.c @@ -0,0 +1,97 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_push, fail_minor, fail_major, fail_class; + hid_t cls, major, minor; + + // register a new error class for this "application" + if ((cls = H5Eregister_class("Custom error class", "H5E_examples", "0.1")) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_class; + } + + // create custom major and minor error codes + if ((major = H5Ecreate_msg(cls, H5E_MAJOR, "Okay, Houston, we've had a problem here")) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_major; + } + if ((minor = H5Ecreate_msg(cls, H5E_MINOR, "Oops!")) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_minor; + } + + // push a custom error message onto the default stack + if (H5Epush2(H5E_DEFAULT, __FILE__, __FUNCTION__, __LINE__, cls, major, minor, "Hello, Error!\n") < + 0) { + ret_val = EXIT_FAILURE; + goto fail_push; + } + + // print the default error stack + if (H5Eprint(H5E_DEFAULT, stderr) < 0) { + ret_val = EXIT_FAILURE; + } + +fail_push: + H5Eclose_msg(minor); +fail_minor: + H5Eclose_msg(major); +fail_major: + H5Eunregister_class(cls); +fail_class:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_count; + + // check the number of error messages on the default stack + // and print what's there + ssize_t count = H5Eget_num(H5E_DEFAULT); + if (count < 0) { + ret_val = EXIT_FAILURE; + goto fail_count; + } + else if (H5Eprint(H5E_DEFAULT, stderr) < 0) { + ret_val = EXIT_FAILURE; + } + +fail_count:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + // pop 10 error messages off the default error stack + // popping off non-existent messages is OK, but might be confusing + if (H5Epop(H5E_DEFAULT, 10) < 0) + ret_val = EXIT_FAILURE; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + // clear the default error stack (for the current thread) + if (H5Eclear2(H5E_DEFAULT) < 0) + ret_val = EXIT_FAILURE; + } + //! <!-- [delete] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/examples/H5F_examples.c b/doxygen/examples/H5F_examples.c index a7ce6fb..4e89fde 100644 --- a/doxygen/examples/H5F_examples.c +++ b/doxygen/examples/H5F_examples.c @@ -10,7 +10,7 @@ main(void) { int ret_val = EXIT_SUCCESS; - //! <!-- [life_cycle] --> + //! <!-- [create] --> { __label__ fail_fapl, fail_fcpl, fail_file; hid_t fcpl, fapl, file; @@ -48,12 +48,13 @@ fail_fapl: H5Pclose(fcpl); fail_fcpl:; } - //! <!-- [life_cycle] --> + //! <!-- [create] --> - //! <!-- [life_cycle_w_open] --> + //! <!-- [read] --> { __label__ fail_fapl, fail_file; - hid_t fapl, file; + hid_t fapl, file; + hsize_t size; if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) == H5I_INVALID_HID) { ret_val = EXIT_FAILURE; @@ -63,7 +64,7 @@ fail_fcpl:; // adjust the file access properties } - unsigned mode = H5F_ACC_RDWR; + unsigned mode = H5F_ACC_RDONLY; char name[] = "f1.h5"; if ((file = H5Fopen(name, mode, fapl)) == H5I_INVALID_HID) { @@ -71,14 +72,41 @@ fail_fcpl:; goto fail_file; } - // do something useful with FILE + if (H5Fget_filesize(file, &size) < 0) { + ret_val = EXIT_FAILURE; + } + + printf("File size: %llu bytes\n", size); H5Fclose(file); fail_file: H5Pclose(fapl); fail_fapl:; } - //! <!-- [life_cycle_w_open] --> + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_file; + hid_t file; + + unsigned mode = H5F_ACC_RDWR; + char name[] = "f1.h5"; + + if ((file = H5Fopen(name, mode, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // create a cycle by hard linking the root group in the root group + if (H5Lcreate_hard(file, ".", file, "loopback", H5P_DEFAULT, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + + H5Fclose(file); +fail_file:; + } + //! <!-- [update] --> //! <!-- [minimal] --> { @@ -183,5 +211,18 @@ fail_fapl:; } //! <!-- [mount] --> + //! <!-- [delete] --> + { +#if H5_VERSION_GE(1, 12, 0) + + // this function is only available in HDF5 1.12.x + if (H5Fdelete("f1.h5", H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + +#endif + } + //! <!-- [delete] --> + return ret_val; } diff --git a/doxygen/examples/H5G_examples.c b/doxygen/examples/H5G_examples.c new file mode 100644 index 0000000..3109efb --- /dev/null +++ b/doxygen/examples/H5G_examples.c @@ -0,0 +1,186 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_group, fail_prop, fail_lcpl, fail_file; + hid_t file, lcpl, group; + char fname[] = "g1.h5"; + char path[] = "/αυτή/είναι/μια/νέα/ομάδα"; + + if ((file = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + if ((lcpl = H5Pcreate(H5P_LINK_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_lcpl; + } + // ensure that intermediate groups are created automatically + if (H5Pset_create_intermediate_group(lcpl, 1) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // use UTF-8 encoding for link names + if (H5Pset_char_encoding(lcpl, H5T_CSET_UTF8) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // create five groups + if ((group = H5Gcreate(file, path, lcpl, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_group; + } + + H5Gclose(group); +fail_group: +fail_prop: + H5Pclose(lcpl); +fail_lcpl: + H5Fclose(file); +fail_file:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_file; + char fname[] = "g1.h5"; + char path[] = "/αυτή/είναι"; + hid_t file; + H5G_info_t info; + + if ((file = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // open one of the intermediate groups + if (H5Gget_info_by_name(file, path, &info, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_info; + } + + printf("Link count: %llu\n", info.nlinks); + switch (info.storage_type) { + case H5G_STORAGE_TYPE_COMPACT: + printf("Compact storage\n"); + break; + case H5G_STORAGE_TYPE_DENSE: + printf("Compact storage\n"); + break; + case H5G_STORAGE_TYPE_SYMBOL_TABLE: + printf("Symbol table\n"); + break; + default: + printf("UFO\n"); + break; + } + +fail_info: + H5Fclose(file); +fail_file:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_group, fail_prop, fail_lcpl, fail_file; + hid_t file, lcpl, group; + char fname[] = "g1.h5"; + char path[] = "/αυτή/είναι/μια/άλλη/νέα/ομάδα"; + + if ((file = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + if ((lcpl = H5Pcreate(H5P_LINK_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_lcpl; + } + // ensure that intermediate groups are created automatically + if (H5Pset_create_intermediate_group(lcpl, 1) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // use UTF-8 encoding for link names + if (H5Pset_char_encoding(lcpl, H5T_CSET_UTF8) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // create an anonymous group + if ((group = H5Gcreate_anon(file, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_group; + } + // link the new group to existing the group at "/αυτή/είναι/μια" + if (H5Lcreate_hard(group, ".", file, path, lcpl, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + + H5Gclose(group); +fail_group: +fail_prop: + H5Pclose(lcpl); +fail_lcpl: + H5Fclose(file); +fail_file:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_info, fail_object, fail_file; + hid_t file, obj; + char fname[] = "g1.h5"; + char path[] = "/αυτή/είναι/μια/άλλη/νέα/ομάδα"; + char delete_path[] = "/αυτή/είναι/μια"; + H5O_info_t info; + + if ((file = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // open a "leaf" group as object + if ((obj = H5Oopen(file, path, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_object; + } + // delete the link to an intermediate group on the path to the leaf + if (H5Ldelete(file, delete_path, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + // link deletion will propagate along hard links along all paths + // reachable from the intermediate group and cause reference counts to + // be decremented, freeing the objects if the count reaches 0 + if (H5Oget_info(obj, &info, H5O_INFO_BASIC) < 0) { + ret_val = EXIT_FAILURE; + goto fail_info; + } + + printf("Leaf reference count: %d\n", info.rc); + +fail_info: + H5Oclose(obj); +fail_object: + H5Fclose(file); +fail_file:; + } + //! <!-- [delete] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/examples/H5I_examples.c b/doxygen/examples/H5I_examples.c new file mode 100644 index 0000000..4aa4783 --- /dev/null +++ b/doxygen/examples/H5I_examples.c @@ -0,0 +1,242 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_dcpl; + hid_t dcpl; + + // create an ID of a pre-defined ID type + if ((dcpl = H5Pcreate(H5P_DATASET_XFER)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // we can reliably predict the ID type + assert(H5Iget_type(dcpl) == H5I_GENPROP_LST); + printf("%d\n", H5Iget_type(dcpl)); + + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_dcpl; + hid_t dcpl; + + // create an ID of a pre-defined ID type + if ((dcpl = H5Pcreate(H5P_DATASET_XFER)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // this better be valid + assert(H5Iis_valid(dcpl) > 0); + + // this ID is NOT associated with any HDF5 file; + // see the error message + assert(H5Iget_file_id(dcpl) == H5I_INVALID_HID); + + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_rc, fail_dcpl; + hid_t dcpl; + int rc; + + // create an ID of a pre-defined ID type + if ((dcpl = H5Pcreate(H5P_DATASET_XFER)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // retrieve the IDs reference count + if ((rc = H5Iget_ref(dcpl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_rc; + } + printf("Reference count: %d\n", rc); + + // bump its reference count (by 1) + if ((rc = H5Iinc_ref(dcpl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_rc; + } + printf("Reference count: %d\n", rc); + +fail_rc: + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_rc, fail_dcpl; + hid_t dcpl; + int rc; + + // create an ID of a pre-defined ID type + if ((dcpl = H5Pcreate(H5P_DATASET_XFER)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // decrease its reference count (from 1) to 0 + if ((rc = H5Idec_ref(dcpl)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_rc; + } + printf("Reference count: %d\n", rc); + + // at this point, the ID is no longer valid + assert(H5Iis_valid(dcpl) == 0); + + // dropping the ref. count to 0 has the side-effect of closing + // the associated item, and calling H5Pclose would create an error + goto fail_dcpl; + +fail_rc: + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [delete] --> + + //! <!-- [create_ud] --> + herr_t free_func(void *obj) + { + printf("Calling free_func...\n"); + H5free_memory(obj); + return 0; + } + + { + __label__ fail_id, fail_obj, fail_register; + H5I_type_t type; + int * obj; + hid_t obj_id; + + // register a new ID type + if ((type = H5Iregister_type(128, 1024, &free_func)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_register; + } + printf("New identifier type ID: %d\n", type); + + // create a new object + if ((obj = H5allocate_memory(10 * sizeof(int), 0)) == NULL) { + ret_val = EXIT_FAILURE; + goto fail_obj; + } + + // obtain an ID for the new object + if ((obj_id = H5Iregister(type, obj)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_id; + } + printf("New object identifier: %ld\n", obj_id); + +fail_id: + H5Iclear_type(type, 1); +fail_obj: + H5Idestroy_type(type); +fail_register:; + } + //! <!-- [create_ud] --> + + //! <!-- [read_ud] --> + { + __label__ fail_query, fail_register; + H5I_type_t type; + hsize_t count; + + // register a new ID type + if ((type = H5Iregister_type(128, 1024, NULL)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_register; + } + printf("New FOO identifier type ID: %d\n", type); + + // return the number of identifiers of TYPE currently in use + if (H5Inmembers(type, &count) < 0) { + ret_val = EXIT_FAILURE; + goto fail_query; + } + printf("%llu FOO identifiers in use\n", count); + +fail_query: + H5Idestroy_type(type); +fail_register:; + } + //! <!-- [read_ud] --> + + //! <!-- [update_ud] --> + { + __label__ fail_id, fail_register; + H5I_type_t type; + int obj = 42; + hid_t obj_id; + + // register a new ID type + if ((type = H5Iregister_type(128, 1024, NULL)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_register; + } + printf("New identifier type ID: %d\n", type); + + // obtain an ID for the new object + if ((obj_id = H5Iregister(type, &obj)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_id; + } + printf("New object identifier: %ld\n", obj_id); + + // bump the reference count + assert(H5Iinc_ref(obj_id) == 2); + + // force the deletion of all IDs regardless of reference count + H5Iclear_type(type, 1); +fail_id: + H5Idestroy_type(type); +fail_register:; + } + //! <!-- [update_ud] --> + + //! <!-- [delete_ud] --> + { + __label__ fail_register; + H5I_type_t type; + + // register a new ID type + if ((type = H5Iregister_type(128, 1024, NULL)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_register; + } + printf("New identifier type ID: %d\n", type); + + // decrementing the identifier type's ref. count to 0 triggers + // the type to be destroyed + assert(H5Idec_type_ref(type) == 0); + +fail_register:; + } + //! <!-- [delete_ud] --> + + return ret_val; +} diff --git a/doxygen/examples/H5L_examples.c b/doxygen/examples/H5L_examples.c new file mode 100644 index 0000000..63f54fe --- /dev/null +++ b/doxygen/examples/H5L_examples.c @@ -0,0 +1,156 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +//! <!-- [iter_cb] --> +herr_t +iter_cb(hid_t group, const char *name, const H5L_info_t *info, void *op_data) +{ + printf("Link \"%s\" is a", name); + switch (info->type) { + case H5L_TYPE_HARD: + printf(" hard link.\n"); + break; + case H5L_TYPE_SOFT: + printf(" soft link.\n"); + break; + case H5L_TYPE_EXTERNAL: + printf("n external link.\n"); + break; + default: + printf(" UFO link.\n"); + break; + } + + return 0; +} +//! <!-- [iter_cb] --> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_link, fail_prop, fail_lcpl, fail_create; + + hid_t file, lcpl; + + if ((file = H5Fcreate("l1.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_create; + } + + // make link creation easier by auto-creating intermediate + // groups and UTF-8 encoding of link names + if ((lcpl = H5Pcreate(H5P_LINK_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_lcpl; + } + if (H5Pset_create_intermediate_group(lcpl, 1) < 0 || H5Pset_char_encoding(lcpl, H5T_CSET_UTF8) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + + // create a loop by hard linking the root group + if (H5Lcreate_hard(file, ".", file, "√", lcpl, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_link; + } + // create a soft link to nowhere + if (H5Lcreate_soft("e1 62 80 87 04 09 43 ba 02 d3", file, "/path/to/nowhere", lcpl, H5P_DEFAULT) < + 0) { + ret_val = EXIT_FAILURE; + goto fail_link; + } + // create an external link to nowhere in a non-existent file + if (H5Lcreate_external("non-existent-file.h5", "???", file, "external", lcpl, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_link; + } + +fail_link: +fail_prop: + H5Pclose(lcpl); +fail_lcpl: + H5Fclose(file); +fail_create:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_iterate, fail_read; + hid_t file; + hsize_t idx = 0; + + if ((file = H5Fopen("l1.h5", H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_read; + } + + if (H5Literate(file, H5_INDEX_NAME, H5_ITER_NATIVE, &idx, iter_cb, NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_iterate; + } + +fail_iterate: + H5Fclose(file); +fail_read:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_move, fail_update; + hid_t file; + + if ((file = H5Fopen("l1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_update; + } + + // move the "√" link to the group at "/path/to" + // the cycle remains! + if (H5Lmove(file, "√", file, "path/to/√", H5P_DEFAULT, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_move; + } + +fail_move: + H5Fclose(file); +fail_update:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_delete, fail_file; + hid_t file; + + if ((file = H5Fopen("l1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // delete the "external" link + if (H5Ldelete(file, "external", H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_delete; + } + +fail_delete: + H5Fclose(file); +fail_file:; + } + //! <!-- [delete] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/examples/H5O_examples.c b/doxygen/examples/H5O_examples.c new file mode 100644 index 0000000..296acd1 --- /dev/null +++ b/doxygen/examples/H5O_examples.c @@ -0,0 +1,193 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <stdio.h> +#include <stdlib.h> + +#define H5P_DEFAULTx2 H5P_DEFAULT, H5P_DEFAULT + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_file; + hid_t file, group; + char src_path[] = "/a/few/groups"; + + if ((file = H5Fcreate("o1.h5", H5F_ACC_TRUNC, H5P_DEFAULTx2)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // create a few groups + { + __label__ fail_group, fail_lcpl; + hid_t lcpl; + if ((lcpl = H5Pcreate(H5P_LINK_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_lcpl; + } + if (H5Pset_create_intermediate_group(lcpl, 1) < 0) { + ret_val = EXIT_FAILURE; + goto fail_group; + } + if ((group = H5Gcreate(file, src_path, lcpl, H5P_DEFAULTx2)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_group; + } + + H5Gclose(group); +fail_group: + H5Pclose(lcpl); +fail_lcpl:; + } + + // create a copy + if (H5Ocopy(file, ".", file, "copy of", H5P_DEFAULTx2) < 0) { + ret_val = EXIT_FAILURE; + } + + H5Fclose(file); +fail_file:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_info, fail_file; + hid_t file; + char path[] = "/a/few/groups"; + H5O_info2_t info; + + if ((file = H5Fopen("o1.h5", H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // retrieve information about the object + if (H5Oget_info_by_name(file, path, &info, H5O_INFO_BASIC | H5O_INFO_NUM_ATTRS, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_info; + } + + // determine the object type + switch (info.type) { + case H5O_TYPE_GROUP: + printf("HDF5 group\n"); + break; + case H5O_TYPE_DATASET: + printf("HDF5 dataset\n"); + break; + case H5O_TYPE_NAMED_DATATYPE: + printf("HDF5 datatype\n"); + break; + default: + printf("UFO?\n"); + break; + } + // print basic information + printf("Reference count: %u\n", info.rc); + printf("Attribute count: %lld\n", info.num_attrs); + +fail_info: + H5Fclose(file); +fail_file:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_obj, fail_incr, fail_file; + hid_t file, obj; + char path[] = "/a/few/groups"; + H5O_info2_t info; + + if ((file = H5Fopen("o1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // open an object by path name + if ((obj = H5Oopen(file, path, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_obj; + } + + // bump its reference count (by 1) + if (H5Oincr_refcount(obj) < 0) { + ret_val = EXIT_FAILURE; + goto fail_incr; + } + + // confirm the new reference count + if (H5Oget_info(obj, &info, H5O_INFO_BASIC) < 0) { + ret_val = EXIT_FAILURE; + goto fail_incr; + } + printf("Reference count: %u\n", info.rc); + +fail_incr: + H5Oclose(obj); +fail_obj: + H5Fclose(file); +fail_file:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_obj, fail_delete, fail_file; + hid_t file, obj; + char path[] = "/a/few/groups"; + H5O_info2_t info; + + if ((file = H5Fopen("o1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // open an object by path name + if ((obj = H5Oopen(file, path, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_obj; + } + + // render it inaccessible from the root group by deleting the one and + // only link to it; this drops the reference count by 1 + if (H5Ldelete(file, path, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + goto fail_delete; + } + + // confirm the new reference count + if (H5Oget_info(obj, &info, H5O_INFO_BASIC) < 0) { + ret_val = EXIT_FAILURE; + goto fail_delete; + } + printf("Reference count: %u\n", info.rc); + + // if we close the file at this point, we'd be creating a tombstone, + // an object that cannot be reached and that cannot be reclaimed by the + // freespace manager; decrement the reference count to zero to prevent that + if (H5Idec_ref(obj) < 0) { + ret_val = EXIT_FAILURE; + goto fail_delete; + } + else + // attempting to close the object would be like a double H5Oclose and fail + goto fail_obj; + +fail_delete: + H5Oclose(obj); +fail_obj: + H5Fclose(file); +fail_file:; + } + //! <!-- [delete] --> + + return ret_val; +} diff --git a/doxygen/examples/H5PL_examples.c b/doxygen/examples/H5PL_examples.c new file mode 100644 index 0000000..d012d1b --- /dev/null +++ b/doxygen/examples/H5PL_examples.c @@ -0,0 +1,97 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_set; + // enable ONLY filter plugins + if (H5PLset_loading_state(H5PL_FILTER_PLUGIN) < 0) { + ret_val = EXIT_FAILURE; + goto fail_set; + } + + // ensure that "/tmp" is at the front of the search path list + if (H5PLprepend("/tmp") < 0) { + ret_val = EXIT_FAILURE; + } + +fail_set:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_read; + unsigned size, mask; + char buf[255]; + + // retrieve the number of entries in the plugin path list + if (H5PLsize(&size) < 0) { + ret_val = EXIT_FAILURE; + goto fail_read; + } + printf("Number of stored plugin paths: %d\n", size); + + // check the plugin state mask + if (H5PLget_loading_state(&mask) < 0) { + ret_val = EXIT_FAILURE; + goto fail_read; + } + printf("Filter plugins %s be loaded.\n", (mask & H5PL_FILTER_PLUGIN) == 1 ? "can" : "can't"); + printf("VOL plugins %s be loaded.\n", (mask & H5PL_VOL_PLUGIN) == 2 ? "can" : "can't"); + + // print the paths in the plugin path list + for (unsigned i = 0; i < size; ++i) { + if (H5PLget(i, buf, 255) < 0) { + ret_val = EXIT_FAILURE; + break; + } + printf("%s\n", buf); + } + +fail_read:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + // replace "/tmp" with something more sensible + if (H5PLreplace("/foo/bar", 0) < 0) { + ret_val = EXIT_FAILURE; + } + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_delete; + unsigned size; + + if (H5PLsize(&size) < 0) { + ret_val = EXIT_FAILURE; + goto fail_delete; + } + + // clean out the list of plugin paths + for (int i = size - 1; i >= 0; --i) { + if (H5PLremove(i) < 0) { + ret_val = EXIT_FAILURE; + break; + } + } + +fail_delete:; + } + //! <!-- [delete] --> + + return ret_val; +} diff --git a/doxygen/examples/H5P_examples.c b/doxygen/examples/H5P_examples.c new file mode 100644 index 0000000..cdfc03b --- /dev/null +++ b/doxygen/examples/H5P_examples.c @@ -0,0 +1,227 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_dcpl; + hid_t dcpl; + + // every property list is created as an instance of a suitable + // property list class + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // ... + + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_dcpl, fail_plist_cls_id; + hid_t dcpl, plist_cls_id; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + // to perform introspection on any kind of property list, + // we need to determine its property list class by obtaining a handle + if ((plist_cls_id = H5Pget_class(dcpl)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_plist_cls_id; + } + // Compare the handle to the handles of built-in or user-defined + // property list classes + assert(H5Pequal(plist_cls_id, H5P_DATASET_CREATE) > 0); + +fail_plist_cls_id: + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_dcpl, fail_prop; + hid_t dcpl; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // a property list is updated by adding (or removing) properties + if (H5Pset_fill_time(dcpl, H5D_FILL_TIME_NEVER) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + +fail_prop: + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_dcpl; + hid_t dcpl; + + if ((dcpl = H5Pcreate(H5P_DATASET_CREATE)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dcpl; + } + + // a property list is "deleted" by closing it + H5Pclose(dcpl); +fail_dcpl:; + } + //! <!-- [delete] --> + + //! <!-- [create_class] --> + { + __label__ fail_cls, fail_prop; + hid_t plist_cls, plist; + int izero = 0; + double dzero = 0.0; + + // create a new property list class + if ((plist_cls = H5Pcreate_class(H5P_ROOT, "int & double", NULL, NULL, NULL, NULL, NULL, NULL)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_cls; + } + // add a permanent integer property + if (H5Pregister2(plist_cls, "int", sizeof(int), &izero, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < + 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // add a permanent double property + if (H5Pregister2(plist_cls, "double", sizeof(double), &dzero, NULL, NULL, NULL, NULL, NULL, NULL, + NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // create an instance of this user-defined property list class + if ((plist = H5Pcreate(plist_cls)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + + // ... + + H5Pclose(plist); +fail_prop: + H5Pclose_class(plist_cls); +fail_cls:; + } + //! <!-- [create_class] --> + + //! <!-- [read_class] --> + { + __label__ fail_cls, fail_prop, fail_plist; + hid_t plist_cls, plist; + size_t nprops; + + if ((plist_cls = H5Pcreate_class(H5P_ROOT, "ud_plist", NULL, NULL, NULL, NULL, NULL, NULL)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_cls; + } + if ((plist = H5Pcreate(plist_cls)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + if (H5Pinsert2(plist, "temp", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_plist; + } + // count the registered properties of this class + if (H5Pget_nprops(plist_cls, &nprops) < 0) { + ret_val = EXIT_FAILURE; + goto fail_plist; + } + // this will be 0 as there are no registered properties + printf("Property list class has %lu registered properties.\n", nprops); + + // count the properties in this property list + if (H5Pget_nprops(plist, &nprops) < 0) { + ret_val = EXIT_FAILURE; + goto fail_plist; + } + // will be 1 as there is one temporary property + printf("Property list has %lu property.\n", nprops); + +fail_plist: + H5Pclose(plist); +fail_prop: + H5Pclose_class(plist_cls); +fail_cls:; + } + //! <!-- [read_class] --> + + //! <!-- [update_class] --> + { + __label__ fail_cls, fail_prop, fail_plist; + hid_t plist_cls, plist; + + if ((plist_cls = H5Pcreate_class(H5P_ROOT, "ud_plist", NULL, NULL, NULL, NULL, NULL, NULL)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_cls; + } + // create an instance of this user-defined property list class + if ((plist = H5Pcreate(plist_cls)) < 0) { + ret_val = EXIT_FAILURE; + goto fail_prop; + } + // insert a temporary property + if (H5Pinsert2(plist, "temp", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_plist; + } + +fail_plist: + H5Pclose(plist); +fail_prop: + H5Pclose_class(plist_cls); +fail_cls:; + } + //! <!-- [update_class] --> + + //! <!-- [delete_class] --> + { + __label__ fail_cls; + hid_t plist_cls; + + if ((plist_cls = H5Pcreate_class(H5P_ROOT, "int & double", NULL, NULL, NULL, NULL, NULL, NULL)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_cls; + } + // ... + + // a user defined property list class is destroyed by closing the handle + H5Pclose_class(plist_cls); +fail_cls:; + } + //! <!-- [delete_class] --> + + return ret_val; +} diff --git a/doxygen/examples/H5R_examples.c b/doxygen/examples/H5R_examples.c new file mode 100644 index 0000000..b40b992 --- /dev/null +++ b/doxygen/examples/H5R_examples.c @@ -0,0 +1,171 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_file, fail_fspace, fail_dset, fail_sel, fail_aspace, fail_attr, fail_awrite; + hid_t file, fspace, dset, aspace, attr; + H5R_ref_t ref; + + if ((file = H5Fcreate("reference.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // create a region reference which selects all elements of the dataset at "/data" + if ((fspace = H5Screate_simple(2, (hsize_t[]){10, 20}, NULL)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_fspace; + } + if ((dset = H5Dcreate(file, "data", H5T_STD_I32LE, fspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dset; + } + if (H5Sselect_all(fspace) < 0 || H5Rcreate_region(file, "data", fspace, H5P_DEFAULT, &ref) < 0) { + ret_val = EXIT_FAILURE; + goto fail_sel; + } + // store the region reference in a scalar attribute of the root group called "region" + if ((aspace = H5Screate(H5S_SCALAR)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_aspace; + } + if ((attr = H5Acreate(file, "region", H5T_STD_REF, aspace, H5P_DEFAULT, H5P_DEFAULT)) == + H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_attr; + } + if (H5Awrite(attr, H5T_STD_REF, &ref) < 0) { + ret_val = EXIT_FAILURE; + goto fail_awrite; + } + +fail_awrite: + H5Aclose(attr); +fail_attr: + H5Sclose(aspace); +fail_aspace: + H5Rdestroy(&ref); +fail_sel: + H5Dclose(dset); +fail_dset: + H5Sclose(fspace); +fail_fspace: + H5Fclose(file); +fail_file:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_file, fail_attr, fail_aread; + hid_t file, attr; + H5R_ref_t ref; + + if ((file = H5Fopen("reference.h5", H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // read the dataset region reference from the attribute + if ((attr = H5Aopen(file, "region", H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_attr; + } + if (H5Aread(attr, H5T_STD_REF, &ref) < 0) { + ret_val = EXIT_FAILURE; + goto fail_aread; + } + assert(H5Rget_type(&ref) == H5R_DATASET_REGION2); + + // get an HDF5 path name for the dataset of the region reference + { + char buf[255]; + if (H5Rget_obj_name(&ref, H5P_DEFAULT, buf, 255) < 0) { + ret_val = EXIT_FAILURE; + } + printf("Object name: \"%s\"\n", buf); + } + + H5Rdestroy(&ref); +fail_aread: + H5Aclose(attr); +fail_attr: + H5Fclose(file); +fail_file:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_file, fail_attr, fail_ref; + hid_t file, attr; + H5R_ref_t ref; + + if ((file = H5Fopen("reference.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + + // H5T_STD_REF is a generic reference type + // we can "update" the attribute value to refer to the attribute itself + if ((attr = H5Aopen(file, "region", H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_attr; + } + if (H5Rcreate_attr(file, "data", "region", H5P_DEFAULT, &ref) < 0) { + ret_val = EXIT_FAILURE; + goto fail_ref; + } + + assert(H5Rget_type(&ref) == H5R_ATTR); + + if (H5Awrite(attr, H5T_STD_REF, &ref) < 0) { + ret_val = EXIT_FAILURE; + } + + H5Rdestroy(&ref); +fail_ref: + H5Aclose(attr); +fail_attr: + H5Fclose(file); +fail_file:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_file, fail_ref; + hid_t file; + H5R_ref_t ref; + + // create an HDF5 object reference to the root group + if ((file = H5Fopen("reference.h5", H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + if (H5Rcreate_object(file, ".", H5P_DEFAULT, &ref) < 0) { + ret_val = EXIT_FAILURE; + goto fail_ref; + } + + // H5Rdestroy() releases all resources associated with an HDF5 reference + H5Rdestroy(&ref); +fail_ref: + H5Fclose(file); +fail_file:; + } + //! <!-- [delete] --> + + return ret_val; +} diff --git a/doxygen/examples/H5S_examples.c b/doxygen/examples/H5S_examples.c new file mode 100644 index 0000000..c542ec0 --- /dev/null +++ b/doxygen/examples/H5S_examples.c @@ -0,0 +1,132 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_dspace; + hid_t dspace; + + // create a 2D chess board shape (8x8) + if ((dspace = H5Screate_simple(2, (hsize_t[]){8, 8}, NULL)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dspace; + } + + H5Sclose(dspace); +fail_dspace:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_dspace; + hid_t dspace; + + if ((dspace = H5Screate(H5S_NULL)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dspace; + } + + // make changes to the selection on DSPACE + // ... + // parse the resulting selection + + switch (H5Sget_select_type(dspace)) { + case H5S_SEL_HYPERSLABS: + // we are dealing with a hyperslab selection + // determine the regularity and block structure + break; + case H5S_SEL_POINTS: + // we are dealing with a point selection + // for example, retrieve the point list + break; + case H5S_SEL_ALL: + // all dataset elements are selected + break; + case H5S_SEL_NONE: + // the selection is empty + break; + default: + ret_val = EXIT_FAILURE; + break; + } + + if (dspace != H5S_ALL) + H5Sclose(dspace); + +fail_dspace:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_select, fail_dspace; + hid_t dspace; + + // create a 2D chess board shape (8x8) + if ((dspace = H5Screate_simple(2, (hsize_t[]){8, 8}, NULL)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dspace; + } + // select all black fields: do this w/ a hyperslab union in two steps + + // select the black fields on even rows + if (H5Sselect_hyperslab(dspace, H5S_SELECT_SET, (hsize_t[]){0, 0}, (hsize_t[]){2, 2}, + (hsize_t[]){4, 4}, NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_select; + } + // select the black fields on odd rows + // notice the H5S_SELECT_OR operator + if (H5Sselect_hyperslab(dspace, H5S_SELECT_OR, (hsize_t[]){1, 1}, (hsize_t[]){2, 2}, + (hsize_t[]){4, 4}, NULL) < 0) { + ret_val = EXIT_FAILURE; + goto fail_select; + } + + // should be 32 + printf("%lld elements selected.\n", H5Sget_select_npoints(dspace)); + +fail_select: + H5Sclose(dspace); +fail_dspace:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_select, fail_dspace; + hid_t dspace; + + if ((dspace = H5Screate(H5S_NULL)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dspace; + } + + // make changes to and work with the selection on DSPACE + // ... + // finally, clear the selection + + if (H5Sselect_none(dspace) < 0) { + ret_val = EXIT_FAILURE; + goto fail_select; + } + +fail_select: + if (dspace != H5S_ALL) + H5Sclose(dspace); +fail_dspace:; + } + //! <!-- [delete] --> + + return ret_val; +} diff --git a/doxygen/examples/H5T_examples.c b/doxygen/examples/H5T_examples.c new file mode 100644 index 0000000..7cfa7d4 --- /dev/null +++ b/doxygen/examples/H5T_examples.c @@ -0,0 +1,136 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <stdio.h> +#include <stdlib.h> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_insert, fail_dtype, fail_file; + hid_t file, dtype; + + if ((file = H5Fcreate("t1.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // create a compound datatype with room for real and imaginary parts + if ((dtype = H5Tcreate(H5T_COMPOUND, 2 * sizeof(double))) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dtype; + } + // add the real part now and the imaginary part later + if (H5Tinsert(dtype, "re", 0, H5T_IEEE_F64LE) < 0) { + ret_val = EXIT_FAILURE; + goto fail_insert; + } + // commit the datatype definition to the file + if (H5Tcommit(file, "pre-complex", dtype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + +fail_insert: + H5Tclose(dtype); +fail_dtype: + H5Fclose(file); +fail_file:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_dtype, fail_file; + hid_t file, dtype; + + if ((file = H5Fopen("t1.h5", H5F_ACC_RDONLY, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // open the datatype object stored in the file + if ((dtype = H5Topen(file, "pre-complex", H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dtype; + } + + switch (H5Tget_class(dtype)) { // this time we are only interested in compounds + case H5T_COMPOUND: + printf("Record size: %lu bytes\n", H5Tget_size(dtype)); + printf("Record has %d field(s).\n", H5Tget_nmembers(dtype)); + break; + default: + break; + } + + H5Tclose(dtype); +fail_dtype: + H5Fclose(file); +fail_file:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + __label__ fail_insert, fail_clone, fail_dtype, fail_file; + hid_t file, dtype, clone; + + if ((file = H5Fopen("t1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // open the datatype object stored in the file + if ((dtype = H5Topen(file, "pre-complex", H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_dtype; + } + // the original datatype object is immutable and we need to clone it + if ((clone = H5Tcopy(dtype)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_clone; + } + // remember that the original has enough room for real and imaginary parts + // add the imaginary part + if (H5Tinsert(clone, "im", sizeof(double), H5T_IEEE_F64LE) < 0) { + ret_val = EXIT_FAILURE; + goto fail_insert; + } + // commit the "updated" datatype definition to the file + if (H5Tcommit(file, "complex", clone, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + +fail_insert: + H5Tclose(clone); +fail_clone: + H5Tclose(dtype); +fail_dtype: + H5Fclose(file); +fail_file:; + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { + __label__ fail_file; + hid_t file; + + if ((file = H5Fopen("t1.h5", H5F_ACC_RDWR, H5P_DEFAULT)) == H5I_INVALID_HID) { + ret_val = EXIT_FAILURE; + goto fail_file; + } + // delete the "pre-complex" datatype by unlinking + if (H5Ldelete(file, "pre-complex", H5P_DEFAULT) < 0) { + ret_val = EXIT_FAILURE; + } + + H5Fclose(file); +fail_file:; + } + //! <!-- [delete] --> + + return ret_val; +} diff --git a/doxygen/examples/H5Z_examples.c b/doxygen/examples/H5Z_examples.c new file mode 100644 index 0000000..28a1ea2 --- /dev/null +++ b/doxygen/examples/H5Z_examples.c @@ -0,0 +1,108 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +//! <!-- [filter] --> +size_t +filter(unsigned int flags, size_t cd_nelmts, const unsigned int cd_values[], size_t nbytes, size_t *buf_size, + void **buf) +{ + buf_size = 0; + + if (flags & H5Z_FLAG_REVERSE) { + // read data, e.g., decompress data + // ... + } + else { + // write data, e.g., compress data + // ... + } + + return nbytes; +} +//! <!-- [filter] --> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + __label__ fail_register; + H5Z_class_t cls; + cls.version = H5Z_CLASS_T_VERS; + cls.id = 256; + cls.encoder_present = 1; + cls.decoder_present = 1; + cls.name = "Identity filter"; + cls.can_apply = NULL; + cls.set_local = NULL; + cls.filter = &filter; + + // register the filter + if (H5Zregister(&cls) < 0) { + ret_val = EXIT_FAILURE; + goto fail_register; + } + + // do something with filter + // ... + + // unregister the filter if no longer required + // ... + +fail_register:; + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_avail; + + H5Z_filter_t flt = H5Z_FILTER_DEFLATE; + unsigned flags = 0; + + // check if the deflate filter is available + if (H5Zfilter_avail(flt) < 0) { + ret_val = EXIT_FAILURE; + goto fail_avail; + } + // retrieve the deflate filter info + if (H5Zget_filter_info(flt, &flags) < 0) { + ret_val = EXIT_FAILURE; + goto fail_avail; + } + + // check if the deflate encoder or decoder is enabled + if (H5Z_FILTER_CONFIG_ENCODE_ENABLED & flags) + printf("Deflate encoder enabled.\n"); + if (H5Z_FILTER_CONFIG_DECODE_ENABLED & flags) + printf("Deflate decoder enabled.\n"); + +fail_avail:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + // N/A + } //! <!-- [update] --> + + //! <!-- [delete] --> + { + // unregister the identity filter + if (H5Zunregister(256) < 0) { + ret_val = EXIT_FAILURE; + } + } + //! <!-- [delete] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/examples/H5_examples.c b/doxygen/examples/H5_examples.c new file mode 100644 index 0000000..ef52ed0 --- /dev/null +++ b/doxygen/examples/H5_examples.c @@ -0,0 +1,85 @@ +/* -*- c-file-style: "stroustrup" -*- */ + +#include "hdf5.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +//! <!-- [closing_shop] --> +void +closing_shop(void *ctx) +{ + printf("GoodBye, Cruel World!\n"); +} +//! <!-- [closing_shop] --> + +int +main(void) +{ + int ret_val = EXIT_SUCCESS; + + //! <!-- [create] --> + { + // an HDF5 library instance is automatically initialized as + // part of the first HDF5 API call, but there's no harm in + // calling H5open(). + if (H5open() < 0) { + ret_val = EXIT_FAILURE; + } + } + //! <!-- [create] --> + + //! <!-- [read] --> + { + __label__ fail_read; + unsigned majnum, minnum, relnum; + hbool_t flag; + + // retrieve the library version + if (H5get_libversion(&majnum, &minnum, &relnum) < 0) { + ret_val = EXIT_FAILURE; + goto fail_read; + } + // is this a thread-safe library build? + if (H5is_library_threadsafe(&flag) < 0) { + ret_val = EXIT_FAILURE; + goto fail_read; + } + + printf("Welcome to HDF5 %d.%d.%d\n", majnum, minnum, relnum); + printf("Thread-safety %s\n", (flag > 0) ? "enabled" : "disabled"); + +fail_read:; + } + //! <!-- [read] --> + + //! <!-- [update] --> + { + // update the library instance free list limits + if (H5set_free_list_limits(512 * 1024, 32 * 1024, 2048 * 1024, 128 * 1024, 8192 * 1024, 512 * 1024) < + 0) { + ret_val = EXIT_FAILURE; + } + } + //! <!-- [update] --> + + //! <!-- [delete] --> + { +#if H5_VERSION_GE(1, 13, 0) + // install a finalization routine + if (H5atclose(&closing_shop, NULL) < 0) { + ret_val = EXIT_FAILURE; + } +#endif + // close shop + if (H5close() < 0) { + ret_val = EXIT_FAILURE; + } + } + //! <!-- [delete] --> + + assert(ret_val == EXIT_SUCCESS); + + return ret_val; +} diff --git a/doxygen/hdf5_header.html b/doxygen/hdf5_header.html index 4a575d6..23f41f9 100644 --- a/doxygen/hdf5_header.html +++ b/doxygen/hdf5_header.html @@ -21,7 +21,7 @@ $mathjax </head> <body> -<div style="background:#FFDDDD;font-size:120%;text-align:center;margin:0;padding:5px">Please, help us to better know about our user community by answering the following short survey: <a href="https://www.hdfgroup.org/">https://www.hdfgroup.org/</a></div> +<div style="background:#FFDDDD;font-size:120%;text-align:center;margin:0;padding:5px">Please, help us to better know about our user community by answering the following short survey: <a href="https://www.hdfgroup.org/website-survey/">https://www.hdfgroup.org/website-survey/</a></div> <div id="top"><!-- do not remove this div, it is closed by doxygen! --> diff --git a/doxygen/hdf5doxy_layout.xml b/doxygen/hdf5doxy_layout.xml index 7f71c24..fc20aa1 100644 --- a/doxygen/hdf5doxy_layout.xml +++ b/doxygen/hdf5doxy_layout.xml @@ -11,6 +11,7 @@ <tab type="user" url="@ref RM" title="Reference Manual" /> <tab type="user" url="@ref TN" title="Technical Notes" /> <tab type="user" url="@ref SPEC" title="Specifications" /> + <tab type="user" url="@ref RFC" title="RFCs" /> <tab type="user" url="@ref About" title="About" /> </navindex> diff --git a/examples/CMakeTests.cmake b/examples/CMakeTests.cmake index b422078..70142c8 100644 --- a/examples/CMakeTests.cmake +++ b/examples/CMakeTests.cmake @@ -98,11 +98,14 @@ endif () ### Windows pops up a modal permission dialog on this test if (H5_HAVE_PARALLEL AND HDF5_TEST_PARALLEL AND NOT WIN32) + # Ensure that 24 is a multiple of the number of processes. + # The number 24 corresponds to SPACE1_DIM1 and SPACE1_DIM2 defined in ph5example.c + math(EXPR NUMPROCS "24 / ((24 + ${MPIEXEC_MAX_NUMPROCS} - 1) / ${MPIEXEC_MAX_NUMPROCS})") if (HDF5_ENABLE_USING_MEMCHECKER) - add_test (NAME MPI_TEST_EXAMPLES-ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} $<TARGET_FILE:ph5example> ${MPIEXEC_POSTFLAGS}) + add_test (NAME MPI_TEST_EXAMPLES-ph5example COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${NUMPROCS} ${MPIEXEC_PREFLAGS} $<TARGET_FILE:ph5example> ${MPIEXEC_POSTFLAGS}) else () add_test (NAME MPI_TEST_EXAMPLES-ph5example COMMAND "${CMAKE_COMMAND}" - -D "TEST_PROGRAM=${MPIEXEC_EXECUTABLE};${MPIEXEC_NUMPROC_FLAG};${MPIEXEC_MAX_NUMPROCS};${MPIEXEC_PREFLAGS};$<TARGET_FILE:ph5example>;${MPIEXEC_POSTFLAGS}" + -D "TEST_PROGRAM=${MPIEXEC_EXECUTABLE};${MPIEXEC_NUMPROC_FLAG};${NUMPROCS};${MPIEXEC_PREFLAGS};$<TARGET_FILE:ph5example>;${MPIEXEC_POSTFLAGS}" -D "TEST_ARGS:STRING=" -D "TEST_EXPECT=0" -D "TEST_OUTPUT=ph5example.out" diff --git a/fortran/src/CMakeLists.txt b/fortran/src/CMakeLists.txt index e59a829..316d3c7 100644 --- a/fortran/src/CMakeLists.txt +++ b/fortran/src/CMakeLists.txt @@ -582,4 +582,17 @@ if (NOT WIN32 AND NOT MINGW) PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE COMPONENT fortlibraries ) + if (HDF5_ENABLE_PARALLEL AND MPI_Fortran_FOUND) + configure_file ( + ${HDF_RESOURCES_DIR}/libh5cc.in + ${HDF5_BINARY_DIR}/CMakeFiles/h5pfc + @ONLY + ) + install ( + FILES ${HDF5_BINARY_DIR}/CMakeFiles/h5pfc + DESTINATION ${HDF5_INSTALL_BIN_DIR} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + COMPONENT fortlibraries + ) + endif () endif () diff --git a/fortran/src/H5Fff.F90 b/fortran/src/H5Fff.F90 index f772558..a273431 100644 --- a/fortran/src/H5Fff.F90 +++ b/fortran/src/H5Fff.F90 @@ -824,7 +824,7 @@ CONTAINS SUBROUTINE h5fget_name_f(obj_id, buf, size, hdferr) IMPLICIT NONE INTEGER(HID_T), INTENT(IN) :: obj_id ! Object identifier - CHARACTER(LEN=*), INTENT(INOUT) :: buf + CHARACTER(LEN=*), INTENT(OUT) :: buf ! Buffer to hold file name INTEGER(SIZE_T), INTENT(OUT) :: size ! Size of the file name INTEGER, INTENT(OUT) :: hdferr ! Error code: 0 on success, @@ -844,7 +844,7 @@ CONTAINS CHARACTER(KIND=C_CHAR), DIMENSION(*), INTENT(OUT) :: buf END FUNCTION h5fget_name_c END INTERFACE - buflen = LEN_TRIM(buf) + buflen = LEN(buf) hdferr = h5fget_name_c(obj_id, size, buf, buflen) END SUBROUTINE h5fget_name_f !****s* H5F/h5fget_filesize_f diff --git a/fortran/test/fortranlib_test.F90 b/fortran/test/fortranlib_test.F90 index eff4657..1640a8f 100644 --- a/fortran/test/fortranlib_test.F90 +++ b/fortran/test/fortranlib_test.F90 @@ -74,6 +74,10 @@ PROGRAM fortranlibtest CALL write_test_status(ret_total_error, ' Reopen test', total_error) ret_total_error = 0 + CALL get_name_test(cleanup, ret_total_error) + CALL write_test_status(ret_total_error, ' Get name test', total_error) + + ret_total_error = 0 CALL file_close(cleanup, ret_total_error) CALL write_test_status(ret_total_error, ' File open/close test', total_error) diff --git a/fortran/test/tH5F.F90 b/fortran/test/tH5F.F90 index f4a3232..06dc6de 100644 --- a/fortran/test/tH5F.F90 +++ b/fortran/test/tH5F.F90 @@ -21,7 +21,8 @@ ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ! ! CONTAINS SUBROUTINES -! mountingtest, reopentest, plisttest, file_close, file_space +! mountingtest, reopentest, get_name_test, plisttest, +! file_close, file_space ! !***** ! @@ -580,6 +581,125 @@ CONTAINS END SUBROUTINE reopentest +! The following subroutine checks that h5fget_name_f produces +! correct output for a given obj_id and filename. +! + SUBROUTINE check_get_name(obj_id, fix_filename, total_error) + USE HDF5 ! This module contains all necessary modules + USE TH5_MISC + IMPLICIT NONE + INTEGER(HID_T) :: obj_id ! Object identifier + CHARACTER(LEN=80), INTENT(IN) :: fix_filename ! Expected filename + INTEGER, INTENT(INOUT) :: total_error ! Error count + + CHARACTER(LEN=80):: file_name ! Filename buffer + INTEGER:: error ! HDF5 error code + INTEGER(SIZE_T):: name_size ! Filename length + ! + !Get file name from the dataset identifier + ! + + ! Use an uninitialized buffer + CALL h5fget_name_f(obj_id, file_name, name_size, error) + CALL check("h5fget_name_f",error,total_error) + IF(name_size .NE. LEN_TRIM(fix_filename))THEN + WRITE(*,*) " file name size obtained from the object id is incorrect" + total_error = total_error + 1 + ENDIF + IF(file_name(1:name_size) .NE. TRIM(fix_filename)) THEN + WRITE(*,*) " file name obtained from the object id is incorrect" + total_error = total_error + 1 + END IF + + ! Use a buffer initialized with spaces + file_name(:) = " " + CALL h5fget_name_f(obj_id, file_name, name_size, error) + CALL check("h5fget_name_f",error,total_error) + IF(name_size .NE. LEN_TRIM(fix_filename))THEN + WRITE(*,*) " file name size obtained from the object id is incorrect" + total_error = total_error + 1 + ENDIF + IF(file_name(1:name_size) .NE. TRIM(fix_filename)) THEN + WRITE(*,*) " file name obtained from the object id is incorrect" + total_error = total_error + 1 + END IF + + ! Use a buffer initialized with non-whitespace characters + file_name(:) = "a" + CALL h5fget_name_f(obj_id, file_name, name_size, error) + CALL check("h5fget_name_f",error,total_error) + IF(name_size .NE. LEN_TRIM(fix_filename))THEN + WRITE(*,*) " file name size obtained from the object id is incorrect" + total_error = total_error + 1 + ENDIF + IF(file_name(1:name_size) .NE. TRIM(fix_filename)) THEN + WRITE(*,*) " file name obtained from the object id is incorrect" + total_error = total_error + 1 + END IF + + END SUBROUTINE check_get_name + +! The following subroutine tests h5fget_name_f. +! It creates the file which has name "filename.h5" and +! tests that h5fget_name_f also returns the name "filename.h5" +! + + SUBROUTINE get_name_test(cleanup, total_error) + USE HDF5 ! This module contains all necessary modules + USE TH5_MISC + IMPLICIT NONE + LOGICAL, INTENT(IN) :: cleanup + INTEGER, INTENT(INOUT) :: total_error + + CHARACTER(LEN=*), PARAMETER :: filename = "filename" + CHARACTER(LEN=80) :: fix_filename + + INTEGER(HID_T) :: file_id ! File identifier + INTEGER(HID_T) :: g_id ! Group identifier + + ! + ! Flag to check operation success + ! + INTEGER :: error + + ! + ! Create file "filename.h5" using default properties. + ! + CALL h5_fixname_f(filename, fix_filename, H5P_DEFAULT_F, error) + IF (error .NE. 0) THEN + WRITE(*,*) "Cannot modify filename" + STOP + ENDIF + CALL h5fcreate_f(fix_filename, H5F_ACC_TRUNC_F, file_id, error) + CALL check("h5fcreate_f",error,total_error) + + ! + ! Create group. + ! + CALL h5gopen_f(file_id,"/",g_id, error) + CALL check("h5gopen_f",error,total_error) + + CALL check_get_name(file_id, fix_filename, total_error) + CALL check_get_name(g_id, fix_filename, total_error) + + ! Close the group. + ! + CALL h5gclose_f(g_id, error) + CALL check("h5gclose_f",error,total_error) + + ! + ! Close the file identifiers. + ! + CALL h5fclose_f(file_id, error) + CALL check("h5fclose_f",error,total_error) + + IF(cleanup) CALL h5_cleanup_f(filename, H5P_DEFAULT_F, error) + CALL check("h5_cleanup_f", error, total_error) + RETURN + + END SUBROUTINE get_name_test + + ! ! The following example demonstrates how to get creation property list, ! and access property list. diff --git a/fortran/test/tH5Z.F90 b/fortran/test/tH5Z.F90 index 0eaa941..8c39fea 100644 --- a/fortran/test/tH5Z.F90 +++ b/fortran/test/tH5Z.F90 @@ -192,7 +192,8 @@ CONTAINS INTEGER(HSIZE_T), DIMENSION(2) :: chunk_dims = (/NN, MM/) INTEGER :: rank = 2 ! Dataset rank - INTEGER, DIMENSION(N,M) :: dset_data, data_out ! Data buffers + INTEGER, DIMENSION(N,M) :: dset_data ! Data buffers + INTEGER, DIMENSION(:,:), ALLOCATABLE :: data_out ! Data buffers INTEGER :: error ! Error flag INTEGER :: num_errors = 0 ! Number of data errors @@ -363,8 +364,9 @@ CONTAINS ! ! Read the dataset. ! + ALLOCATE(data_out(1:N,1:M)) CALL h5dread_f (dset_id, H5T_NATIVE_INTEGER, data_out, data_dims, error) - CALL check("h5dread_f", error, total_error) + CALL check("h5dread_f", error, total_error) ! !Compare the data. @@ -385,6 +387,7 @@ CONTAINS 100 IF (num_errors .GT. 0) THEN total_error=total_error + 1 END IF + DEALLOCATE(data_out) ! ! End access to the dataset and release resources used by it. diff --git a/hl/CMakeLists.txt b/hl/CMakeLists.txt index 083c60e..5061c6c 100644 --- a/hl/CMakeLists.txt +++ b/hl/CMakeLists.txt @@ -7,9 +7,17 @@ project (HDF5_HL C) add_subdirectory (src) -#-- Build the High level Tools +# Build HDF5 Tools if (HDF5_BUILD_TOOLS) - add_subdirectory (tools) + #----------------------------------------------------------------------------- + #-- Option to build the High level Tools + #----------------------------------------------------------------------------- + if (EXISTS "${HDF5_HL_SOURCE_DIR}/tools" AND IS_DIRECTORY "${HDF5_HL_SOURCE_DIR}/tools") + option (HDF5_BUILD_HL_TOOLS "Build HDF5 HL Tools" ON) + if (HDF5_BUILD_HL_TOOLS) + add_subdirectory (tools) + endif () + endif () endif () #-- Add High Level Examples diff --git a/hl/Makefile.am b/hl/Makefile.am index 9bf209e..8c427d3 100644 --- a/hl/Makefile.am +++ b/hl/Makefile.am @@ -37,16 +37,19 @@ else TEST_DIR = endif if BUILD_TOOLS_CONDITIONAL +if BUILD_TOOLS_HL_CONDITIONAL TOOLS_DIR = tools else TOOLS_DIR = endif +else + TOOLS_DIR = +endif ## Don't recurse into any subdirectories if HDF5 is not configured to ## use the HL library if BUILD_HDF5_HL_CONDITIONAL SUBDIRS=src $(TEST_DIR) $(TOOLS_DIR) $(CXX_DIR) $(FORTRAN_DIR) - endif DIST_SUBDIRS=src test tools c++ fortran examples diff --git a/hl/c++/src/H5PacketTable.cpp b/hl/c++/src/H5PacketTable.cpp index 2908626..086c702 100644 --- a/hl/c++/src/H5PacketTable.cpp +++ b/hl/c++/src/H5PacketTable.cpp @@ -62,12 +62,9 @@ PacketTable::~PacketTable() * any trouble making or opening the packet table. */ bool -PacketTable::IsValid() +PacketTable::IsValid() const { - if (H5PTis_valid(table_id) == 0) - return true; - else - return false; + return H5PTis_valid(table_id) == 0; } /* IsVariableLength @@ -75,7 +72,7 @@ PacketTable::IsValid() * and 0, otherwise. Returns -1 if the table is invalid (not open). */ int -PacketTable::IsVariableLength() +PacketTable::IsVariableLength() const { return H5PTis_varlen(table_id); } @@ -84,7 +81,7 @@ PacketTable::IsVariableLength() * Sets the index to point to the first packet in the packet table */ void -PacketTable::ResetIndex() +PacketTable::ResetIndex() const { H5PTcreate_index(table_id); } @@ -94,7 +91,7 @@ PacketTable::ResetIndex() * Returns 0 on success, negative on failure (if index is out of bounds) */ int -PacketTable::SetIndex(hsize_t index) +PacketTable::SetIndex(hsize_t index) const { return H5PTset_index(table_id, index); } @@ -104,7 +101,7 @@ PacketTable::SetIndex(hsize_t index) * Returns 0 on success, negative on failure (if index is out of bounds) */ hsize_t -PacketTable::GetIndex(int &error) +PacketTable::GetIndex(int &error) const { hsize_t index; @@ -121,7 +118,7 @@ PacketTable::GetIndex(int &error) * error is set to negative. */ hsize_t -PacketTable::GetPacketCount(int &error) +PacketTable::GetPacketCount(int &error) const { hsize_t npackets; @@ -133,7 +130,7 @@ PacketTable::GetPacketCount(int &error) * Returns the identifier of the packet table */ hid_t -PacketTable::GetTableId() +PacketTable::GetTableId() const { return table_id; } @@ -145,7 +142,7 @@ PacketTable::GetTableId() * the desired functionality cannot be performed via the packet table ID. */ hid_t -PacketTable::GetDatatype() +PacketTable::GetDatatype() const { return H5PTget_type(table_id); } @@ -157,7 +154,7 @@ PacketTable::GetDatatype() * the desired functionality cannot be performed via the packet table ID. */ hid_t -PacketTable::GetDataset() +PacketTable::GetDataset() const { return H5PTget_dataset(table_id); } @@ -169,7 +166,7 @@ PacketTable::GetDataset() * Returns 0 on success, negative on error. */ int -PacketTable::FreeBuff(size_t numStructs, hvl_t *buffer) +PacketTable::FreeBuff(size_t numStructs, hvl_t *buffer) const { return H5PTfree_vlen_buff(table_id, numStructs, buffer); } diff --git a/hl/c++/src/H5PacketTable.h b/hl/c++/src/H5PacketTable.h index eae66f1..c1f1eb5 100644 --- a/hl/c++/src/H5PacketTable.h +++ b/hl/c++/src/H5PacketTable.h @@ -54,39 +54,39 @@ class H5_HLCPPDLL PacketTable { * Use this after the constructor to ensure HDF did not have * any trouble making or opening the packet table. */ - bool IsValid(); + bool IsValid() const; /* IsVariableLength * Return 1 if this packet table uses variable-length datatype, * return 0 if it is Fixed Length. Returns -1 if the table is * invalid (not open). */ - int IsVariableLength(); + int IsVariableLength() const; /* ResetIndex * Sets the "current packet" index to point to the first packet in the * packet table */ - void ResetIndex(); + void ResetIndex() const; /* SetIndex * Sets the current packet to point to the packet specified by index. * Returns 0 on success, negative on failure (if index is out of bounds) */ - int SetIndex(hsize_t index); + int SetIndex(hsize_t index) const; /* GetIndex * Returns the position of the current packet. * On failure, returns 0 and error is set to negative. */ - hsize_t GetIndex(int &error); + hsize_t GetIndex(int &error) const; /* GetPacketCount * Returns the number of packets in the packet table. Error * is set to 0 on success. On failure, returns 0 and * error is set to negative. */ - hsize_t GetPacketCount(int &error); + hsize_t GetPacketCount(int &error) const; hsize_t GetPacketCount() @@ -98,7 +98,7 @@ class H5_HLCPPDLL PacketTable { /* GetTableId * Returns the identifier of the packet table. */ - hid_t GetTableId(); + hid_t GetTableId() const; /* GetDatatype * Returns the datatype identifier used by the packet table, on success, @@ -106,7 +106,7 @@ class H5_HLCPPDLL PacketTable { * Note: it is best to avoid using this identifier in applications, unless * the desired functionality cannot be performed via the packet table ID. */ - hid_t GetDatatype(); + hid_t GetDatatype() const; /* GetDataset * Returns the dataset identifier associated with the packet table, on @@ -114,7 +114,7 @@ class H5_HLCPPDLL PacketTable { * Note: it is best to avoid using this identifier in applications, unless * the desired functionality cannot be performed via the packet table ID. */ - hid_t GetDataset(); + hid_t GetDataset() const; /* FreeBuff * Frees the buffers created when variable-length packets are read. @@ -122,7 +122,7 @@ class H5_HLCPPDLL PacketTable { * location in memory. * Returns 0 on success, negative on error. */ - int FreeBuff(size_t numStructs, hvl_t *buffer); + int FreeBuff(size_t numStructs, hvl_t *buffer) const; protected: hid_t table_id; diff --git a/hl/c++/test/ptableTest.cpp b/hl/c++/test/ptableTest.cpp index 6deb24d..ab49303 100644 --- a/hl/c++/test/ptableTest.cpp +++ b/hl/c++/test/ptableTest.cpp @@ -620,7 +620,7 @@ TestHDFFV_9758() for (hsize_t i = 0; i < NUM_PACKETS; i++) { s1[i].a = static_cast<int>(i); - s1[i].b = 1.0f * static_cast<float>(i * i); + s1[i].b = 1.0F * static_cast<float>(i * i); s1[i].c = 1.0 / static_cast<double>(i + 1); HDsprintf(s1[i].d, "string%" PRIuHSIZE "", i); s1[i].e = static_cast<int>(100 + i); diff --git a/hl/examples/ex_table_01.c b/hl/examples/ex_table_01.c index 8635acf..3294ef4 100644 --- a/hl/examples/ex_table_01.c +++ b/hl/examples/ex_table_01.c @@ -50,10 +50,10 @@ main(void) sizeof(dst_buf[0].pressure), sizeof(dst_buf[0].temperature)}; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Define field information */ const char *field_names[NFIELDS] = {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; diff --git a/hl/examples/ex_table_02.c b/hl/examples/ex_table_02.c index 9c476b3..fb2cad6 100644 --- a/hl/examples/ex_table_02.c +++ b/hl/examples/ex_table_02.c @@ -42,10 +42,10 @@ main(void) Particle dst_buf[NRECORDS + NRECORDS_ADD]; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Calculate the size and the offsets of our struct members in memory */ size_t dst_size = sizeof(Particle); @@ -66,7 +66,7 @@ main(void) int i; /* Append particles */ - Particle particle_in[NRECORDS_ADD] = {{"eight", 80, 80, 8.0f, 80.0}, {"nine", 90, 90, 9.0f, 90.0}}; + Particle particle_in[NRECORDS_ADD] = {{"eight", 80, 80, 8.0F, 80.0}, {"nine", 90, 90, 9.0F, 90.0}}; /* Initialize the field field_type */ string_type = H5Tcopy(H5T_C_S1); diff --git a/hl/examples/ex_table_03.c b/hl/examples/ex_table_03.c index 31cf970..3caa45e 100644 --- a/hl/examples/ex_table_03.c +++ b/hl/examples/ex_table_03.c @@ -46,14 +46,14 @@ main(void) size_t dst_offset[NFIELDS] = {HOFFSET(Particle, name), HOFFSET(Particle, lati), HOFFSET(Particle, longi), HOFFSET(Particle, pressure), HOFFSET(Particle, temperature)}; - Particle p = {"zero", 0, 0, 0.0f, 0.0}; + Particle p = {"zero", 0, 0, 0.0F, 0.0}; size_t dst_sizes[NFIELDS] = {sizeof(p.name), sizeof(p.lati), sizeof(p.longi), sizeof(p.pressure), sizeof(p.temperature)}; /* Define field information */ const char *field_names[NFIELDS] = {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; /* Fill value particle */ - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; hid_t field_type[NFIELDS]; hid_t string_type; hid_t file_id; @@ -63,7 +63,7 @@ main(void) int i; /* Define 2 new particles to write */ - Particle particle_in[NRECORDS_WRITE] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}}; + Particle particle_in[NRECORDS_WRITE] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}}; /* Initialize the field field_type */ string_type = H5Tcopy(H5T_C_S1); diff --git a/hl/examples/ex_table_04.c b/hl/examples/ex_table_04.c index 863fe15..9b39ef7 100644 --- a/hl/examples/ex_table_04.c +++ b/hl/examples/ex_table_04.c @@ -65,23 +65,23 @@ main(void) hid_t string_type; hid_t file_id; hsize_t chunk_size = 10; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; /* Fill value particle */ + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; /* Fill value particle */ hsize_t start; /* Record to start reading/writing */ hsize_t nrecords; /* Number of records to read/write */ int compress = 0; int i; Particle *p_data = NULL; /* Initially no data */ float pressure_in[NRECORDS_ADD] = /* Define new values for the field "Pressure" */ - {0.0f, 1.0f, 2.0f}; + {0.0F, 1.0F, 2.0F}; Position position_in[NRECORDS_ADD] = {/* Define new values for "Latitude,Longitude" */ {0, 0}, {10, 10}, {20, 20}}; NamePressure namepre_in[NRECORDS_ADD] = /* Define new values for "Name,Pressure" */ { - {"zero", 0.0f}, - {"one", 1.0f}, - {"two", 2.0f}, + {"zero", 0.0F}, + {"one", 1.0F}, + {"two", 2.0F}, }; size_t field_sizes_pos[2] = {sizeof(position_in[0].longi), sizeof(position_in[0].lati)}; size_t field_sizes_pre[1] = {sizeof(namepre_in[0].pressure)}; diff --git a/hl/examples/ex_table_05.c b/hl/examples/ex_table_05.c index 337bfb6..cac406b 100644 --- a/hl/examples/ex_table_05.c +++ b/hl/examples/ex_table_05.c @@ -64,7 +64,7 @@ main(void) hid_t string_type; hid_t file_id; hsize_t chunk_size = 10; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; /* Fill value particle */ + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; /* Fill value particle */ int compress = 0; hsize_t nfields; hsize_t start; /* Record to start reading/writing */ @@ -72,7 +72,7 @@ main(void) int i; /* Define new values for the field "Pressure" */ - float pressure_in[NRECORDS_ADD] = {0.0f, 1.0f, 2.0f}; + float pressure_in[NRECORDS_ADD] = {0.0F, 1.0F, 2.0F}; int field_index_pre[1] = {3}; int field_index_pos[2] = {1, 2}; diff --git a/hl/examples/ex_table_06.c b/hl/examples/ex_table_06.c index f6b67c8..cc1bc01 100644 --- a/hl/examples/ex_table_06.c +++ b/hl/examples/ex_table_06.c @@ -49,7 +49,7 @@ main(void) hid_t string_type; hid_t file_id; hsize_t chunk_size = 10; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; /* Fill value particle */ + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; /* Fill value particle */ int compress = 0; hsize_t nfields_out; hsize_t nrecords_out; diff --git a/hl/examples/ex_table_07.c b/hl/examples/ex_table_07.c index ab36613..e05a681 100644 --- a/hl/examples/ex_table_07.c +++ b/hl/examples/ex_table_07.c @@ -44,10 +44,10 @@ main(void) HOFFSET(Particle, pressure), HOFFSET(Particle, temperature)}; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; const char *field_names[NFIELDS] = /* Define field information */ {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; @@ -56,7 +56,7 @@ main(void) hid_t file_id; hsize_t chunk_size = 10; int compress = 0; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; hsize_t start; /* Record to start reading */ hsize_t nrecords; /* Number of records to insert/delete */ hsize_t nfields_out; diff --git a/hl/examples/ex_table_08.c b/hl/examples/ex_table_08.c index 5d447dd..1063172 100644 --- a/hl/examples/ex_table_08.c +++ b/hl/examples/ex_table_08.c @@ -41,10 +41,10 @@ main(void) Particle dst_buf[NRECORDS + NRECORDS_INS]; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Calculate the size and the offsets of our struct members in memory */ size_t dst_size = sizeof(Particle); @@ -54,7 +54,7 @@ main(void) sizeof(p_data[0].pressure), sizeof(p_data[0].temperature)}; /* Define an array of Particles to insert */ - Particle p_data_insert[NRECORDS_INS] = {{"new", 30, 30, 3.0f, 30.0}, {"new", 40, 40, 4.0f, 40.0}}; + Particle p_data_insert[NRECORDS_INS] = {{"new", 30, 30, 3.0F, 30.0}, {"new", 40, 40, 4.0F, 40.0}}; /* Define field information */ const char *field_names[NFIELDS] = {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; diff --git a/hl/examples/ex_table_09.c b/hl/examples/ex_table_09.c index 381925f..171de2e 100644 --- a/hl/examples/ex_table_09.c +++ b/hl/examples/ex_table_09.c @@ -49,10 +49,10 @@ main(void) sizeof(dst_buf[0].pressure), sizeof(dst_buf[0].temperature)}; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Define field information */ const char *field_names[NFIELDS] = {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; @@ -61,7 +61,7 @@ main(void) hid_t file_id; hsize_t chunk_size = 10; int compress = 0; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; /* Fill value particle */ + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; /* Fill value particle */ hsize_t start1; /* Record to start reading from 1st table */ hsize_t nrecords; /* Number of records to insert */ hsize_t start2; /* Record to start writing in 2nd table */ diff --git a/hl/examples/ex_table_10.c b/hl/examples/ex_table_10.c index 4ba5d64..c974e84 100644 --- a/hl/examples/ex_table_10.c +++ b/hl/examples/ex_table_10.c @@ -40,10 +40,10 @@ main(void) } Particle; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; Particle dst_buf[2 * NRECORDS]; /* Calculate the size and the offsets of our struct members in memory */ diff --git a/hl/examples/ex_table_11.c b/hl/examples/ex_table_11.c index 9bf3927..6b38b95 100644 --- a/hl/examples/ex_table_11.c +++ b/hl/examples/ex_table_11.c @@ -38,10 +38,10 @@ main(void) } Particle1; /* Define an array of Particles */ - Particle1 p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle1 p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Calculate the size and the offsets of our struct members in memory */ size_t dst_size1 = sizeof(Particle1); @@ -56,7 +56,7 @@ main(void) hid_t file_id; hsize_t chunk_size = 10; int compress = 0; - Particle1 fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; + Particle1 fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; int fill_data_new[1] = {-100}; hsize_t position; hsize_t nfields_out; diff --git a/hl/examples/ex_table_12.c b/hl/examples/ex_table_12.c index 3e7c27a..a1a2c54 100644 --- a/hl/examples/ex_table_12.c +++ b/hl/examples/ex_table_12.c @@ -44,10 +44,10 @@ main(void) HOFFSET(Particle, pressure), HOFFSET(Particle, temperature)}; /* Define an array of Particles */ - Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0}, {"one", 10, 10, 1.0f, 10.0}, - {"two", 20, 20, 2.0f, 20.0}, {"three", 30, 30, 3.0f, 30.0}, - {"four", 40, 40, 4.0f, 40.0}, {"five", 50, 50, 5.0f, 50.0}, - {"six", 60, 60, 6.0f, 60.0}, {"seven", 70, 70, 7.0f, 70.0}}; + Particle p_data[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"four", 40, 40, 4.0F, 40.0}, {"five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /* Define field information */ const char *field_names[NFIELDS] = {"Name", "Latitude", "Longitude", "Pressure", "Temperature"}; @@ -56,7 +56,7 @@ main(void) hid_t file_id; hsize_t chunk_size = 10; int compress = 0; - Particle fill_data[1] = {{"no data", -1, -1, -99.0f, -99.0}}; + Particle fill_data[1] = {{"no data", -1, -1, -99.0F, -99.0}}; hsize_t nfields_out; hsize_t nrecords_out; diff --git a/hl/src/CMakeLists.txt b/hl/src/CMakeLists.txt index 7678de8..a97d6fa 100644 --- a/hl/src/CMakeLists.txt +++ b/hl/src/CMakeLists.txt @@ -169,3 +169,32 @@ if (NOT WIN32 AND NOT MINGW) COMPONENT hllibraries ) endif () + +#----------------------------------------------------------------------------- +# Option to build documentation +#----------------------------------------------------------------------------- +if (DOXYGEN_FOUND) +# This cmake function requires that the non-default doxyfile settings are provided with set (DOXYGEN_xxx) commands +# In addition the doxyfile aliases @INCLUDE option is not supported and would need to be provided in a set (DOXYGEN_ALIASES) command. +# doxygen_add_docs (hdf5lib_doc +## ${HL_SOURCES} ${HL_HEADERS} ${HDF5_DOXYGEN_DIR}/dox +# ${DOXYGEN_INPUT_DIRECTORY} +# ALL +# WORKING_DIRECTORY ${HDF5_HL_SRC_DIR} +# COMMENT "Generating HDF5 HL library Source Documentation" +# ) + +# This custom target and doxygen/configure work together + # Replace variables inside @@ with the current values + add_custom_target (hdf5hllib_doc ALL + COMMAND ${DOXYGEN_EXECUTABLE} ${HDF5_BINARY_DIR}/Doxyfile + WORKING_DIRECTORY ${HDF5_HL_SRC_DIR} + COMMENT "Generating HDF5 HL library Source API documentation with Doxygen" + VERBATIM ) + + if (NOT TARGET doxygen) + add_custom_target (doxygen) + endif () + + add_dependencies (doxygen hdf5hllib_doc) +endif () diff --git a/hl/src/H5LT.c b/hl/src/H5LT.c index 1ef0f9d..8f2b33f 100644 --- a/hl/src/H5LT.c +++ b/hl/src/H5LT.c @@ -1352,13 +1352,13 @@ find_dataset(H5_ATTR_UNUSED hid_t loc_id, const char *name, H5_ATTR_UNUSED const * modify the op_data buffer (i.e.: dset_name) during the traversal, and the * library never modifies that buffer. */ -H5_GCC_DIAG_OFF("cast-qual") +H5_GCC_CLANG_DIAG_OFF("cast-qual") herr_t H5LTfind_dataset(hid_t loc_id, const char *dset_name) { return H5Literate2(loc_id, H5_INDEX_NAME, H5_ITER_INC, 0, find_dataset, (void *)dset_name); } -H5_GCC_DIAG_ON("cast-qual") +H5_GCC_CLANG_DIAG_ON("cast-qual") /*------------------------------------------------------------------------- * @@ -1776,6 +1776,32 @@ H5LTset_attribute_ulong(hid_t loc_id, const char *obj_name, const char *attr_nam } /*------------------------------------------------------------------------- + * Function: H5LTset_attribute_ullong + * + * Purpose: Create and write an attribute. + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Alessandro Felder + * + * Date: August 27, 2021 + * + * Comments: + * + *------------------------------------------------------------------------- + */ +herr_t +H5LTset_attribute_ullong(hid_t loc_id, const char *obj_name, const char *attr_name, + const unsigned long long *data, size_t size) +{ + + if (H5LT_set_attribute_numerical(loc_id, obj_name, attr_name, size, H5T_NATIVE_ULLONG, data) < 0) + return -1; + + return 0; +} + +/*------------------------------------------------------------------------- * Function: H5LTset_attribute_float * * Purpose: Create and write an attribute. @@ -1919,13 +1945,13 @@ H5LTfind_attribute(hid_t loc_id, const char *attr_name) * modify the op_data buffer (i.e.: attr_name) during the traversal, and the * library never modifies that buffer. */ -H5_GCC_DIAG_OFF("cast-qual") +H5_GCC_CLANG_DIAG_OFF("cast-qual") herr_t H5LT_find_attribute(hid_t loc_id, const char *attr_name) { return H5Aiterate2(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, find_attr, (void *)attr_name); } -H5_GCC_DIAG_ON("cast-qual") +H5_GCC_CLANG_DIAG_ON("cast-qual") /*------------------------------------------------------------------------- * Function: H5LTget_attribute_ndims @@ -2180,7 +2206,7 @@ realloc_and_append(hbool_t _no_user_buf, size_t *len, char *buf, const char *str */ if (size_str < *len - 1) { if (size_str + size_str_to_add < *len - 1) { - HDstrncat(buf, str_to_add, size_str_to_add); + HDstrcat(buf, str_to_add); } else { HDstrncat(buf, str_to_add, (*len - 1) - size_str); @@ -3317,6 +3343,33 @@ H5LTget_attribute_ulong(hid_t loc_id, const char *obj_name, const char *attr_nam } /*------------------------------------------------------------------------- + * Function: H5LTget_attribute_ullong + * + * Purpose: Reads an attribute named attr_name + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Alessandro Felder + * + * Date: August 27, 2021 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5LTget_attribute_ullong(hid_t loc_id, const char *obj_name, const char *attr_name, unsigned long long *data) +{ + /* Get the attribute */ + if (H5LT_get_attribute_mem(loc_id, obj_name, attr_name, H5T_NATIVE_ULLONG, data) < 0) + return -1; + + return 0; +} + +/*------------------------------------------------------------------------- * Function: H5LTget_attribute_float * * Purpose: Reads an attribute named attr_name diff --git a/hl/src/H5LTpublic.h b/hl/src/H5LTpublic.h index 2af9b07..f19d353 100644 --- a/hl/src/H5LTpublic.h +++ b/hl/src/H5LTpublic.h @@ -139,6 +139,9 @@ H5_HLDLL herr_t H5LTset_attribute_long_long(hid_t loc_id, const char *obj_name, H5_HLDLL herr_t H5LTset_attribute_ulong(hid_t loc_id, const char *obj_name, const char *attr_name, const unsigned long *buffer, size_t size); +H5_HLDLL herr_t H5LTset_attribute_ullong(hid_t loc_id, const char *obj_name, const char *attr_name, + const unsigned long long *buffer, size_t size); + H5_HLDLL herr_t H5LTset_attribute_float(hid_t loc_id, const char *obj_name, const char *attr_name, const float *buffer, size_t size); @@ -182,6 +185,9 @@ H5_HLDLL herr_t H5LTget_attribute_long_long(hid_t loc_id, const char *obj_name, H5_HLDLL herr_t H5LTget_attribute_ulong(hid_t loc_id, const char *obj_name, const char *attr_name, unsigned long *data); +H5_HLDLL herr_t H5LTget_attribute_ullong(hid_t loc_id, const char *obj_name, const char *attr_name, + unsigned long long *data); + H5_HLDLL herr_t H5LTget_attribute_float(hid_t loc_id, const char *obj_name, const char *attr_name, float *data); diff --git a/hl/test/gen_test_ds.c b/hl/test/gen_test_ds.c index 368c083..a56e6cf 100644 --- a/hl/test/gen_test_ds.c +++ b/hl/test/gen_test_ds.c @@ -75,7 +75,7 @@ main(int argc, char **argv) int nerrors = 0; char filename[65]; - if (argc < 2) { + if (argc < 2 || !argv[0] || !argv[1]) { HDprintf("Usage: gen_test [le | be]\n"); return 1; } diff --git a/hl/test/test_ds.c b/hl/test/test_ds.c index 8c6ef91..964e13f 100644 --- a/hl/test/test_ds.c +++ b/hl/test/test_ds.c @@ -5210,6 +5210,8 @@ test_attach_detach(void) HL_TESTING2("permutations of attaching and detaching"); + gid = var1_id = var2_id = var3_id = H5I_INVALID_HID; + if ((fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) goto out; diff --git a/hl/test/test_lite.c b/hl/test/test_lite.c index cae91ff..53f834a 100644 --- a/hl/test/test_lite.c +++ b/hl/test/test_lite.c @@ -43,8 +43,9 @@ #define ATTR7_NAME "attr ushort" #define ATTR8_NAME "attr uint" #define ATTR9_NAME "attr ulong" -#define ATTR10_NAME "attr float" -#define ATTR11_NAME "attr double" +#define ATTR10_NAME "attr ullong" +#define ATTR11_NAME "attr float" +#define ATTR12_NAME "attr double" static herr_t make_attributes(hid_t loc_id, const char *obj_name); @@ -472,28 +473,30 @@ make_attributes(hid_t loc_id, const char *obj_name) size_t type_size; int i; - char attr_str_in[] = {"My attribute"}; - char attr_str_out[20]; - char attr_char_in[5] = {1, 2, 3, 4, 5}; - char attr_char_out[5]; - short attr_short_in[5] = {1, 2, 3, 4, 5}; - short attr_short_out[5]; - int attr_int_in[5] = {1, 2, 3, 4, 5}; - int attr_int_out[5]; - long attr_long_in[5] = {1, 2, 3, 4, 5}; - long attr_long_out[5]; - float attr_float_in[5] = {1, 2, 3, 4, 5}; - float attr_float_out[5]; - double attr_double_in[5] = {1, 2, 3, 4, 5}; - double attr_double_out[5]; - unsigned char attr_uchar_in[5] = {1, 2, 3, 4, 5}; - unsigned char attr_uchar_out[5]; - unsigned short attr_ushort_in[5] = {1, 2, 3, 4, 5}; - unsigned short attr_ushort_out[5]; - unsigned int attr_uint_in[5] = {1, 2, 3, 4, 5}; - unsigned int attr_uint_out[5]; - unsigned long attr_ulong_in[5] = {1, 2, 3, 4, 5}; - unsigned long attr_ulong_out[5]; + char attr_str_in[] = {"My attribute"}; + char attr_str_out[20]; + char attr_char_in[5] = {1, 2, 3, 4, 5}; + char attr_char_out[5]; + short attr_short_in[5] = {1, 2, 3, 4, 5}; + short attr_short_out[5]; + int attr_int_in[5] = {1, 2, 3, 4, 5}; + int attr_int_out[5]; + long attr_long_in[5] = {1, 2, 3, 4, 5}; + long attr_long_out[5]; + float attr_float_in[5] = {1, 2, 3, 4, 5}; + float attr_float_out[5]; + double attr_double_in[5] = {1, 2, 3, 4, 5}; + double attr_double_out[5]; + unsigned char attr_uchar_in[5] = {1, 2, 3, 4, 5}; + unsigned char attr_uchar_out[5]; + unsigned short attr_ushort_in[5] = {1, 2, 3, 4, 5}; + unsigned short attr_ushort_out[5]; + unsigned int attr_uint_in[5] = {1, 2, 3, 4, 5}; + unsigned int attr_uint_out[5]; + unsigned long attr_ulong_in[5] = {1, 2, 3, 4, 5}; + unsigned long attr_ulong_out[5]; + unsigned long long attr_ullong_in[5] = {1, 2, 3, 4, 5}; + unsigned long long attr_ullong_out[5]; /*------------------------------------------------------------------------- * H5LTset_attribute_string test @@ -509,7 +512,7 @@ make_attributes(hid_t loc_id, const char *obj_name) PASSED(); /*------------------------------------------------------------------------- - * H5LTset_attribute_string test + * H5LTget_attribute_string test *------------------------------------------------------------------------- */ @@ -859,7 +862,7 @@ make_attributes(hid_t loc_id, const char *obj_name) PASSED(); /*------------------------------------------------------------------------- - * H5LTget_attribute_long test + * H5LTget_attribute_ulong test *------------------------------------------------------------------------- */ @@ -888,6 +891,48 @@ make_attributes(hid_t loc_id, const char *obj_name) PASSED(); /*------------------------------------------------------------------------- + * H5LTset_attribute_ullong test + *------------------------------------------------------------------------- + */ + + HL_TESTING2("H5LTset_attribute_ullong"); + + /* Set the attribute */ + if (H5LTset_attribute_ullong(loc_id, obj_name, ATTR10_NAME, attr_ullong_in, (size_t)5) < 0) + return -1; + + PASSED(); + + /*------------------------------------------------------------------------- + * H5LTget_attribute_ullong test + *------------------------------------------------------------------------- + */ + + HL_TESTING2("H5LTget_attribute_ullong"); + + /* Get the attribute */ + if (H5LTget_attribute_ullong(loc_id, obj_name, ATTR10_NAME, attr_ullong_out) < 0) + return -1; + + for (i = 0; i < 5; i++) { + if (attr_ullong_in[i] != attr_ullong_out[i]) { + return -1; + } + } + + /* Get the attribute */ + if (H5LTget_attribute(loc_id, obj_name, ATTR10_NAME, H5T_NATIVE_ULLONG, attr_ullong_out) < 0) + return -1; + + for (i = 0; i < 5; i++) { + if (attr_ullong_in[i] != attr_ullong_out[i]) { + return -1; + } + } + + PASSED(); + + /*------------------------------------------------------------------------- * H5LTset_attribute_float test *------------------------------------------------------------------------- */ @@ -895,7 +940,7 @@ make_attributes(hid_t loc_id, const char *obj_name) HL_TESTING2("H5LTset_attribute_float"); /* Set the attribute */ - if (H5LTset_attribute_float(loc_id, obj_name, ATTR10_NAME, attr_float_in, (size_t)5) < 0) + if (H5LTset_attribute_float(loc_id, obj_name, ATTR11_NAME, attr_float_in, (size_t)5) < 0) return -1; PASSED(); @@ -908,7 +953,7 @@ make_attributes(hid_t loc_id, const char *obj_name) HL_TESTING2("H5LTget_attribute_float"); /* Get the attribute */ - if (H5LTget_attribute_float(loc_id, obj_name, ATTR10_NAME, attr_float_out) < 0) + if (H5LTget_attribute_float(loc_id, obj_name, ATTR11_NAME, attr_float_out) < 0) return -1; for (i = 0; i < 5; i++) { @@ -918,7 +963,7 @@ make_attributes(hid_t loc_id, const char *obj_name) } /* Get the attribute */ - if (H5LTget_attribute(loc_id, obj_name, ATTR10_NAME, H5T_NATIVE_FLOAT, attr_float_out) < 0) + if (H5LTget_attribute(loc_id, obj_name, ATTR11_NAME, H5T_NATIVE_FLOAT, attr_float_out) < 0) return -1; for (i = 0; i < 5; i++) { @@ -937,7 +982,7 @@ make_attributes(hid_t loc_id, const char *obj_name) HL_TESTING2("H5LTset_attribute_double"); /* Set the attribute */ - if (H5LTset_attribute_double(loc_id, obj_name, ATTR11_NAME, attr_double_in, (size_t)5) < 0) + if (H5LTset_attribute_double(loc_id, obj_name, ATTR12_NAME, attr_double_in, (size_t)5) < 0) return -1; PASSED(); @@ -950,7 +995,7 @@ make_attributes(hid_t loc_id, const char *obj_name) HL_TESTING2("H5LTget_attribute_double"); /* Get the attribute */ - if (H5LTget_attribute_double(loc_id, obj_name, ATTR11_NAME, attr_double_out) < 0) + if (H5LTget_attribute_double(loc_id, obj_name, ATTR12_NAME, attr_double_out) < 0) return -1; for (i = 0; i < 5; i++) { @@ -960,7 +1005,7 @@ make_attributes(hid_t loc_id, const char *obj_name) } /* Get the attribute */ - if (H5LTget_attribute(loc_id, obj_name, ATTR11_NAME, H5T_NATIVE_DOUBLE, attr_double_out) < 0) + if (H5LTget_attribute(loc_id, obj_name, ATTR12_NAME, H5T_NATIVE_DOUBLE, attr_double_out) < 0) return -1; for (i = 0; i < 5; i++) { diff --git a/hl/test/test_packet.c b/hl/test/test_packet.c index 1d3a569..5f30d4b 100644 --- a/hl/test/test_packet.c +++ b/hl/test/test_packet.c @@ -45,10 +45,10 @@ typedef struct particle_t { * a static array of particles for writing and checking reads *------------------------------------------------------------------------- */ -static particle_t testPart[NRECORDS] = {{"zero", 0, 0, 0.0f, 0.0f}, {"one", 10, 10, 1.0f, 10.0f}, - {"two", 20, 20, 2.0f, 20.0f}, {"three", 30, 30, 3.0f, 30.0f}, - {"four", 40, 40, 4.0f, 40.0f}, {"five", 50, 50, 5.0f, 50.0f}, - {"six", 60, 60, 6.0f, 60.0f}, {"seven", 70, 70, 7.0f, 70.0f}}; +static particle_t testPart[NRECORDS] = {{"zero", 0, 0, 0.0F, 0.0}, {"one", 10, 10, 1.0F, 10.0}, + {"two", 20, 20, 2.0F, 20.0}, {"three", 30, 30, 3.0F, 30.0}, + {"Four", 40, 40, 4.0F, 40.0}, {"Five", 50, 50, 5.0F, 50.0}, + {"six", 60, 60, 6.0F, 60.0}, {"seven", 70, 70, 7.0F, 70.0}}; /*------------------------------------------------------------------------- * function that compares one particle diff --git a/hl/test/test_table.c b/hl/test/test_table.c index 0d4a72a..6199e27 100644 --- a/hl/test/test_table.c +++ b/hl/test/test_table.c @@ -199,7 +199,7 @@ test_table(hid_t fid, int do_write) hsize_t chunk_size = 10; int compress = 0; int * fill = NULL; - particle_t fill1[1] = {{"no data", -1, -99.0f, -99.0f, -1}}; + particle_t fill1[1] = {{"no data", -1, -99.0, -99.0, -1}}; int fill1_new[1] = {-100}; hsize_t position; char tname[20]; @@ -227,25 +227,25 @@ test_table(hid_t fid, int do_write) particle2_t rbuf2[NRECORDS]; particle3_t rbuf3[NRECORDS]; particle_t rbufc[NRECORDS * 2]; - particle_t abuf[2] = {{"eight", 80, 8.0f, 80.0f, 80}, {"nine", 90, 9.0f, 90.0f, 90}}; - particle_t ibuf[2] = {{"zero", 0, 0.0f, 0.0f, 0}, {"zero", 0, 0.0f, 0.0f, 0}}; + particle_t abuf[2] = {{"eight", 80, 8.0, 80.0, 80}, {"nine", 90, 9.0, 90.0, 90}}; + particle_t ibuf[2] = {{"zero", 0, 0.0, 0.0, 0}, {"zero", 0, 0.0, 0.0, 0}}; particle_t wbufd[NRECORDS]; particle_t wbuf[NRECORDS] = {{ "zero", 0, - 0.0f, - 0.0f, + 0.0, + 0.0, 0, }, - {"one", 10, 1.0f, 10.0f, 10}, - {"two", 20, 2.0f, 20.0f, 20}, - {"three", 30, 3.0f, 30.0f, 30}, - {"four", 40, 4.0f, 40.0f, 40}, - {"five", 50, 5.0f, 50.0f, 50}, - {"six", 60, 6.0f, 60.0f, 60}, - {"seven", 70, 7.0f, 70.0f, 70}}; + {"one", 10, 1.0, 10.0, 10}, + {"two", 20, 2.0, 20.0, 20}, + {"three", 30, 3.0, 30.0, 30}, + {"four", 40, 4.0, 40.0, 40}, + {"five", 50, 5.0, 50.0, 50}, + {"six", 60, 6.0, 60.0, 60}, + {"seven", 70, 7.0, 70.0, 70}}; /* buffers for the field "Pressure" and "New_field" */ - float pressure_in[NRECORDS] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f}; + float pressure_in[NRECORDS] = {0.0F, 1.0F, 2.0F, 3.0F, 4.0F, 5.0F, 6.0F, 7.0F}; float pressure_out[NRECORDS]; int buf_new[NRECORDS] = {0, 1, 2, 3, 4, 5, 6, 7}; /* buffers for the fields "Latitude,Longitude" */ @@ -254,8 +254,8 @@ test_table(hid_t fid, int do_write) /* buffers for the fields "Name,Pressure" */ namepressure_t namepre_out[NRECORDS]; namepressure_t namepre_in[NRECORDS] = { - {"zero", 0.0f}, {"one", 1.0f}, {"two", 2.0f}, {"three", 3.0f}, - {"four", 4.0f}, {"five", 5.0f}, {"six", 6.0f}, {"seven", 7.0f}, + {"zero", 0.0F}, {"one", 1.0F}, {"two", 2.0F}, {"three", 3.0F}, + {"four", 4.0F}, {"five", 5.0F}, {"six", 6.0F}, {"seven", 7.0F}, }; /*------------------------------------------------------------------------- @@ -332,14 +332,14 @@ test_table(hid_t fid, int do_write) HOFFSET(particle4_t, aty), HOFFSET(particle4_t, rro)}; /* Define an array of Particles */ - particle4_t p_data[NRECORDS] = {{12112, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12113, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12114, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12115, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12116, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12117, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12118, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}, - {12119, 1.4f, 2.5f, {1, 2, 3}, {4, 5, 6}, {99, 100}}}; + particle4_t p_data[NRECORDS] = {{12112, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12113, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12114, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12115, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12116, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12117, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12118, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}, + {12119, 1.4, 2.5, {1, 2, 3}, {4, 5, 6}, {99, 100}}}; /*------------------------------------------------------------------------- * initialize table parameters diff --git a/hl/tools/h5watch/h5watchgentest.c b/hl/tools/h5watch/h5watchgentest.c index c83e485..44cb0cb 100644 --- a/hl/tools/h5watch/h5watchgentest.c +++ b/hl/tools/h5watch/h5watchgentest.c @@ -224,7 +224,7 @@ main(void) one_cbuf[i].field2.b.a = 20; one_cbuf[i].field2.b.b = 40; one_cbuf[i].field2.b.c = 80; - one_cbuf[i].field3 = 3.0F; + one_cbuf[i].field3 = 3.0; one_cbuf[i].field4.a = 4; one_cbuf[i].field4.b = 8; } /* end for */ @@ -313,7 +313,7 @@ main(void) two_cbuf[i].field2.b.a = 20; two_cbuf[i].field2.b.b = 40; two_cbuf[i].field2.b.c = 80; - two_cbuf[i].field3 = 3.0F; + two_cbuf[i].field3 = 3.0; two_cbuf[i].field4.a = 4; two_cbuf[i].field4.b = 8; } /* end for */ diff --git a/java/src/hdf/hdf5lib/HDFArray.java b/java/src/hdf/hdf5lib/HDFArray.java index bb9357e..21e2b02 100644 --- a/java/src/hdf/hdf5lib/HDFArray.java +++ b/java/src/hdf/hdf5lib/HDFArray.java @@ -46,10 +46,10 @@ public class HDFArray { * * @param anArray * The array object. - * @exception hdf.hdf5lib.exceptions.HDF5Exception - * object is not an array. + * @exception hdf.hdf5lib.exceptions.HDF5JavaException + * object is not an array. */ - public HDFArray(Object anArray) throws HDF5Exception + public HDFArray(Object anArray) throws HDF5JavaException { if (anArray == null) { HDF5JavaException ex = new HDF5JavaException("HDFArray: array is null?: "); @@ -76,16 +76,14 @@ public class HDFArray { * @return A one-D array of bytes, filled with zeroes. The bytes are sufficient to hold the data of the Array passed * to the constructor. * @exception hdf.hdf5lib.exceptions.HDF5JavaException - * Allocation failed. + * Allocation failed. */ - public byte[] emptyBytes() - throws HDF5JavaException + public byte[] emptyBytes() throws HDF5JavaException { byte[] b = null; - if ((ArrayDescriptor.dims == 1) - && (ArrayDescriptor.NT == 'B')) { + if ((ArrayDescriptor.dims == 1) && (ArrayDescriptor.NT == 'B')) { b = (byte[]) _theArray; } else { @@ -103,10 +101,9 @@ public class HDFArray { * * @return A one-D array of bytes, constructed from the Array passed to the constructor. * @exception hdf.hdf5lib.exceptions.HDF5JavaException - * the object not an array or other internal error. + * the object not an array or other internal error. */ - public byte[] byteify() - throws HDF5JavaException + public byte[] byteify() throws HDF5JavaException { if (_barray != null) { return _barray; @@ -224,8 +221,6 @@ public class HDFArray { if (ArrayDescriptor.NT == 'J') { arow = HDFNativeData.longToByte(0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], (long[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); - arow = HDFNativeData.longToByte(0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], - (long[]) ArrayDescriptor.objs[ArrayDescriptor.dims - 1]); } else if (ArrayDescriptor.NT == 'I') { arow = HDFNativeData.intToByte(0, ArrayDescriptor.dimlen[ArrayDescriptor.dims], @@ -552,8 +547,7 @@ public class HDFArray { + "?")); } } - if (ArrayDescriptor.currentindex[ArrayDescriptor.dims - 1] != ArrayDescriptor.dimlen[ArrayDescriptor.dims - - 1]) { + if (ArrayDescriptor.currentindex[ArrayDescriptor.dims - 1] != ArrayDescriptor.dimlen[ArrayDescriptor.dims - 1]) { throw new java.lang.InternalError( new String("HDFArray::arrayify Panic didn't complete all data: currentindex[" + i + "] = " + ArrayDescriptor.currentindex[i] + " (should be " + (ArrayDescriptor.dimlen[i]) + "?")); @@ -580,7 +574,7 @@ public class HDFArray { Integer[] out = new Integer[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Integer(in[i]); + out[i] = Integer.valueOf(in[i]); } return out; } @@ -592,7 +586,7 @@ public class HDFArray { Integer[] out = new Integer[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Integer(in[i]); + out[i] = Integer.valueOf(in[i]); } return out; } @@ -615,7 +609,7 @@ public class HDFArray { Short[] out = new Short[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Short(in[i]); + out[i] = Short.valueOf(in[i]); } return out; } @@ -627,7 +621,7 @@ public class HDFArray { Short[] out = new Short[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Short(in[i]); + out[i] = Short.valueOf(in[i]); } return out; } @@ -649,7 +643,7 @@ public class HDFArray { Byte[] out = new Byte[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Byte(bin[i]); + out[i] = Byte.valueOf(bin[i]); } return out; } @@ -659,7 +653,7 @@ public class HDFArray { Byte[] out = new Byte[len]; for (int i = 0; i < len; i++) { - out[i] = new Byte(bin[i]); + out[i] = Byte.valueOf(bin[i]); } return out; } @@ -682,7 +676,7 @@ public class HDFArray { Float[] out = new Float[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Float(in[i]); + out[i] = Float.valueOf(in[i]); } return out; } @@ -694,7 +688,7 @@ public class HDFArray { Float[] out = new Float[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Float(in[i]); + out[i] = Float.valueOf(in[i]); } return out; } @@ -717,7 +711,7 @@ public class HDFArray { Double[] out = new Double[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Double(in[i]); + out[i] = Double.valueOf(in[i]); } return out; } @@ -729,7 +723,7 @@ public class HDFArray { Double[] out = new Double[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Double(in[i]); + out[i] = Double.valueOf(in[i]); } return out; } @@ -752,7 +746,7 @@ public class HDFArray { Long[] out = new Long[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Long(in[i]); + out[i] = Long.valueOf(in[i]); } return out; } @@ -764,7 +758,7 @@ public class HDFArray { Long[] out = new Long[nelems]; for (int i = 0; i < nelems; i++) { - out[i] = new Long(in[i]); + out[i] = Long.valueOf(in[i]); } return out; } @@ -790,12 +784,12 @@ class ArrayDescriptor { static int dims = 0; static String className; - public ArrayDescriptor(Object anArray) throws HDF5Exception + public ArrayDescriptor(Object anArray) throws HDF5JavaException { Class tc = anArray.getClass(); if (tc.isArray() == false) { /* exception: not an array */ - HDF5Exception ex = new HDF5JavaException("ArrayDescriptor: not an array?: "); + HDF5JavaException ex = new HDF5JavaException("ArrayDescriptor: not an array?: "); throw (ex); } diff --git a/java/src/hdf/hdf5lib/HDFNativeData.java b/java/src/hdf/hdf5lib/HDFNativeData.java index 5b29050..85378db 100644 --- a/java/src/hdf/hdf5lib/HDFNativeData.java +++ b/java/src/hdf/hdf5lib/HDFNativeData.java @@ -153,8 +153,7 @@ public class HDFNativeData { * The input array of bytes * @return an array of 'len' float */ - public synchronized static native float[] byteToFloat(int start, int len, - byte[] data); + public synchronized static native float[] byteToFloat(int start, int len, byte[] data); /** * Convert 4 bytes from an array of bytes into a single float @@ -437,41 +436,38 @@ public class HDFNativeData { * - Error unsupported type. */ public synchronized static Object byteToNumber(byte[] barray, Object obj) - throws HDF5Exception { + throws HDF5Exception + { Class theClass = obj.getClass(); String type = theClass.getName(); Object retobj = null; if (type.equals("java.lang.Integer")) { int[] i = hdf.hdf5lib.HDFNativeData.byteToInt(0, 1, barray); - retobj = new Integer(i[0]); + retobj = Integer.valueOf(i[0]); } else if (type.equals("java.lang.Byte")) { - retobj = new Byte(barray[0]); + retobj = Byte.valueOf(barray[0]); } else if (type.equals("java.lang.Short")) { - short[] f = hdf.hdf5lib.HDFNativeData - .byteToShort(0, 1, barray); - retobj = new Short(f[0]); + short[] f = hdf.hdf5lib.HDFNativeData.byteToShort(0, 1, barray); + retobj = Short.valueOf(f[0]); } else if (type.equals("java.lang.Float")) { - float[] f = hdf.hdf5lib.HDFNativeData - .byteToFloat(0, 1, barray); - retobj = new Float(f[0]); + float[] f = hdf.hdf5lib.HDFNativeData.byteToFloat(0, 1, barray); + retobj = Float.valueOf(f[0]); } else if (type.equals("java.lang.Long")) { long[] f = hdf.hdf5lib.HDFNativeData.byteToLong(0, 1, barray); - retobj = new Long(f[0]); + retobj = Long.valueOf(f[0]); } else if (type.equals("java.lang.Double")) { - double[] f = hdf.hdf5lib.HDFNativeData.byteToDouble(0, 1, - barray); - retobj = new Double(f[0]); + double[] f = hdf.hdf5lib.HDFNativeData.byteToDouble(0, 1, barray); + retobj = Double.valueOf(f[0]); } else { /* exception: unsupported type */ - HDF5Exception ex = new HDF5JavaException( - "byteToNumber: setfield bad type: " + obj + " " + type); + HDF5Exception ex = new HDF5JavaException("byteToNumber: setfield bad type: " + obj + " " + type); throw (ex); } return (retobj); diff --git a/java/src/hdf/hdf5lib/structs/H5FD_hdfs_fapl_t.java b/java/src/hdf/hdf5lib/structs/H5FD_hdfs_fapl_t.java index 5da4abd..95a9254 100644 --- a/java/src/hdf/hdf5lib/structs/H5FD_hdfs_fapl_t.java +++ b/java/src/hdf/hdf5lib/structs/H5FD_hdfs_fapl_t.java @@ -1,15 +1,14 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Read-Only HDFS Virtual File Driver (VFD) * - * Copyright (c) 2018, The HDF Group. * + * Copyright by The HDF Group. * * * * All rights reserved. * * * - * NOTICE: * - * All information contained herein is, and remains, the property of The HDF * - * Group. The intellectual and technical concepts contained herein are * - * proprietary to The HDF Group. Dissemination of this information or * - * reproduction of this material is strictly forbidden unless prior written * - * permission is obtained from The HDF Group. * + * 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://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ package hdf.hdf5lib.structs; diff --git a/java/src/hdf/hdf5lib/structs/H5FD_ros3_fapl_t.java b/java/src/hdf/hdf5lib/structs/H5FD_ros3_fapl_t.java index 39f5424..ad02979 100644 --- a/java/src/hdf/hdf5lib/structs/H5FD_ros3_fapl_t.java +++ b/java/src/hdf/hdf5lib/structs/H5FD_ros3_fapl_t.java @@ -1,15 +1,14 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Read-Only S3 Virtual File Driver (VFD) * - * Copyright (c) 2017-2018, The HDF Group. * + * Copyright by The HDF Group. * * * * All rights reserved. * * * - * NOTICE: * - * All information contained herein is, and remains, the property of The HDF * - * Group. The intellectual and technical concepts contained herein are * - * proprietary to The HDF Group. Dissemination of this information or * - * reproduction of this material is strictly forbidden unless prior written * - * permission is obtained from The HDF Group. * + * 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://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ package hdf.hdf5lib.structs; diff --git a/java/src/jni/h5Constants.c b/java/src/jni/h5Constants.c index 7354e95..bdffdbd 100644 --- a/java/src/jni/h5Constants.c +++ b/java/src/jni/h5Constants.c @@ -26,8 +26,8 @@ extern "C" { #include <stdlib.h> #include "h5jni.h" -H5_GCC_DIAG_OFF("missing-prototypes") -H5_GCC_DIAG_OFF("unused-parameter") +H5_GCC_CLANG_DIAG_OFF("missing-prototypes") +H5_GCC_CLANG_DIAG_OFF("unused-parameter") JNIEXPORT jlong JNICALL Java_hdf_hdf5lib_HDF5Constants_H5_1QUARTER_1HADDR_1MAX(JNIEnv *env, jclass cls) @@ -1212,7 +1212,7 @@ Java_hdf_hdf5lib_HDF5Constants_H5ES_1STATUS_1FAIL(JNIEnv *env, jclass cls) } /* Java does not have unsigned native types */ -H5_GCC_DIAG_OFF("sign-conversion") +H5_GCC_CLANG_DIAG_OFF("sign-conversion") JNIEXPORT jint JNICALL Java_hdf_hdf5lib_HDF5Constants_H5F_1ACC_1CREAT(JNIEnv *env, jclass cls) { @@ -1253,7 +1253,7 @@ Java_hdf_hdf5lib_HDF5Constants_H5F_1ACC_1SWMR_1WRITE(JNIEnv *env, jclass cls) { return H5F_ACC_SWMR_WRITE; } -H5_GCC_DIAG_ON("sign-conversion") +H5_GCC_CLANG_DIAG_ON("sign-conversion") JNIEXPORT jint JNICALL Java_hdf_hdf5lib_HDF5Constants_H5F_1CLOSE_1DEFAULT(JNIEnv *env, jclass cls) @@ -3724,8 +3724,8 @@ Java_hdf_hdf5lib_HDF5Constants_H5Z_1FILTER_1ALL(JNIEnv *env, jclass cls) return H5Z_FILTER_ALL; } -H5_GCC_DIAG_ON("missing-prototypes") -H5_GCC_DIAG_ON("unused-parameter") +H5_GCC_CLANG_DIAG_ON("missing-prototypes") +H5_GCC_CLANG_DIAG_ON("unused-parameter") #ifdef __cplusplus } /* end extern "C" */ diff --git a/java/src/jni/h5util.c b/java/src/jni/h5util.c index 8021438..4272205 100644 --- a/java/src/jni/h5util.c +++ b/java/src/jni/h5util.c @@ -870,11 +870,8 @@ h5str_sprintf(JNIEnv *env, h5str_t *out_str, hid_t container, hid_t tid, void *i } else { if (typeSize > 0) { - if (NULL == (this_str = (char *)HDmalloc(typeSize + 1))) + if (NULL == (this_str = HDstrdup(tmp_str))) H5_OUT_OF_MEMORY_ERROR(ENVONLY, "h5str_sprintf: failed to allocate string buffer"); - - HDstrncpy(this_str, tmp_str, typeSize); - this_str[typeSize] = '\0'; } } @@ -3664,19 +3661,14 @@ obj_info_all(hid_t loc_id, const char *name, const H5L_info2_t *info, void *op_d info_all_t *datainfo = (info_all_t *)op_data; H5O_info2_t object_info; htri_t object_exists; - size_t str_len; datainfo->otype[datainfo->count] = -1; datainfo->ltype[datainfo->count] = -1; datainfo->obj_token[datainfo->count] = H5O_TOKEN_UNDEF; - str_len = HDstrlen(name); - if (NULL == (datainfo->objname[datainfo->count] = (char *)HDmalloc(str_len + 1))) + if (NULL == (datainfo->objname[datainfo->count] = HDstrdup(name))) goto done; - HDstrncpy(datainfo->objname[datainfo->count], name, str_len); - (datainfo->objname[datainfo->count])[str_len] = '\0'; - if ((object_exists = H5Oexists_by_name(loc_id, name, H5P_DEFAULT)) < 0) goto done; @@ -3702,7 +3694,6 @@ obj_info_max(hid_t loc_id, const char *name, const H5L_info2_t *info, void *op_d { info_all_t *datainfo = (info_all_t *)op_data; H5O_info2_t object_info; - size_t str_len; datainfo->otype[datainfo->count] = -1; datainfo->ltype[datainfo->count] = -1; @@ -3710,13 +3701,9 @@ obj_info_max(hid_t loc_id, const char *name, const H5L_info2_t *info, void *op_d datainfo->obj_token[datainfo->count] = H5O_TOKEN_UNDEF; /* This will be freed by h5str_array_free(oName, n) */ - str_len = HDstrlen(name); - if (NULL == (datainfo->objname[datainfo->count] = (char *)HDmalloc(str_len + 1))) + if (NULL == (datainfo->objname[datainfo->count] = HDstrdup(name))) goto done; - HDstrncpy(datainfo->objname[datainfo->count], name, str_len); - (datainfo->objname[datainfo->count])[str_len] = '\0'; - if (H5Oget_info3(loc_id, &object_info, H5O_INFO_ALL) < 0) goto done; diff --git a/java/test/TestH5Arw.java b/java/test/TestH5Arw.java index 282b736..8ce2fee 100644 --- a/java/test/TestH5Arw.java +++ b/java/test/TestH5Arw.java @@ -100,7 +100,7 @@ public class TestH5Arw { if (H5aid >= 0) try {H5.H5Aclose(H5aid);} catch (Exception ex) {} if (H5did >= 0) - try {H5.H5Aclose(H5did);} catch (Exception ex) {} + try {H5.H5Dclose(H5did);} catch (Exception ex) {} if (H5fid > 0) try {H5.H5Fclose(H5fid);} catch (Exception ex) {} H5fid = HDF5Constants.H5I_INVALID_HID; diff --git a/java/test/TestH5Pfapl.java b/java/test/TestH5Pfapl.java index cc674e2..a65b52e 100644 --- a/java/test/TestH5Pfapl.java +++ b/java/test/TestH5Pfapl.java @@ -102,7 +102,7 @@ public class TestH5Pfapl { for(int indx = 0; ;indx++) { java.text.DecimalFormat myFormat = new java.text.DecimalFormat("00000"); try { - file = new File("test"+myFormat.format(new Integer(indx))+".h5"); + file = new File("test"+myFormat.format(Integer.valueOf(indx))+".h5"); } catch (Throwable err) {} diff --git a/release_docs/INSTALL_CMake.txt b/release_docs/INSTALL_CMake.txt index 5d11957..91eb593 100644 --- a/release_docs/INSTALL_CMake.txt +++ b/release_docs/INSTALL_CMake.txt @@ -740,6 +740,7 @@ HDF5_BUILD_FORTRAN "Build FORTRAN support" OFF HDF5_BUILD_JAVA "Build JAVA support" OFF HDF5_BUILD_HL_LIB "Build HIGH Level HDF5 Library" ON HDF5_BUILD_TOOLS "Build HDF5 Tools" ON +HDF5_BUILD_HL_TOOLS "Build HIGH Level HDF5 Tools" ON ---------------- HDF5 Advanced Options --------------------- ONLY_SHARED_LIBS "Only Build Shared Libraries" OFF diff --git a/release_docs/README_HDF5_CMake b/release_docs/README_HDF5_CMake index cf0ab6f..c575320 100644 --- a/release_docs/README_HDF5_CMake +++ b/release_docs/README_HDF5_CMake @@ -1,15 +1,16 @@ This tar file contains - build-unix.sh script to build HDF5 with CMake on unix machines - build-unix-hpc.sh script to build HDF5 with CMake on unix machines and run - tests with batch scripts (sbatch). + build-unix.sh script to build HDF5 with CMake on unix machines + build-unix-hpc.sh script to build HDF5 with CMake on unix machines and run + tests with batch scripts (sbatch). CTestScript.cmake - HDF5config.cmake CMake scripts for building HDF5 + HDF5config.cmake CMake scripts for building HDF5 HDF5options.cmake - hdf5-1.13.0 HDF5 1.13.0 source - LIBAEC.tar.gz source for building SZIP replacement - ZLib.tar.gz source for building ZLIB - hdf5_plugins.tar.gz source for building compression plugins + hdf5-1.13.0 HDF5 1.13.0 source + LIBAEC.tar.gz source for building SZIP replacement + ZLib.tar.gz source for building ZLIB + hdf5_plugins.tar.gz source for building compression plugins + HDF5Examples-1.14.4-Source.tar.gz source for building examples For more information about building HDF5 with CMake, see USING_HDF5_CMake.txt in hdf5-1.13.0/release_docs, or diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 1e69f54..ed12c5e 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -49,6 +49,14 @@ New Features Configuration: ------------- + - Added new option to control the build of High-Level tools + that default ON/enabled. + + Add configure options (autotools - CMake): + enable-hltools HDF5_BUILD_HL_TOOLS + + (ADB - 2021/09/16, HDFFV-11266) + - Adds C++ Autotools configuration file for Intel * Checks for icpc as the compiler @@ -463,6 +471,25 @@ New Features Library: -------- + - Change how the release part of version, in major.minor.release is checked + for compatibility + + The HDF5 library uses a function, H5check_version, to check that + the version defined in the header files, which is used to compile an + application is compatible with the version codified in the library, which + the application loads at runtime. This previously required an exact match + or the library would print a warning, dump the build settings and then + abort or continue. An environment variable controlled the logic. + + Now the function first checks that the library release version, in + major.minor.release, is not older than the version in the headers. + Secondly, if the release version is different, it checks if either + the library version or the header version is in the exception list, in + which case the release part of version, in major.minor.release, must + be exact. An environment variable still controls the logic. + + (ADB - 2021/07/27) + - gcc warning suppression macros were moved out of H5public.h The HDF5 library uses a set of macros to suppress warnings on gcc. @@ -726,6 +753,11 @@ New Features Fortran Library: ---------------- + - H5Fget_name_f fixed to handle correctly trailing whitespaces and + newly allocated buffers. + + (MSB - 2021/08/30, github-826,972) + - Add wrappers for H5Pset/get_file_locking() API calls h5pget_file_locking_f() @@ -801,6 +833,26 @@ New Features Tools: ------ + - Refactored the perform tools and removed depends on test library. + + Moved the perf and h5perf tools from tools/test/perform to + tools/src/h5perf so that they can be installed. This required + that the test library dependency be removed by copying the + needed functions from h5test.c. + The standalone scripts and other perform tools remain in the + tools/test/perform folder. + + (ADB - 2021/08/10) + + - Removed partial long exceptions + + Some of the tools accepted shortened versions of the long options + (ex: --datas instead of --dataset). These were implemented inconsistently, + are difficult to maintian, and occasionally block useful long option + names. These partial long options have been removed from all the tools. + + (DER - 2021/08/03) + - h5repack added help text for user-defined filters. Added help text line that states the valid values of the filter flag @@ -863,7 +915,13 @@ New Features High-Level APIs: ---------------- - - + - added set/get for unsigned long long attributes + + the attribute writing high-level API has been expanded to include + public set/get functions for ULL attributes, analogously to the + existing set/get for other types. + + (AF - 2021/09/08) C Packet Table API: ------------------- @@ -885,6 +943,35 @@ Bug Fixes since HDF5-1.12.0 release =================================== Library ------- + - Detection of simple data transform function "x" + + In the case of the simple data transform function "x" the (parallel) + library recognizes this is the same as not applying this data transform + function. This improves the I/O performance. In the case of the parallel + library, it also avoids breaking to independent I/O, which makes it + possible to apply a filter when writing or reading data to or from + teh HDF5 file. + + (JWSB - 2021/09/13) + + - Fixed an invalid read and memory leak when parsing corrupt file space + info messages + + When the corrupt file from CVE-2020-10810 was parsed by the library, + the code that imports the version 0 file space info object header + message to the version 1 struct could read past the buffer read from + the disk, causing an invalid memory read. Not catching this error would + cause downstream errors that eventually resulted in a previously + allocated buffer to be unfreed when the library shut down. In builds + where the free lists are in use, this could result in an infinite loop + and SIGABRT when the library shuts down. + + We now track the buffer size and raise an error on attempts to read + past the end of it. + + (DER - 2021/08/12, HDFFV-11053) + + - Fixed CVE-2018-14460 The tool h5repack produced a segfault when the rank in dataspace @@ -1060,6 +1147,38 @@ Bug Fixes since HDF5-1.12.0 release Configuration ------------- + - Corrected pkg-config compile script + + It was discovered that the position of the "$@" argument for the command + in the compile script may fail on some platforms and configurations. The + position of the "$@"command argument was moved before the pkg-config sub command. + + (ADB - 2021/08/30) + + - Fixed CMake C++ compiler flags + + A recent refactoring of the C++ configure files accidently removed the + file that executed the enable_language command for C++ needed by the + HDFCXXCompilerFlags.cmake file. Also updated the intel warnings files, + including adding support for windows platforms. + + (ADB - 2021/08/10) + + - Better support for libaec (open-source Szip library) in CMake + + Implemented better support for libaec 1.0.5 (or later) library. This version + of libaec contains improvements for better integration with HDF5. Furthermore, + the variable USE_LIBAEC_STATIC has been introduced to allow to make use of + static version of libaec library. Use libaec_DIR or libaec_ROOT to set + the location in which libaec can be found. + + Be aware, the Szip library of libaec 1.0.4 depends on another library within + libaec library. This dependency is not specified in the current CMake + configuration which means that one can not use the static Szip library of + libaec 1.0.4 when building HDF5. This has been resolved in libaec 1.0.5. + + (JWSB - 2021/06/22) + - Refactor CMake configure for Fortran The Fortran configure tests for KINDs reused a single output file that was @@ -1421,6 +1540,10 @@ The following platforms are not supported but have been tested for this release. Known Problems ============== + Setting a variable-length dataset fill value will leak the memory allocated + for the p field of the hvl_t struct. A fix is in progress for this. + HDFFV-10840 + CMake files do not behave correctly with paths containing spaces. Do not use spaces in paths because the required escaping for handling spaces results in very complex and fragile build files. diff --git a/release_docs/USING_CMake_Examples.txt b/release_docs/USING_CMake_Examples.txt index bd089a6..a12a952 100644 --- a/release_docs/USING_CMake_Examples.txt +++ b/release_docs/USING_CMake_Examples.txt @@ -83,6 +83,7 @@ III. Defaults in the HDF5_Examples_options.cmake file #### HDF_BUILD_CXX:BOOL=OFF ### #### HDF_BUILD_FORTRAN:BOOL=OFF ### #### HDF_BUILD_JAVA:BOOL=OFF ### +#### HDF_BUILD_FILTERS:BOOL=OFF ### #### BUILD_TESTING:BOOL=OFF ### #### HDF_ENABLE_PARALLEL:BOOL=OFF ### #### HDF_ENABLE_THREADSAFE:BOOL=OFF ### diff --git a/release_docs/USING_HDF5_CMake.txt b/release_docs/USING_HDF5_CMake.txt index f2d7754..792c719 100644 --- a/release_docs/USING_HDF5_CMake.txt +++ b/release_docs/USING_HDF5_CMake.txt @@ -41,13 +41,30 @@ I. Preconditions 2. You have installed the HDF5 library built with CMake, by executing the HDF Install Utility (the *.msi file in the binary package for - Windows). If you are using a Windows platform, you can obtain a - pre-built Windows binary from The HDF Group's website at + Windows). You can obtain pre-built binaries from The HDF Group's website at www.hdfgroup.org. 3. Set the environment variable HDF5_DIR to the installed location of - the config files for HDF5. On Windows: + the config files for HDF5. + On Windows: HDF5_DIR=C:/Program Files/HDF_Group/HDF5/1.13.x/cmake + On unix: + HDF5_DIR=<install root folder>/HDF_Group/HDF5/1.13.x/cmake + + If you are using shared libraries, you may need to add to the path + environment variable. Set the path environment variable to the + installed location of the library files for HDF5. + On Windows (*.dll): + PATH=%PATH%;C:/Program Files/HDF_Group/HDF5/1.13.x/bin + On unix (*.so): + LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<install root folder>/HDF_Group/HDF5/1.13.x/lib + + If you are using filter plugin libraries, you will need to set the + HDF5_PLUGIN_PATH environment variable. + On Windows: + HDF5_PLUGIN_PATH=C:/Program Files/HDF_Group/HDF5/1.13.x/lib/plugin + On unix: + HDF5_PLUGIN_PATH=<install root folder>/HDF_Group/HDF5/1.13.x/lib/plugin (Note there are no quote characters used on Windows and all platforms use forward slashes) @@ -99,12 +116,13 @@ These steps are described in more detail below. * MinGW Makefiles * NMake Makefiles * Unix Makefiles - * Visual Studio 12 2013 - * Visual Studio 12 2013 Win64 * Visual Studio 14 2015 * Visual Studio 14 2015 Win64 * Visual Studio 15 2017 * Visual Studio 15 2017 Win64 + * Visual Studio 16 2019 + * ... in addition VS2019 will need to set the "-A" option, + * ... [Win32, x64, ARM, ARM64] <options> is: * BUILD_TESTING:BOOL=ON @@ -114,7 +132,7 @@ These steps are described in more detail below. 2.1 Visual CMake users, click the Configure button. If this is the first time you are running cmake-gui in this directory, you will be prompted for the - generator you wish to use (for example on Windows, Visual Studio 12 2013). + generator you wish to use (for example on Windows, Visual Studio 14 2015 Win64). CMake will read in the CMakeLists.txt files from the source directory and display options for the HDF5 project. After the first configure you can adjust the cache settings and/or specify locations of other programs. @@ -132,7 +150,7 @@ These steps are described in more detail below. 2.2 Alternative command line example on Windows in c:\MyHDFstuff\hdf5\build directory: - cmake -G "Visual Studio 12 2013" -DBUILD_TESTING:BOOL=ON .. + cmake -G "Visual Studio 14 2015 Win64" -DBUILD_TESTING:BOOL=ON .. 3. Build HDF5 Applications diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a055271..955a394 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -180,6 +180,7 @@ set (H5ES_SOURCES ${HDF5_SRC_DIR}/H5ESlist.c ) set (H5ES_HDRS + ${HDF5_SRC_DIR}/H5ESdevelop.h ${HDF5_SRC_DIR}/H5ESpublic.h ) IDE_GENERATED_PROPERTIES ("H5ES" "${H5ES_HDRS}" "${H5ES_SOURCES}" ) @@ -669,6 +670,7 @@ IDE_GENERATED_PROPERTIES ("H5UC" "${H5UC_HDRS}" "${H5UC_SOURCES}" ) set (H5VL_SOURCES ${HDF5_SRC_DIR}/H5VL.c ${HDF5_SRC_DIR}/H5VLcallback.c + ${HDF5_SRC_DIR}/H5VLdyn_ops.c ${HDF5_SRC_DIR}/H5VLint.c ${HDF5_SRC_DIR}/H5VLnative.c ${HDF5_SRC_DIR}/H5VLnative_attr.c @@ -682,6 +684,7 @@ set (H5VL_SOURCES ${HDF5_SRC_DIR}/H5VLnative_object.c ${HDF5_SRC_DIR}/H5VLnative_token.c ${HDF5_SRC_DIR}/H5VLpassthru.c + ${HDF5_SRC_DIR}/H5VLtest.c ) set (H5VL_HDRS ${HDF5_SRC_DIR}/H5VLconnector.h diff --git a/src/H5.c b/src/H5.c index 3454786..69c81ea 100644 --- a/src/H5.c +++ b/src/H5.c @@ -70,6 +70,10 @@ hbool_t H5_PKG_INIT_VAR = FALSE; /* Library Private Variables */ /*****************************/ +/* Library incompatible release versions */ +const unsigned VERS_RELEASE_EXCEPTIONS[] = {0}; +const unsigned VERS_RELEASE_EXCEPTIONS_SIZE = 0; + /* statically initialize block for pthread_once call used in initializing */ /* the first global mutex */ #ifdef H5_HAVE_THREADSAFE @@ -285,13 +289,13 @@ done: } /* end H5_init_library() */ /*------------------------------------------------------------------------- - * Function: H5_term_library + * Function: H5_term_library * - * Purpose: Terminate interfaces in a well-defined order due to - * dependencies among the interfaces, then terminate - * library-specific data. + * Purpose: Terminate interfaces in a well-defined order due to + * dependencies among the interfaces, then terminate + * library-specific data. * - * Return: void + * Return: void * *------------------------------------------------------------------------- */ @@ -509,22 +513,22 @@ done: } /* end H5_term_library() */ /*------------------------------------------------------------------------- - * Function: H5dont_atexit + * Function: H5dont_atexit * - * Purpose: Indicates that the library is not to clean up after itself - * when the application exits by calling exit() or returning - * from main(). This function must be called before any other - * HDF5 function or constant is used or it will have no effect. + * Purpose: Indicates that the library is not to clean up after itself + * when the application exits by calling exit() or returning + * from main(). This function must be called before any other + * HDF5 function or constant is used or it will have no effect. * - * If this function is used then certain memory buffers will not - * be de-allocated nor will open files be flushed automatically. - * The application may still call H5close() explicitly to - * accomplish these things. + * If this function is used then certain memory buffers will not + * be de-allocated nor will open files be flushed automatically. + * The application may still call H5close() explicitly to + * accomplish these things. * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative if this function is called more than - * once or if it is called too late. + * Failure: negative if this function is called more than + * once or if it is called too late. * *------------------------------------------------------------------------- */ @@ -545,19 +549,19 @@ H5dont_atexit(void) } /* end H5dont_atexit() */ /*------------------------------------------------------------------------- - * Function: H5garbage_collect + * Function: H5garbage_collect * - * Purpose: Walks through all the garbage collection routines for the - * library, which are supposed to free any unused memory they have - * allocated. + * Purpose: Walks through all the garbage collection routines for the + * library, which are supposed to free any unused memory they have + * allocated. * * These should probably be registered dynamically in a linked list of * functions to call, but there aren't that many right now, so we * hard-wire them... * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * *------------------------------------------------------------------------- */ @@ -578,9 +582,9 @@ done: } /* end H5garbage_collect() */ /*------------------------------------------------------------------------- - * Function: H5set_free_list_limits + * Function: H5set_free_list_limits * - * Purpose: Sets limits on the different kinds of free lists. Setting a value + * Purpose: Sets limits on the different kinds of free lists. Setting a value * of -1 for a limit means no limit of that type. These limits are global * for the entire library. Each "global" limit only applies to free lists * of that type, so if an application sets a limit of 1 MB on each of the @@ -598,9 +602,9 @@ done: * int blk_global_lim; IN: The limit on all "block" free list memory used * int blk_list_lim; IN: The limit on memory used in each "block" free list * - * Return: Success: non-negative + * Return: Success: non-negative * - * Failure: negative + * Failure: negative * *------------------------------------------------------------------------- */ @@ -624,11 +628,11 @@ done: } /* end H5set_free_list_limits() */ /*------------------------------------------------------------------------- - * Function: H5get_free_list_sizes + * Function: H5get_free_list_sizes * - * Purpose: Gets the current size of the different kinds of free lists that - * the library uses to manage memory. The free list sizes can be set with - * H5set_free_list_limits and garbage collected with H5garbage_collect. + * Purpose: Gets the current size of the different kinds of free lists that + * the library uses to manage memory. The free list sizes can be set with + * H5set_free_list_limits and garbage collected with H5garbage_collect. * These lists are global for the entire library. * * Parameters: @@ -637,8 +641,8 @@ done: * size_t *blk_size; OUT: The current size of all "block" free list memory used * size_t *fac_size; OUT: The current size of all "factory" free list memory used * - * Return: Success: non-negative - * Failure: negative + * Return: Success: non-negative + * Failure: negative * * Programmer: Quincey Koziol * Friday, March 6, 2020 @@ -663,23 +667,23 @@ done: } /* end H5get_free_list_sizes() */ /*------------------------------------------------------------------------- - * Function: H5get_alloc_stats + * Function: H5get_alloc_stats * - * Purpose: Gets the memory allocation statistics for the library, if the - * --enable-memory-alloc-sanity-check option was given when building the + * Purpose: Gets the memory allocation statistics for the library, if the + * --enable-memory-alloc-sanity-check option was given when building the * library. Applications can check whether this option was enabled by - * detecting if the 'H5_MEMORY_ALLOC_SANITY_CHECK' macro is defined. This - * option is enabled by default for debug builds of the library and - * disabled by default for non-debug builds. If the option is not enabled, - * all the values returned with be 0. These statistics are global for the - * entire library, but don't include allocations from chunked dataset I/O - * filters or non-native VOL connectors. + * detecting if the 'H5_MEMORY_ALLOC_SANITY_CHECK' macro is defined. This + * option is enabled by default for debug builds of the library and + * disabled by default for non-debug builds. If the option is not enabled, + * all the values returned with be 0. These statistics are global for the + * entire library, but don't include allocations from chunked dataset I/O + * filters or non-native VOL connectors. * * Parameters: * H5_alloc_stats_t *stats; OUT: Memory allocation statistics * - * Return: Success: non-negative - * Failure: negative + * Return: Success: non-negative + * Failure: negative * * Programmer: Quincey Koziol * Saturday, March 7, 2020 @@ -812,12 +816,12 @@ H5__debug_mask(const char *s) #ifdef H5_HAVE_PARALLEL /*------------------------------------------------------------------------- - * Function: H5__mpi_delete_cb + * Function: H5__mpi_delete_cb * - * Purpose: Callback attribute on MPI_COMM_SELF to terminate the HDF5 + * Purpose: Callback attribute on MPI_COMM_SELF to terminate the HDF5 * library when the communicator is destroyed, i.e. on MPI_Finalize. * - * Return: MPI_SUCCESS + * Return: MPI_SUCCESS * *------------------------------------------------------------------------- */ @@ -831,18 +835,18 @@ H5__mpi_delete_cb(MPI_Comm H5_ATTR_UNUSED comm, int H5_ATTR_UNUSED keyval, void #endif /*H5_HAVE_PARALLEL*/ /*------------------------------------------------------------------------- - * Function: H5get_libversion + * Function: H5get_libversion * - * Purpose: Returns the library version numbers through arguments. MAJNUM - * will be the major revision number of the library, MINNUM the - * minor revision number, and RELNUM the release revision number. + * Purpose: Returns the library version numbers through arguments. MAJNUM + * will be the major revision number of the library, MINNUM the + * minor revision number, and RELNUM the release revision number. * - * Note: When printing an HDF5 version number it should be printed as + * Note: When printing an HDF5 version number it should be printed as * - * printf("%u.%u.%u", maj, min, rel) or - * printf("version %u.%u release %u", maj, min, rel) + * printf("%u.%u.%u", maj, min, rel) or + * printf("version %u.%u release %u", maj, min, rel) * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -867,17 +871,20 @@ done: } /* end H5get_libversion() */ /*------------------------------------------------------------------------- - * Function: H5check_version + * Function: H5check_version * - * Purpose: Verifies that the arguments match the version numbers - * compiled into the library. This function is intended to be - * called from user to verify that the versions of header files - * compiled into the application match the version of the hdf5 - * library. + * Purpose: Verifies that the arguments match the version numbers + * compiled into the library. This function is intended to be + * called from user to verify that the versions of header files + * compiled into the application match the version of the hdf5 + * library. + * Within major.minor.release version, the expectation + * is that all release versions are compatible, exceptions to + * this rule must be added to the VERS_RELEASE_EXCEPTIONS list. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: abort() + * Failure: abort() * *------------------------------------------------------------------------- */ @@ -890,6 +897,15 @@ done: "linked with a different version of static or shared HDF5 library.\n" \ "You should recompile the application or check your shared library related\n" \ "settings such as 'LD_LIBRARY_PATH'.\n" +#define RELEASE_MISMATCH_WARNING \ + "Warning! ***HDF5 library release mismatched error***\n" \ + "The HDF5 header files used to compile this application are not compatible with\n" \ + "the version used by the HDF5 library to which this application is linked.\n" \ + "Data corruption or segmentation faults may occur if the application continues.\n" \ + "This can happen when an application was compiled by one version of HDF5 but\n" \ + "linked with an incompatible version of static or shared HDF5 library.\n" \ + "You should recompile the application or check your shared library related\n" \ + "settings such as 'LD_LIBRARY_PATH'.\n" herr_t H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) @@ -918,7 +934,11 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) disable_version_check = (unsigned int)HDstrtol(s, NULL, 0); } - if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE != relnum) { + /* H5_VERS_MAJOR and H5_VERS_MINOR must match */ + /* Cast relnum to int to avoid warning for unsigned < 0 comparison + * in first release versions */ + if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE > (int)relnum) { + switch (disable_version_check) { case 0: HDfprintf(stderr, "%s%s", version_mismatch_warning, @@ -953,7 +973,51 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) break; } /* end switch */ - } /* end if */ + } /* end if (H5_VERS_MAJOR != majnum || H5_VERS_MINOR != minnum || H5_VERS_RELEASE > relnum) */ + + /* H5_VERS_RELEASE should be compatible, we will only add checks for exceptions */ + if (H5_VERS_RELEASE != relnum) { + for (unsigned i = 0; i < VERS_RELEASE_EXCEPTIONS_SIZE; i++) { + /* Check for incompatible headers or incompatible library */ + if (VERS_RELEASE_EXCEPTIONS[i] == relnum || VERS_RELEASE_EXCEPTIONS[i] == H5_VERS_RELEASE) { + switch (disable_version_check) { + case 0: + HDfprintf( + stderr, "%s%s", version_mismatch_warning, + "You can, at your own risk, disable this warning by setting the environment\n" + "variable 'HDF5_DISABLE_VERSION_CHECK' to a value of '1'.\n" + "Setting it to 2 or higher will suppress the warning messages totally.\n"); + /* Mention the versions we are referring to */ + HDfprintf(stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n", majnum, minnum, + relnum, (unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR, + (unsigned)H5_VERS_RELEASE); + + /* Bail out now. */ + HDfputs("Bye...\n", stderr); + HDabort(); + case 1: + /* continue with a warning */ + /* Note that the warning message is embedded in the format string.*/ + HDfprintf(stderr, + "%s'HDF5_DISABLE_VERSION_CHECK' " + "environment variable is set to %d, application will\n" + "continue at your own risk.\n", + version_mismatch_warning, disable_version_check); + /* Mention the versions we are referring to */ + HDfprintf(stderr, "Headers are %u.%u.%u, library is %u.%u.%u\n", majnum, minnum, + relnum, (unsigned)H5_VERS_MAJOR, (unsigned)H5_VERS_MINOR, + (unsigned)H5_VERS_RELEASE); + break; + default: + /* 2 or higher: continue silently */ + break; + } /* end switch */ + + } /* end if */ + + } /* end for */ + + } /* end if (H5_VERS_RELEASE != relnum) */ /* Indicate that the version check has been performed */ checked = 1; @@ -964,12 +1028,9 @@ H5check_version(unsigned majnum, unsigned minnum, unsigned relnum) * Check only the first sizeof(lib_str) char. Assume the information * will fit within this size or enough significance. */ - HDsnprintf(lib_str, sizeof(lib_str), "HDF5 library version: %d.%d.%d", H5_VERS_MAJOR, H5_VERS_MINOR, - H5_VERS_RELEASE); - if (*substr) { - HDstrncat(lib_str, "-", (size_t)1); - HDstrncat(lib_str, substr, (sizeof(lib_str) - HDstrlen(lib_str)) - 1); - } /* end if */ + HDsnprintf(lib_str, sizeof(lib_str), "HDF5 library version: %d.%d.%d%s%s", H5_VERS_MAJOR, + H5_VERS_MINOR, H5_VERS_RELEASE, (*substr ? "-" : ""), substr); + if (HDstrcmp(lib_str, H5_lib_vers_info_g) != 0) { HDfputs("Warning! Library version information error.\n" "The HDF5 library version information are not " @@ -998,7 +1059,7 @@ done: * is failing inexplicably, then try calling this function * first. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -1017,12 +1078,12 @@ done: } /* end H5open() */ /*------------------------------------------------------------------------- - * Function: H5atclose + * Function: H5atclose * - * Purpose: Register a callback for the library to invoke when it's - * closing. Callbacks are invoked in LIFO order. + * Purpose: Register a callback for the library to invoke when it's + * closing. Callbacks are invoked in LIFO order. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -1056,11 +1117,11 @@ done: } /* end H5atclose() */ /*------------------------------------------------------------------------- - * Function: H5close + * Function: H5close * - * Purpose: Terminate the library and release all resources. + * Purpose: Terminate the library and release all resources. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ @@ -1081,9 +1142,9 @@ H5close(void) } /* end H5close() */ /*------------------------------------------------------------------------- - * Function: H5allocate_memory + * Function: H5allocate_memory * - * Purpose: Allocate a memory buffer with the semantics of malloc(). + * Purpose: Allocate a memory buffer with the semantics of malloc(). * * NOTE: This function is intended for use with filter * plugins so that all allocation and free operations @@ -1121,9 +1182,9 @@ H5allocate_memory(size_t size, hbool_t clear) } /* end H5allocate_memory() */ /*------------------------------------------------------------------------- - * Function: H5resize_memory + * Function: H5resize_memory * - * Purpose: Resize a memory buffer with the semantics of realloc(). + * Purpose: Resize a memory buffer with the semantics of realloc(). * * NOTE: This function is intended for use with filter * plugins so that all allocation and free operations @@ -1158,14 +1219,14 @@ H5resize_memory(void *mem, size_t size) } /* end H5resize_memory() */ /*------------------------------------------------------------------------- - * Function: H5free_memory + * Function: H5free_memory * - * Purpose: Frees memory allocated by the library that it is the user's + * Purpose: Frees memory allocated by the library that it is the user's * responsibility to free. Ensures that the same library * that was used to allocate the memory frees it. Passing * NULL pointers is allowed. * - * Return: SUCCEED/FAIL + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1182,12 +1243,12 @@ H5free_memory(void *mem) } /* end H5free_memory() */ /*------------------------------------------------------------------------- - * Function: H5is_library_threadsafe + * Function: H5is_library_threadsafe * - * Purpose: Checks to see if the library was built with thread-safety + * Purpose: Checks to see if the library was built with thread-safety * enabled. * - * Return: SUCCEED/FAIL + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ @@ -1213,16 +1274,16 @@ H5is_library_threadsafe(hbool_t *is_ts /*out*/) } /* end H5is_library_threadsafe() */ /*------------------------------------------------------------------------- - * Function: H5is_library_terminating + * Function: H5is_library_terminating * - * Purpose: Checks to see if the library is shutting down. + * Purpose: Checks to see if the library is shutting down. * - * Note: Useful for plugins to detect when the library is terminating. - * For example, a VOL connector could check if a "file close" - * callback was the result of the library shutdown process, or - * an API action from the application. + * Note: Useful for plugins to detect when the library is terminating. + * For example, a VOL connector could check if a "file close" + * callback was the result of the library shutdown process, or + * an API action from the application. * - * Return: SUCCEED/FAIL + * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ diff --git a/src/H5A.c b/src/H5A.c index 4c1f5f1..c986d1f 100644 --- a/src/H5A.c +++ b/src/H5A.c @@ -320,7 +320,7 @@ H5A__create_by_name_api_common(hid_t loc_id, const char *obj_name, const char *a /* obj_name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, obj_name, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Verify access property list and set up collective metadata if appropriate */ @@ -630,7 +630,7 @@ H5A__open_by_name_api_common(hid_t loc_id, const char *obj_name, const char *att /* obj_name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, obj_name, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Verify access property list and set up collective metadata if appropriate */ @@ -764,8 +764,8 @@ H5A__open_by_idx_api_common(hid_t loc_id, const char *obj_name, H5_index_t idx_t HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid iteration order specified") /* Set up object access arguments */ - if (H5VL_setup_idx_args(loc_id, obj_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, - &loc_params) < 0) + if (H5VL_setup_idx_args(loc_id, obj_name, idx_type, order, n, FALSE, lapl_id, vol_obj_ptr, &loc_params) < + 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Verify access property list and set up collective metadata if appropriate */ @@ -1057,7 +1057,7 @@ done: *--------------------------------------------------------------------------*/ herr_t H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, hid_t dtype_id, - void *buf, hid_t es_id) + void *buf /*out*/, hid_t es_id) { H5VL_object_t *vol_obj = NULL; /* Object for attr_id */ void * token = NULL; /* Request token for async operation */ @@ -1065,7 +1065,7 @@ H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE7("e", "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id); + H5TRACE7("e", "*s*sIuiixi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id); /* Set up request token pointer for asynchronous operation */ if (H5ES_NONE != es_id) @@ -1079,7 +1079,7 @@ H5Aread_async(const char *app_file, const char *app_func, unsigned app_line, hid if (NULL != token) /* clang-format off */ if (H5ES_insert(es_id, vol_obj->connector, token, - H5ARG_TRACE7(__func__, "*s*sIuii*xi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id)) < 0) + H5ARG_TRACE7(__func__, "*s*sIuiixi", app_file, app_func, app_line, attr_id, dtype_id, buf, es_id)) < 0) /* clang-format on */ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "can't insert token into event set") @@ -1106,8 +1106,9 @@ done: hid_t H5Aget_space(hid_t attr_id) { - H5VL_object_t *vol_obj = NULL; /* Attribute object for ID */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", attr_id); @@ -1116,11 +1117,17 @@ H5Aget_space(hid_t attr_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an attribute") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_SPACE; + vol_cb_args.args.get_space.space_id = H5I_INVALID_HID; + /* Get the dataspace */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < - 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace of attribute") + /* Set the return value */ + ret_value = vol_cb_args.args.get_space.space_id; + done: FUNC_LEAVE_API(ret_value) } /* H5Aget_space() */ @@ -1144,8 +1151,9 @@ done: hid_t H5Aget_type(hid_t attr_id) { - H5VL_object_t *vol_obj = NULL; /* Attribute object for ID */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", attr_id); @@ -1154,10 +1162,17 @@ H5Aget_type(hid_t attr_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an attribute") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_TYPE; + vol_cb_args.args.get_type.type_id = H5I_INVALID_HID; + /* Get the datatype */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype of attribute") + /* Set the return value */ + ret_value = vol_cb_args.args.get_type.type_id; + done: FUNC_LEAVE_API(ret_value) } /* H5Aget_type() */ @@ -1184,8 +1199,9 @@ done: hid_t H5Aget_create_plist(hid_t attr_id) { - H5VL_object_t *vol_obj = NULL; /* Attribute object for ID */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", attr_id); @@ -1196,11 +1212,18 @@ H5Aget_create_plist(hid_t attr_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an attribute") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_ACPL; + vol_cb_args.args.get_acpl.acpl_id = H5I_INVALID_HID; + /* Get the acpl */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_ACPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, H5I_INVALID_HID, "unable to get creation property list for attribute") + /* Set the return value */ + ret_value = vol_cb_args.args.get_acpl.acpl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Aget_create_plist() */ @@ -1229,9 +1252,10 @@ done: ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf /*out*/) { - H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t attr_name_len = 0; /* Length of attribute name */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "izx", attr_id, buf_size, buf); @@ -1242,15 +1266,21 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf /*out*/) if (!buf && buf_size) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "buf cannot be NULL if buf_size is non-zero") - /* Set location struct parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(attr_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_NAME; + vol_cb_args.args.get_name.loc_params.type = H5VL_OBJECT_BY_SELF; + vol_cb_args.args.get_name.loc_params.obj_type = H5I_get_type(attr_id); + vol_cb_args.args.get_name.buf_size = buf_size; + vol_cb_args.args.get_name.buf = buf; + vol_cb_args.args.get_name.attr_name_len = &attr_name_len; /* Get the attribute name */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - buf_size, buf, &ret_value) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, (-1), "unable to get attribute name") + /* Set the return value */ + ret_value = (ssize_t)attr_name_len; + done: FUNC_LEAVE_API(ret_value) } /* H5Aget_name() */ @@ -1276,9 +1306,10 @@ ssize_t H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - ssize_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t attr_name_len = 0; /* Length of attribute name */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("Zs", "i*sIiIohxzi", loc_id, obj_name, idx_type, order, n, name, size, lapl_id); @@ -1303,19 +1334,26 @@ H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_i if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - loc_params.type = H5VL_OBJECT_BY_IDX; - loc_params.loc_data.loc_by_idx.name = obj_name; - loc_params.loc_data.loc_by_idx.idx_type = idx_type; - loc_params.loc_data.loc_by_idx.order = order; - loc_params.loc_data.loc_by_idx.n = n; - loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_NAME; + vol_cb_args.args.get_name.loc_params.type = H5VL_OBJECT_BY_IDX; + vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.name = obj_name; + vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.idx_type = idx_type; + vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.order = order; + vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.n = n; + vol_cb_args.args.get_name.loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; + vol_cb_args.args.get_name.loc_params.obj_type = H5I_get_type(loc_id); + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = name; + vol_cb_args.args.get_name.attr_name_len = &attr_name_len; /* Get the name */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - size, name, &ret_value) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get name") + /* Set the return value */ + ret_value = (ssize_t)attr_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Aget_name_by_idx() */ @@ -1340,8 +1378,10 @@ done: hsize_t H5Aget_storage_size(hid_t attr_id) { - H5VL_object_t *vol_obj; - hsize_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hsize_t storage_size = 0; /* Storage size of attribute */ + hsize_t ret_value; /* Return value */ FUNC_ENTER_API(0) H5TRACE1("h", "i", attr_id); @@ -1350,10 +1390,16 @@ H5Aget_storage_size(hid_t attr_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(attr_id, H5I_ATTR))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an attribute") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_STORAGE_SIZE; + vol_cb_args.args.get_storage_size.data_size = &storage_size; + /* Get the storage size */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_STORAGE_SIZE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, 0, "unable to get acpl") + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, 0, "unable to get storage size") + + /* Set the return value */ + ret_value = storage_size; done: FUNC_LEAVE_API(ret_value) @@ -1375,9 +1421,9 @@ done: herr_t H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", attr_id, ainfo); @@ -1388,12 +1434,15 @@ H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/) if (!ainfo) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "attribute_info parameter cannot be NULL") - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(attr_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_INFO; + vol_cb_args.args.get_info.loc_params.type = H5VL_OBJECT_BY_SELF; + vol_cb_args.args.get_info.loc_params.obj_type = H5I_get_type(attr_id); + vol_cb_args.args.get_info.attr_name = NULL; + vol_cb_args.args.get_info.ainfo = ainfo; /* Get the attribute information */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - ainfo) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") done: @@ -1417,9 +1466,9 @@ herr_t H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H5A_info_t *ainfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*s*sxi", loc_id, obj_name, attr_name, ainfo, lapl_id); @@ -1438,18 +1487,21 @@ H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = obj_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_INFO; + vol_cb_args.args.get_info.loc_params.type = H5VL_OBJECT_BY_NAME; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_name.name = obj_name; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + vol_cb_args.args.get_info.loc_params.obj_type = H5I_get_type(loc_id); + vol_cb_args.args.get_info.attr_name = attr_name; + vol_cb_args.args.get_info.ainfo = ainfo; + /* Get the attribute information */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - ainfo, attr_name) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") done: @@ -1474,9 +1526,9 @@ herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5A_info_t *ainfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Attribute object for ID */ + H5VL_attr_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIohxi", loc_id, obj_name, idx_type, order, n, ainfo, lapl_id); @@ -1497,21 +1549,24 @@ H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_i if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") - loc_params.type = H5VL_OBJECT_BY_IDX; - loc_params.loc_data.loc_by_idx.name = obj_name; - loc_params.loc_data.loc_by_idx.idx_type = idx_type; - loc_params.loc_data.loc_by_idx.order = order; - loc_params.loc_data.loc_by_idx.n = n; - loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_GET_INFO; + vol_cb_args.args.get_info.loc_params.type = H5VL_OBJECT_BY_IDX; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.name = obj_name; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.idx_type = idx_type; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.order = order; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.n = n; + vol_cb_args.args.get_info.loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; + vol_cb_args.args.get_info.loc_params.obj_type = H5I_get_type(loc_id); + vol_cb_args.args.get_info.attr_name = NULL; + vol_cb_args.args.get_info.ainfo = ainfo; + /* Get the attribute information */ - if (H5VL_attr_get(vol_obj, H5VL_ATTR_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - ainfo) < 0) + if (H5VL_attr_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") done: @@ -1541,12 +1596,19 @@ H5A__rename_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const HDassert(new_name); /* Avoid thrashing things if the names are the same */ - if (HDstrcmp(old_name, new_name) != 0) + if (HDstrcmp(old_name, new_name) != 0) { + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_RENAME; + vol_cb_args.args.rename.old_name = old_name; + vol_cb_args.args.rename.new_name = new_name; + /* Rename the attribute */ - if (H5VL_attr_specific(vol_obj, loc_params, H5VL_ATTR_RENAME, H5P_DATASET_XFER_DEFAULT, token_ptr, - old_name, new_name) < 0) + if (H5VL_attr_specific(vol_obj, loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute from '%s' to '%s'", old_name, new_name) + } done: FUNC_LEAVE_NOAPI(ret_value) @@ -1700,7 +1762,7 @@ H5A__rename_by_name_api_common(hid_t loc_id, const char *obj_name, const char *o /* obj_name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, obj_name, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") /* Rename the attribute */ @@ -1830,14 +1892,15 @@ herr_t H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx /*in,out */, H5A_operator2_t op, void *op_data) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iIiIo*hAO*x", loc_id, idx_type, order, idx, op, op_data); - /* check arguments */ + /* Check arguments */ if (H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) @@ -1845,16 +1908,25 @@ H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *i if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") + /* Get the loc object */ + if (NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Set the location access parameters */ loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(loc_id); - /* get the loc object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_ITER; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx = idx; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; /* Iterate over attributes */ - if ((ret_value = H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, idx, op, op_data)) < 0) + if ((ret_value = H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes"); done: @@ -1908,9 +1980,10 @@ herr_t H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx /*in,out */, H5A_operator2_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object location */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIo*hAO*xi", loc_id, obj_name, idx_type, order, idx, op, op_data, lapl_id); @@ -1929,18 +2002,27 @@ H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_i if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") + /* get the loc object */ + if (NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Set the location access parameters */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.obj_type = H5I_get_type(loc_id); loc_params.loc_data.loc_by_name.name = obj_name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - /* get the loc object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_ITER; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx = idx; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; /* Iterate over attributes */ - if ((ret_value = H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, idx, op, op_data)) < 0) + if ((ret_value = H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HERROR(H5E_ATTR, H5E_BADITER, "attribute iteration failed"); done: @@ -1964,9 +2046,10 @@ done: herr_t H5Adelete(hid_t loc_id, const char *name) { - H5VL_object_t * vol_obj = NULL; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*s", loc_id, name); @@ -1983,17 +2066,20 @@ H5Adelete(hid_t loc_id, const char *name) if (H5CX_set_loc(loc_id) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set collective metadata read") - /* Fill in location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set the location access parameters */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_DELETE; + vol_cb_args.args.del.name = name; + /* Delete the attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_DELETE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - name) < 0) + if (H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") done: @@ -2019,9 +2105,10 @@ done: herr_t H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*s*si", loc_id, obj_name, attr_name, lapl_id); @@ -2038,19 +2125,22 @@ H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") - /* Fill in location struct fields */ + /* Get the object */ + if (NULL == (vol_obj = H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* Set the location access parameters */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.loc_data.loc_by_name.name = obj_name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object */ - if (NULL == (vol_obj = H5VL_vol_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_DELETE; + vol_cb_args.args.del.name = attr_name; /* Delete the attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_DELETE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - attr_name) < 0) + if (H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") done: @@ -2085,9 +2175,10 @@ herr_t H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id) { - H5VL_object_t * vol_obj; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "i*sIiIohi", loc_id, obj_name, idx_type, order, n, lapl_id); @@ -2106,21 +2197,24 @@ H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_ite if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set access property list info") - loc_params.type = H5VL_OBJECT_BY_IDX; - loc_params.loc_data.loc_by_idx.name = obj_name; - loc_params.loc_data.loc_by_idx.idx_type = idx_type; - loc_params.loc_data.loc_by_idx.order = order; - loc_params.loc_data.loc_by_idx.n = n; - loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; - loc_params.obj_type = H5I_get_type(loc_id); - /* get the object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set the location access parameters */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = obj_name; + loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_DELETE_BY_IDX; + vol_cb_args.args.delete_by_idx.idx_type = idx_type; + vol_cb_args.args.delete_by_idx.order = order; + vol_cb_args.args.delete_by_idx.n = n; + /* Delete the attribute */ - if (H5VL_attr_specific(vol_obj, &loc_params, H5VL_ATTR_DELETE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - NULL) < 0) + if (H5VL_attr_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") done: @@ -2233,7 +2327,8 @@ static herr_t H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const char *attr_name, hbool_t *attr_exists, void **token_ptr) { - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_attr_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -2245,9 +2340,13 @@ H5A__exists_common(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, const if (!attr_name || !*attr_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_ATTR_EXISTS; + vol_cb_args.args.exists.name = attr_name; + vol_cb_args.args.exists.exists = attr_exists; + /* Check if the attribute exists */ - if (H5VL_attr_specific(vol_obj, loc_params, H5VL_ATTR_EXISTS, H5P_DATASET_XFER_DEFAULT, token_ptr, - attr_name, attr_exists) < 0) + if (H5VL_attr_specific(vol_obj, loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") done: @@ -2400,7 +2499,7 @@ H5A__exists_by_name_api_common(hid_t loc_id, const char *obj_name, const char *a /* obj_name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, obj_name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, obj_name, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "can't set object access arguments") /* Check if the attribute exists */ diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 188f9ee..a4e6d60 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -275,24 +275,24 @@ typedef struct H5AC_proxy_entry_t { /* size_t min_size = */ ( 1 * 1024 * 1024), \ /* long int epoch_length = */ 50000, \ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, \ - /* double lower_hr_threshold = */ 0.9f, \ - /* double increment = */ 2.0f, \ + /* double lower_hr_threshold = */ 0.9, \ + /* double increment = */ 2.0, \ /* hbool_t apply_max_increment = */ TRUE, \ /* size_t max_increment = */ (4 * 1024 * 1024), \ /* enum H5C_cache_flash_incr_mode */ \ /* flash_incr_mode = */ H5C_flash_incr__add_space, \ - /* double flash_multiple = */ 1.4f, \ - /* double flash_threshold = */ 0.25f, \ + /* double flash_multiple = */ 1.4, \ + /* double flash_threshold = */ 0.25, \ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,\ - /* double upper_hr_threshold = */ 0.999f, \ - /* double decrement = */ 0.9f, \ + /* double upper_hr_threshold = */ 0.999, \ + /* double decrement = */ 0.9, \ /* hbool_t apply_max_decrement = */ TRUE, \ /* size_t max_decrement = */ (1 * 1024 * 1024), \ /* int epochs_before_eviction = */ 3, \ /* hbool_t apply_empty_reserve = */ TRUE, \ - /* double empty_reserve = */ 0.1f, \ + /* double empty_reserve = */ 0.1, \ /* size_t dirty_bytes_threshold = */ (256 * 1024), \ - /* int metadata_write_strategy = */ \ + /* int metadata_write_strategy = */ \ H5AC__DEFAULT_METADATA_WRITE_STRATEGY \ } #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5Adeprec.c b/src/H5Adeprec.c index 3d4e391..8ae4e41 100644 --- a/src/H5Adeprec.c +++ b/src/H5Adeprec.c @@ -309,10 +309,11 @@ done: int H5Aget_num_attrs(hid_t loc_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_info2_t oinfo; - int ret_value = -1; + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5O_info2_t oinfo; + int ret_value = -1; FUNC_ENTER_API((-1)) H5TRACE1("Is", "i", loc_id); @@ -324,9 +325,13 @@ H5Aget_num_attrs(hid_t loc_id) if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = &oinfo; + vol_cb_args.args.get_info.fields = H5O_INFO_NUM_ATTRS; + /* Get the number of attributes for the object */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &oinfo, H5O_INFO_NUM_ATTRS) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, (-1), "unable to get attribute count for object") H5_CHECKED_ASSIGN(ret_value, int, oinfo.num_attrs, hsize_t); @@ -375,8 +380,10 @@ done: herr_t H5Aiterate1(hid_t loc_id, unsigned *attr_num /*in,out*/, H5A_operator1_t op, void *op_data) { - H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_attr_optional_args_t attr_opt_args; /* Arguments for optional operation */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(H5_ITER_ERROR) H5TRACE4("e", "i*IuAo*x", loc_id, attr_num, op, op_data); @@ -389,9 +396,17 @@ H5Aiterate1(hid_t loc_id, unsigned *attr_num /*in,out*/, H5A_operator1_t op, voi if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, H5_ITER_ERROR, "invalid location identifier") + /* Set up VOL callback arguments */ + attr_opt_args.iterate_old.loc_id = loc_id; + attr_opt_args.iterate_old.attr_num = attr_num; + attr_opt_args.iterate_old.op = op; + attr_opt_args.iterate_old.op_data = op_data; + vol_cb_args.op_type = H5VL_NATIVE_ATTR_ITERATE_OLD; + vol_cb_args.args = &attr_opt_args; + /* Call attribute iteration routine */ - if ((ret_value = H5VL_attr_optional(vol_obj, H5VL_NATIVE_ATTR_ITERATE_OLD, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, loc_id, attr_num, op, op_data)) < 0) + if ((ret_value = H5VL_attr_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < + 0) HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes"); done: diff --git a/src/H5Aint.c b/src/H5Aint.c index 8ec5463..300d686 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -844,7 +844,6 @@ done: const void *buf; IN: Buffer of data to write RETURNS Non-negative on success/Negative on failure - DESCRIPTION This function writes a complete attribute to disk. --------------------------------------------------------------------------*/ @@ -949,31 +948,33 @@ done: NAME H5A__get_name PURPOSE - Private function for H5Aget_name. Gets a copy of the name for an - attribute + Gets a copy of the name for an attribute RETURNS - This function returns the length of the attribute's name (which may be - longer than 'buf_size') on success or negative for failure. + Non-negative on success/Negative on failure DESCRIPTION This function retrieves the name of an attribute for an attribute ID. Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string terminator. If the name of the attribute is longer than 'buf_size'-1, the string terminator is stored in the last position of the buffer to properly terminate the string. + This function returns the length of the attribute's name (which may be + longer than 'buf_size') in the 'attr_name_len' parameter. --------------------------------------------------------------------------*/ -ssize_t -H5A__get_name(H5A_t *attr, size_t buf_size, char *buf) +herr_t +H5A__get_name(H5A_t *attr, size_t buf_size, char *buf, size_t *attr_name_len) { - size_t copy_len, nbytes; - ssize_t ret_value = -1; /* Return value */ + size_t copy_len, nbytes; FUNC_ENTER_PACKAGE_NOERR - /* get the real attribute length */ + /* Sanity checks */ + HDassert(attr); + HDassert(attr_name_len); + + /* Get the real attribute length */ nbytes = HDstrlen(attr->shared->name); - HDassert((ssize_t)nbytes >= 0); /*overflow, pretty unlikely --rpm*/ - /* compute the string length which will fit into the user's buffer */ + /* Compute the string length which will fit into the user's buffer */ copy_len = MIN(buf_size - 1, nbytes); /* Copy all/some of the name */ @@ -984,10 +985,10 @@ H5A__get_name(H5A_t *attr, size_t buf_size, char *buf) buf[copy_len] = '\0'; } /* end if */ - /* Set return value */ - ret_value = (ssize_t)nbytes; + /* Set actual attribute name length */ + *attr_name_len = nbytes; - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* H5A__get_name() */ /*------------------------------------------------------------------------- @@ -1091,13 +1092,10 @@ done: NAME H5A__get_create_plist PURPOSE - private version of H5Aget_create_plist + Private version of H5Aget_create_plist RETURNS This function returns the ID of a copy of the attribute's creation property list, or negative on failure. - - ERRORS - DESCRIPTION This function returns a copy of the creation property list for an attribute. The resulting ID must be closed with H5Pclose() or @@ -1304,7 +1302,7 @@ H5A__close_cb(H5VL_object_t *attr_vol_obj, void **request) HDassert(attr_vol_obj); /* Close the attribute */ - if ((ret_value = H5VL_attr_close(attr_vol_obj, H5P_DATASET_XFER_DEFAULT, request)) < 0) + if (H5VL_attr_close(attr_vol_obj, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "problem closing attribute") /* Free the VOL object */ @@ -2768,7 +2766,7 @@ H5A__iterate(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, H5 /* Call internal attribute iteration routine */ if ((ret_value = H5A__iterate_common(obj_loc_id, idx_type, order, idx, &attr_op, op_data)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error iterating over attributes") + HERROR(H5E_ATTR, H5E_BADITER, "error iterating over attributes"); done: /* Release resources */ diff --git a/src/H5Amodule.h b/src/H5Amodule.h index c89c93f..9f86ddd 100644 --- a/src/H5Amodule.h +++ b/src/H5Amodule.h @@ -33,33 +33,29 @@ * * Use the functions in this module to manage HDF5 attributes. * - * The Attribute Interface, H5A, provides a mechanism for attaching additional - * information to a dataset, group, or named datatype. - * - * Attributes are accessed by opening the object that they are attached to and - * are not independent objects. Typically an attribute is small in size and - * contains user metadata about the object that it is attached to. - * - * Attributes look similar to HDF5 datasets in that they have a datatype and - * dataspace. However, they do not support partial I/O operations and cannot be - * compressed or extended. + * Like HDF5 datasets, HDF5 attributes are array variables which have an element + * datatype and a shape (dataspace). However, they perform a different function: + * Attributes decorate other HDF5 objects, and are typically used to + * represent application metadata. Unlike datasets, the HDF5 library does not + * support partial I/O operations for attributes and they cannot be compressed + * or extended. * * <table> * <tr><th>Create</th><th>Read</th></tr> * <tr valign="top"> * <td> - * \snippet H5A_examples.c create + * \snippet{lineno} H5A_examples.c create * </td> * <td> - * \snippet H5A_examples.c read + * \snippet{lineno} H5A_examples.c read * </td> * <tr><th>Update</th><th>Delete</th></tr> * <tr valign="top"> * <td> - * \snippet H5A_examples.c update + * \snippet{lineno} H5A_examples.c update * </td> * <td> - * \snippet H5A_examples.c delete + * \snippet{lineno} H5A_examples.c delete * </td> * </tr> * </table> diff --git a/src/H5Apkg.h b/src/H5Apkg.h index a349f9f..b50cbc4 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -200,14 +200,14 @@ H5_DLL herr_t H5A__iterate(const H5G_loc_t *loc, const char *obj_name, H5_index_ #ifndef H5_NO_DEPRECATED_SYMBOLS H5_DLL herr_t H5A__iterate_old(hid_t loc_id, unsigned *attr_num, H5A_operator1_t op, void *op_data); #endif /* H5_NO_DEPRECATED_SYMBOLS */ -H5_DLL herr_t H5A__delete_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name); -H5_DLL herr_t H5A__delete_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, - hbool_t *attr_exists); -H5_DLL herr_t H5A__write(H5A_t *attr, const H5T_t *mem_type, const void *buf); -H5_DLL herr_t H5A__read(const H5A_t *attr, const H5T_t *mem_type, void *buf); -H5_DLL ssize_t H5A__get_name(H5A_t *attr, size_t buf_size, char *buf); +H5_DLL herr_t H5A__delete_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name); +H5_DLL herr_t H5A__delete_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5A__exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, + hbool_t *attr_exists); +H5_DLL herr_t H5A__write(H5A_t *attr, const H5T_t *mem_type, const void *buf); +H5_DLL herr_t H5A__read(const H5A_t *attr, const H5T_t *mem_type, void *buf); +H5_DLL herr_t H5A__get_name(H5A_t *attr, size_t buf_size, char *buf, size_t *attr_name_len); /* Attribute "dense" storage routines */ H5_DLL herr_t H5A__dense_create(H5F_t *f, H5O_ainfo_t *ainfo); diff --git a/src/H5Apublic.h b/src/H5Apublic.h index b3da77f..b78ae05 100644 --- a/src/H5Apublic.h +++ b/src/H5Apublic.h @@ -78,11 +78,11 @@ extern "C" { * * \return \herr_t * - * \details H5Aclose() terminates access to the attribute specified by - * \p attr_id by releasing the identifier. + * \details H5Aclose() terminates access to the attribute through + * \p attr_id and releases the identifier. * - * \attention Further use of a released attribute identifier is illegal; a - * function using such an identifier will generate an error. + * \par Example + * \snippet H5A_examples.c create * * \since 1.0.0 * @@ -117,27 +117,19 @@ H5_DLL herr_t H5Aclose_async(const char *app_file, const char *app_func, unsigne * The attribute name, \p attr_name, must be unique for the object. * * The attribute is created with the specified datatype and dataspace, - * \p type_id and \p space_id, which are created with the H5T and - * H5S interfaces, respectively. + * \p type_id and \p space_id. * - * If \p type_id is either a fixed-length or variable-length string, - * it is important to set the string length when defining the - * datatype. String datatypes are derived from #H5T_C_S1 (or - * #H5T_FORTRAN_S1 for Fortran), which defaults to 1 character in - * size. See H5Tset_size() and Creating variable-length string - * datatypes. - * - * The access property list is currently unused, but will be used in - * the future. This property list should currently be #H5P_DEFAULT. + * \plist_unused{acpl} * * The attribute identifier returned by this function must be released * with H5Aclose() resource leaks will develop. * - * \note The \p aapl parameter is currently not used; specify #H5P_DEFAULT. - * * \note If \p loc_id is a file identifier, the attribute will be attached * that file’s root group. * + * \par Example + * \snippet H5A_examples.c create + * * \since 1.8.0 * * \see H5Aclose() @@ -175,28 +167,19 @@ H5_DLL hid_t H5Acreate_async(const char *app_file, const char *app_func, unsigne * attached to the object specified by \p loc_id and \p obj_name. * * \p loc_id is a location identifier; \p obj_name is the object - * name relative to \p loc_id. If \p loc_id fully specifies the - * object to which the attribute is to be attached, \p obj_name - * should be '.' (a dot). + * name relative to \p loc_id. * * The attribute name, \p attr_name, must be unique for the object. * * The attribute is created with the specified datatype and - * dataspace, \p type_id and \p space_id, which are created with - * the H5T and H5S interfaces respectively. + * dataspace, \p type_id and \p space_id. * - * The attribute creation and access property lists are currently - * unused, but will be used in the future for optional attribute - * creation and access properties. These property lists should - * currently be #H5P_DEFAULT. + * \plist_unused{aapl} * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access * the object, \p obj_name. * - * The attribute identifier returned by this function must be - * released with H5close() or resource leaks will develop. - * * \since 1.8.0 * */ @@ -224,10 +207,14 @@ H5_DLL hid_t H5Acreate_by_name_async(const char *app_file, const char *app_func, * * \details H5Adelete() removes the attribute specified by its name, * \p attr_name, from a file, dataset, group, or named datatype. - * This function should not be used when attribute identifiers - * are open on \p loc_id as it may cause the internal indexes of - * the attributes to change and future writes to the open - * attributes to produce incorrect results. + * + * \attention This function should not be used when other attribute identifiers + * are open on \p loc_id. This may cause the internal indexes of + * the attributes to change and future writes to the open + * attributes to produce incorrect results. + * + * \par Example + * \snippet H5A_examples.c delete * * \since 1.0.0 * @@ -254,27 +241,16 @@ H5_DLL herr_t H5Adelete(hid_t loc_id, const char *attr_name); * * The object from which the attribute is to be removed is * specified by a location identifier and name, \p loc_id and - * \p obj_name, respectively. If \p loc_id fully specifies the - * object from which the attribute is to be removed, \p obj_name - * should be '.' (a dot). + * \p obj_name, respectively. * * The attribute to be removed is specified by a position in an - * index, \p n. The type of index is specified by \p idx_type and - * may be #H5_INDEX_NAME, for an alpha-numeric index by name, or - * #H5_INDEX_CRT_ORDER, for an index by creation order. The order - * in which the index is to be traversed is specified by \p order - * and may be #H5_ITER_INC (increment) for top-down iteration, - * #H5_ITER_DEC (decrement) for bottom-up iteration, or - * #H5_ITER_NATIVE, in which case HDF5 will iterate in the - * fastest-available order. For example, if \p idx_type, \p order, + * index, \p n. The type of index is specified by \p idx_type. + * The order in which the index is to be traversed is specified by + * \p order. For example, if \p idx_type, \p order, * and \p n are set to #H5_INDEX_NAME, #H5_ITER_INC, and 5, - * respectively, the fifth attribute by alpha-numeric order of + * respectively, the fifth attribute in lexicographic order of * attribute names will be removed. * - * For a discussion of \p idx_type and \p order, the valid values - * of those parameters, and the use of \p n, see the description - * of H5Aiterate2(). - * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access * the object, \p obj_name. @@ -302,9 +278,6 @@ H5_DLL herr_t H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t id * from an object specified by location and name, \p loc_id and * \p obj_name, respectively. * - * If \p loc_id fully specifies the object from which the - * attribute is to be removed, \p obj_name should be '.' (a dot). - * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to * access the object, \p obj_name. @@ -360,9 +333,7 @@ H5_DLL herr_t H5Aexists_async(const char *app_file, const char *app_func, unsign * \p loc_id specifies a location in the file containing the object. * \p obj_name is the name of the object to which the attribute is * attached and can be a relative name, relative to \p loc_id, - * or an absolute name, based in the root group of the file. If - * \p loc_id fully specifies the object, \p obj_name should be '.' - * (a dot). + * or an absolute name, based in the root group of the file. * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access @@ -394,9 +365,6 @@ H5_DLL herr_t H5Aexists_by_name_async(const char *app_file, const char *app_func * creation property list associated with the attribute specified * by \p attr_id. * - * The creation property list identifier should be released with - * H5Pclose(). - * * \since 1.8.0 * */ @@ -413,32 +381,9 @@ H5_DLL hid_t H5Aget_create_plist(hid_t attr_id); * \return \herr_t * * \details H5Aget_info() retrieves attribute information, locating the - * attribute with an attribute identifier, \p attr_id, which is - * the identifier returned by H5Aopen() or H5Aopen_by_idx(). The + * attribute with an attribute identifier, \p attr_id. The * attribute information is returned in the \p ainfo struct. * - * The \p ainfo struct is defined as follows: - * \snippet this H5A_info_t_snip - * - * \p corder_valid indicates whether the creation order data is - * valid for this attribute. Note that if creation order is not - * being tracked, no creation order data will be valid. Valid - * values are \c TRUE and \c FALSE. - * - * \p corder is a positive integer containing the creation - * order of the attribute. This value is 0-based, so, for - * example, the third attribute created will have a \p corder - * value of 2. - * - * \p cset indicates the character set used for the attribute’s - * name; valid values are defined in H5Tpublic.h and include - * the following: - * \csets - * This value is set with H5Pset_char_encoding(). - * - * \p data_size indicates the size, in the number of characters, - * of the attribute. - * * \since 1.8.0 * */ @@ -466,16 +411,9 @@ H5_DLL herr_t H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/); * The attribute is located by its index position and the attribute * information is returned in the \p ainfo struct. * - * If \p loc_id fully specifies the object to which the attribute - * is attached, \p obj_name should be '.' (a dot). - * * The attribute is located by means of an index type, an index * traversal order, and a position in the index, \p idx_type, - * \p order and \p n, respectively. These parameters and their - * valid values are discussed in the description of H5Aiterate2(). - * - * The \p ainfo struct, which will contain the returned attribute - * information, is described in H5Aget_info(). + * \p order and \p n, respectively. * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access @@ -493,8 +431,7 @@ H5_DLL herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t * \brief Retrieves attribute information, by attribute name * * \fgdt_loc_id - * - * \param[in] obj_name Name of object to which attribute is attached, + * \param[in] obj_name Name of the object to which an attribute is attached, * relative to location * \param[in] attr_name Attribute name * \param[out] ainfo Struct containing returned attribute information @@ -507,11 +444,6 @@ H5_DLL herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t * location and name, \p loc_id and \p obj_name, respectively. * The attribute information is returned in the \p ainfo struct. * - * If \p loc_id fully specifies the object to which the attribute - * is attached, \p obj_name should be '.' (a dot). - * - * The \p ainfo struct is described in H5Aget_info(). - * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to * access the object, \p obj_name. @@ -542,8 +474,8 @@ H5_DLL herr_t H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char * string terminator is stored in the last position of the buffer * to properly terminate the string. * - * If the user only wants to find out the size of this name, the - * values 0 and NULL can be passed in for the parameters + * If the user only wants to retrieve the name length, the + * values 0 and NULL should be passed for the parameters * \p bufsize and \p buf. * * \since 1.0.0 @@ -554,7 +486,7 @@ H5_DLL ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf); /** * \ingroup H5A * - * \brief Gets an attribute name, by attribute index position + * \brief Gets an attribute name by attribute index position * * \fgdt_loc_id * \param[in] obj_name Name of object to which attribute is attached, @@ -575,13 +507,9 @@ H5_DLL ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf); * located by its index position, the size of the name is specified * in \p size, and the attribute name is returned in \p name. * - * If \p loc_id fully specifies the object to which the attribute - * is attached, \p obj_name should be '.' (a dot). - * * The attribute is located by means of an index type, an index * traversal order, and a position in the index, \p idx_type, - * \p order and \p n, respectively. These parameters and their - * valid values are discussed in the description of H5Aiterate2(). + * \p order and \p n, respectively. * * If the attribute name’s size is unknown, the values 0 and NULL * can be passed in for the parameters \p size and \p name. The @@ -621,7 +549,7 @@ H5_DLL hid_t H5Aget_space(hid_t attr_id); /** * \ingroup H5A * - * \brief Returns the amount of storage required for an attribute + * \brief Returns the amount of storage used to store an attribute * * \attr_id * @@ -639,17 +567,16 @@ H5_DLL hsize_t H5Aget_storage_size(hid_t attr_id); /** * \ingroup H5A * - * \brief Gets an attribute datatype + * \brief Gets an attribute's datatype * * \attr_id * * \return \hid_t{datatype} * - * \details H5Aget_type() retrieves a copy of the datatype for an attribute. + * \details H5Aget_type() retrieves a copy of the attribute's datatype. * The datatype is reopened if it is a named type before returning * it to the application. The datatypes returned by this function - * are always read-only. If an error occurs when atomizing the - * return datatype, then the datatype is closed. + * are always read-only. * * The datatype identifier returned from this function must be * released with H5Tclose() or resource leaks will develop. @@ -662,7 +589,7 @@ H5_DLL hid_t H5Aget_type(hid_t attr_id); /** * \ingroup H5A * - * \brief Calls user-defined function for each attribute on an object + * \brief Calls a user-defined function for each attribute on an object * * \fgdt_loc_id * \param[in] idx_type Type of index @@ -689,17 +616,6 @@ H5_DLL hid_t H5Aget_type(hid_t attr_id); * are specified by three parameters: the index type, * \p idx_type; the order in which the index is to be traversed, * \p order; and the attribute’s position in the index, \p idx. - * - * The type of index specified by \p idx_type can be one of the - * following: - * - * \indexes - * - * The order in which the index is to be traversed, as specified - * by \p order, can be one of the following: - * - * \orders - * * The next attribute to be operated on is specified by \p idx, * a position in the index. * @@ -716,11 +632,6 @@ H5_DLL hid_t H5Aget_type(hid_t attr_id); * the value returned identifies the parameter to be operated on * in the next step of the iteration. * - * \p op is a user-defined function whose prototype is defined - * as follows: - * \snippet this H5A_operator2_t_snip - * \click4more - * * \note This function is also available through the H5Aiterate() macro. * * \since 1.8.0 @@ -756,24 +667,10 @@ H5_DLL herr_t H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t ord * additional information as defined below, is passed to a * user-defined function, \p op, which operates on that attribute. * - * If \p loc_id fully specifies the object to which these - * attributes are attached, \p obj_name should be '.' (a dot). - * * The order of the iteration and the attributes iterated over * are specified by three parameters: the index type, \p idx_type; * the order in which the index is to be traversed, \p order; * and the attribute’s position in the index, \p idx. - * - * The type of index specified by \p idx_type can be one of the - * following: - * - * \indexes - * - * The order in which the index is to be traversed, as specified - * by \p order, can be one of the following: - * - * \orders - * * The next attribute to be operated on is specified by \p idx, * a position in the index. * @@ -790,25 +687,6 @@ H5_DLL herr_t H5Aiterate2(hid_t loc_id, H5_index_t idx_type, H5_iter_order_t ord * the value returned identifies the parameter to be operated on in * the next step of the iteration. * - * \p op is a user-defined function whose prototype is defined - * as follows: - * \snippet this H5A_operator2_t_snip - * \click4more - * - * Valid return values from an operator and the resulting - * H5Aiterate_by_name() and \p op behavior are as follows: - * - * \li Zero causes the iterator to continue, returning zero when - * all attributes have been processed. - * \li A positive value causes the iterator to immediately return - * that positive value, indicating short-circuit success. - * The iterator can be restarted at the next attribute, as - * indicated by the return value of \p idx. - * \li A negative value causes the iterator to immediately return - * that value, indicating failure. The iterator can be - * restarted at the next attribute, as indicated by the return - * value of \p idx. - * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access * the object, \p obj_name. @@ -835,8 +713,7 @@ H5_DLL herr_t H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t * \details H5Aopen() opens an existing attribute, \p attr_name, that is * attached to object specified by an object identifier, \p obj_id. * - * The attribute access property list, \p aapl_id, is currently unused - * and should be #H5P_DEFAULT. + * \plist_unused{aapl_id} * * This function, H5Aopen_by_idx() or H5Aopen_by_name() must be called * before the attribute can be accessed for any further purpose, @@ -845,6 +722,9 @@ H5_DLL herr_t H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t * The attribute identifier returned by this function must be released * with H5Aclose() or resource leaks will develop. * + * \par Example + * \snippet H5A_examples.c read + * * \since 1.8.0 * * \see H5Aclose(), H5Acreate() @@ -876,17 +756,13 @@ H5_DLL hid_t H5Aopen_async(const char *app_file, const char *app_func, unsigned * * \details H5Aopen_by_idx() opens an existing attribute that is attached * to an object specified by location and name, \p loc_id and - * \p obj_name, respectively. If \p loc_id fully specifies the - * object to which the attribute is attached, \p obj_name, should - * be '.' (a dot). + * \p obj_name, respectively. * * The attribute is identified by an index type, an index traversal * order, and a position in the index, \p idx_type, \p order and - * \p n, respectively. These parameters and their valid values are - * discussed in the description of H5Aiterate2(). + * \p n, respectively. * - * The attribute access property list, \p aapl_id, is currently - * unused and should currently be #H5P_DEFAULT. + * \plist_unused{aapl_id} * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access @@ -933,11 +809,9 @@ H5_DLL hid_t H5Aopen_by_idx_async(const char *app_file, const char *app_func, un * * \p loc_id specifies a location from which the target object can * be located and \p obj_name is an object name relative to - * \p loc_id. If \p loc_id fully specifies the object to which the - * attribute is attached, \p obj_name should be '.' (a dot). + * \p loc_id. * - * The attribute access property list, \p aapl_id, is currently - * unused and should currently be #H5P_DEFAULT. + * \plist_unused{aapl_id} * * The link access property list, \p lapl_id, may provide * information regarding the properties of links required to access @@ -982,6 +856,9 @@ H5_DLL hid_t H5Aopen_by_name_async(const char *app_file, const char *app_func, u * Datatype conversion takes place at the time of a read or write and * is automatic. * + * \par Example + * \snippet H5A_examples.c read + * * \version 1.8.8 Fortran updated to Fortran2003. * \version 1.4.2 The \p dims parameter was added to the Fortran API in this * release. @@ -1051,15 +928,12 @@ H5_DLL herr_t H5Arename_by_name_async(const char *app_file, const char *app_func * attribute's in-memory datatype is specified with \p type_id. * The entire attribute is written from \p buf to the file. * - * If \p type_id is either a fixed-length or variable-length string, - * it is important to set the string length when defining the datatype. - * String datatypes are derived from #H5T_C_S1 (or #H5T_FORTRAN_S1 for - * Fortran codes), which defaults to 1 character in size. - * See H5Tset_size() and Creating variable-length string datatypes. - * * Datatype conversion takes place at the time of a read or write and * is automatic. * + * \par Example + * \snippet H5A_examples.c update + * * \version 1.8.8 Fortran updated to Fortran2003. * \version 1.4.2 Fortran \p dims parameter added in this release * \since 1.0.0 @@ -1100,6 +974,7 @@ H5_DLL herr_t H5Awrite_async(const char *app_file, const char *app_func, unsigne H5_DLL herr_t H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name, const char *new_attr_name, hid_t lapl_id); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -1133,6 +1008,7 @@ H5_DLL herr_t H5Arename_by_name(hid_t loc_id, const char *obj_name, const char * #define H5Aexists_by_name_async_wrap H5_NO_EXPAND(H5Aexists_by_name_async) #define H5Aclose_async_wrap H5_NO_EXPAND(H5Aclose_async) #endif /* H5A_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * @@ -1182,9 +1058,9 @@ typedef herr_t (*H5A_operator1_t)(hid_t location_id /*in*/, const char *attr_nam * * \return \hid_tv{attribute} * - * \note The \p acpl parameters is currently not used; specify #H5P_DEFAULT. + * \deprecation_note{H5Acreate2()} * - * \deprecated Deprecated in favor of H5Acreate2() + * \plist_unused{acpl} * * \details H5Acreate1() creates an attribute, \p name, which is attached * to the object specified by the identifier \p loc_id. @@ -1192,18 +1068,7 @@ typedef herr_t (*H5A_operator1_t)(hid_t location_id /*in*/, const char *attr_nam * The attribute name, \p name, must be unique for the object. * * The attribute is created with the specified datatype and dataspace, - * \p type_id and \p space_id, which are created with the H5T and - * H5S interfaces, respectively. - * - * If \p type_id is either a fixed-length or variable-length string, - * it is important to set the string length when defining the - * datatype. String datatypes are derived from #H5T_C_S1 (or - * #H5T_FORTRAN_S1 for Fortran), which defaults to 1 character in - * size. See H5Tset_size() and Creating variable-length string - * datatypes. - * - * The attribute identifier returned by this function must be released - * with H5Aclose() resource leaks will develop. + * \p type_id and \p space_id. * * \since 1.8.0 * @@ -1225,8 +1090,7 @@ H5_DLL hid_t H5Acreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t spa * \return Returns the number of attributes if successful; otherwise returns * a negative value. * - * \deprecated This function is deprecated in favor of the functions - * H5Oget_info(), H5Oget_info_by_name(), and H5Oget_info_by_idx(). + * \deprecation_note{H5Oget_info(), H5Oget_info_by_name(), and H5Oget_info_by_idx()} * * \details H5Aget_num_attrs() returns the number of attributes attached to * the object specified by its identifier, \p loc_id. @@ -1249,8 +1113,7 @@ H5_DLL int H5Aget_num_attrs(hid_t loc_id); * * \return \herr_t * - * \deprecated This function is deprecated in favor of the function - * H5Aiterate2(). + * \deprecation_note{H5Aiterate2()} * * \details H5Aiterate1() iterates over the attributes of the object * specified by its identifier, \p loc_id. The object can be a @@ -1262,10 +1125,6 @@ H5_DLL int H5Aget_num_attrs(hid_t loc_id); * \p op, is returned in \p idx. If \p idx is the null pointer, * then all attributes are processed. * - * \p op is a user-defined function whose prototype is defined as follows: - * \snippet this H5A_operator1_t_snip - * \click4more - * * \version 1.8.0 The function \p H5Aiterate was renamed to H5Aiterate1() * and deprecated in this release. * \since 1.0.0 @@ -1283,8 +1142,7 @@ H5_DLL herr_t H5Aiterate1(hid_t loc_id, unsigned *idx, H5A_operator1_t op, void * * \return \hid_tv{attribute} * - * \deprecated This function is deprecated in favor of the function - * H5Aopen_by_idx(). + * \deprecation_note{H5Aopen_by_idx()} * * \details H5Aopen_idx() opens an attribute which is attached to the * object specified with \p loc_id . The location object may be @@ -1310,8 +1168,7 @@ H5_DLL hid_t H5Aopen_idx(hid_t loc_id, unsigned idx); * * \return \hid_tv{attribute} * - * \deprecated This function is deprecated in favor of the function - * H5Aopen_by_name(). + * \deprecation_note{H5Aopen_by_name()} * * \details H5Aopen_name() opens an attribute specified by its name, * \p name, which is attached to the object specified with diff --git a/src/H5CS.c b/src/H5CS.c index 6510c25..d7cb6f1 100644 --- a/src/H5CS.c +++ b/src/H5CS.c @@ -262,9 +262,9 @@ H5CS_copy_stack(void) if (NULL == (new_stack->rec = HDcalloc(old_stack->nused, sizeof(const char *)))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate function stack records") - /* Copy old stack to new one, duplicating the strings */ - for (u = 0; u < old_stack->nused; u++) - new_stack->rec[u] = HDstrdup(old_stack->rec[u]); + /* Copy pointers on old stack to new one */ + /* (Strings don't need to be duplicated, they are statically allocated) */ + HDmemcpy(new_stack->rec, old_stack->rec, sizeof(char *) * old_stack->nused); new_stack->nused = new_stack->nalloc = old_stack->nused; /* Set the return value */ @@ -298,11 +298,9 @@ H5CS_close_stack(H5CS_t *stack) HDassert(stack); /* Free stack */ - for (u = 0; u < stack->nused; u++) { - if (stack->rec[u]) - HDfree((void *)stack->rec[u]); - stack->rec[u] = NULL; - } /* end for */ + /* The function name string are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ if (stack->rec) { HDfree(stack->rec); stack->rec = NULL; diff --git a/src/H5CX.c b/src/H5CX.c index c304548..01bf435 100644 --- a/src/H5CX.c +++ b/src/H5CX.c @@ -761,13 +761,14 @@ H5CX__get_context(void) static void H5CX__push_common(H5CX_node_t *cnode) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_STATIC_NOERR /* Sanity check */ HDassert(cnode); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + HDassert(head); /* Set non-zero context info */ cnode->ctx.dxpl_id = H5P_DATASET_XFER_DEFAULT; @@ -834,7 +835,7 @@ done: void H5CX_push_special(void) { - H5CX_node_t *cnode; /* Context node */ + H5CX_node_t *cnode = NULL; /* Context node */ FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -868,13 +869,13 @@ H5CX_push_special(void) herr_t H5CX_retrieve_state(H5CX_state_t **api_state) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(api_state); @@ -975,6 +976,16 @@ H5CX_retrieve_state(H5CX_state_t **api_state) #endif /* H5_HAVE_PARALLEL */ done: + /* Cleanup on error */ + if (ret_value < 0) { + if (*api_state) { + /* Release the (possibly partially allocated) API state struct */ + if (H5CX_free_state(*api_state) < 0) + HDONE_ERROR(H5E_CONTEXT, H5E_CANTRELEASE, FAIL, "unable to release API state") + *api_state = NULL; + } /* end if */ + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5CX_retrieve_state() */ @@ -998,12 +1009,12 @@ done: herr_t H5CX_restore_state(const H5CX_state_t *api_state) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(api_state); @@ -1066,22 +1077,22 @@ H5CX_free_state(H5CX_state_t *api_state) HDassert(api_state); /* Release the DCPL */ - if (api_state->dcpl_id != H5P_DATASET_CREATE_DEFAULT) + if (0 != api_state->dcpl_id && H5P_DATASET_CREATE_DEFAULT != api_state->dcpl_id) if (H5I_dec_ref(api_state->dcpl_id) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on DCPL") /* Release the DXPL */ - if (api_state->dxpl_id != H5P_DATASET_XFER_DEFAULT) + if (0 != api_state->dxpl_id && H5P_DATASET_XFER_DEFAULT != api_state->dxpl_id) if (H5I_dec_ref(api_state->dxpl_id) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on DXPL") /* Release the LAPL */ - if (api_state->lapl_id != H5P_LINK_ACCESS_DEFAULT) + if (0 != api_state->lapl_id && H5P_LINK_ACCESS_DEFAULT != api_state->lapl_id) if (H5I_dec_ref(api_state->lapl_id) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on LAPL") /* Release the LCPL */ - if (api_state->lcpl_id != H5P_LINK_CREATE_DEFAULT) + if (0 != api_state->lcpl_id && H5P_LINK_CREATE_DEFAULT != api_state->lcpl_id) if (H5I_dec_ref(api_state->lcpl_id) < 0) HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on LCPL") @@ -1124,15 +1135,19 @@ done: hbool_t H5CX_is_def_dxpl(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hbool_t is_def_dxpl = FALSE; /* Flag to indicate DXPL is default */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT); + /* Set return value */ + is_def_dxpl = ((*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT); + + FUNC_LEAVE_NOAPI(is_def_dxpl) } /* end H5CX_is_def_dxpl() */ /*------------------------------------------------------------------------- @@ -1150,13 +1165,13 @@ H5CX_is_def_dxpl(void) void H5CX_set_dxpl(hid_t dxpl_id) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ - HDassert(*head); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + HDassert(head && *head); /* Set the API context's DXPL to a new value */ (*head)->ctx.dxpl_id = dxpl_id; @@ -1179,13 +1194,13 @@ H5CX_set_dxpl(hid_t dxpl_id) void H5CX_set_dcpl(hid_t dcpl_id) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ - HDassert(*head); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + HDassert(head && *head); /* Set the API context's DCPL to a new value */ (*head)->ctx.dcpl_id = dcpl_id; @@ -1209,13 +1224,13 @@ H5CX_set_dcpl(hid_t dcpl_id) herr_t H5CX_set_libver_bounds(H5F_t *f) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -1245,13 +1260,13 @@ done: void H5CX_set_lcpl(hid_t lcpl_id) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ - HDassert(*head); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + HDassert(head && *head); /* Set the API context's LCPL to a new value */ (*head)->ctx.lcpl_id = lcpl_id; @@ -1274,12 +1289,12 @@ H5CX_set_lcpl(hid_t lcpl_id) void H5CX_set_lapl(hid_t lapl_id) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context's LAPL to a new value */ @@ -1314,15 +1329,15 @@ H5CX_set_apl(hid_t *acspl_id, const H5P_libclass_t *libclass, #endif /* H5_HAVE_PARALLEL */ is_collective) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity checks */ HDassert(acspl_id); HDassert(libclass); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set access plist to the default property list of the appropriate class if it's the generic default */ @@ -1437,13 +1452,13 @@ H5CX_set_loc(hid_t loc_id) { #ifdef H5_HAVE_PARALLEL - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set collective metadata read flag */ @@ -1491,13 +1506,13 @@ done: herr_t H5CX_set_vol_wrap_ctx(void *vol_wrap_ctx) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -1525,13 +1540,13 @@ done: herr_t H5CX_set_vol_connector_prop(const H5VL_connector_prop_t *vol_connector_prop) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -1559,15 +1574,19 @@ done: hid_t H5CX_get_dxpl(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hid_t dxpl_id = H5I_INVALID_HID; /* DXPL ID for API operation */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.dxpl_id) + /* Set return value */ + dxpl_id = (*head)->ctx.dxpl_id; + + FUNC_LEAVE_NOAPI(dxpl_id) } /* end H5CX_get_dxpl() */ /*------------------------------------------------------------------------- @@ -1585,15 +1604,19 @@ H5CX_get_dxpl(void) hid_t H5CX_get_lapl(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hid_t lapl_id = H5I_INVALID_HID; /* LAPL ID for API operation */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.lapl_id) + /* Set return value */ + lapl_id = (*head)->ctx.lapl_id; + + FUNC_LEAVE_NOAPI(lapl_id) } /* end H5CX_get_lapl() */ /*------------------------------------------------------------------------- @@ -1611,14 +1634,14 @@ H5CX_get_lapl(void) herr_t H5CX_get_vol_wrap_ctx(void **vol_wrap_ctx) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_wrap_ctx); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Check for value that was set */ @@ -1647,14 +1670,14 @@ done: herr_t H5CX_get_vol_connector_prop(H5VL_connector_prop_t *vol_connector_prop) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_connector_prop); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Check for value that was set */ @@ -1683,15 +1706,19 @@ done: haddr_t H5CX_get_tag(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + haddr_t tag = HADDR_UNDEF; /* Current object's tag (ohdr chunk #0 address) */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.tag) + /* Set return value */ + tag = (*head)->ctx.tag; + + FUNC_LEAVE_NOAPI(tag) } /* end H5CX_get_tag() */ /*------------------------------------------------------------------------- @@ -1709,15 +1736,19 @@ H5CX_get_tag(void) H5AC_ring_t H5CX_get_ring(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + H5AC_ring_t ring = H5AC_RING_INV; /* Current metadata cache ring for entries */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.ring) + /* Set return value */ + ring = (*head)->ctx.ring; + + FUNC_LEAVE_NOAPI(ring) } /* end H5CX_get_ring() */ #ifdef H5_HAVE_PARALLEL @@ -1737,15 +1768,19 @@ H5CX_get_ring(void) hbool_t H5CX_get_coll_metadata_read(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hbool_t coll_md_read = FALSE; FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.coll_metadata_read) + /* Set return value */ + coll_md_read = (*head)->ctx.coll_metadata_read; + + FUNC_LEAVE_NOAPI(coll_md_read) } /* end H5CX_get_coll_metadata_read() */ /*------------------------------------------------------------------------- @@ -1765,15 +1800,15 @@ H5CX_get_coll_metadata_read(void) herr_t H5CX_get_mpi_coll_datatypes(MPI_Datatype *btype, MPI_Datatype *ftype) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(btype); HDassert(ftype); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context values */ @@ -1799,15 +1834,19 @@ done: hbool_t H5CX_get_mpi_file_flushing(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hbool_t flushing = FALSE; FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.mpi_file_flushing) + /* Set return value */ + flushing = (*head)->ctx.mpi_file_flushing; + + FUNC_LEAVE_NOAPI(flushing) } /* end H5CX_get_mpi_file_flushing() */ /*------------------------------------------------------------------------- @@ -1826,15 +1865,19 @@ H5CX_get_mpi_file_flushing(void) hbool_t H5CX_get_mpio_rank0_bcast(void) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + hbool_t do_rank0_bcast = FALSE; FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); - FUNC_LEAVE_NOAPI((*head)->ctx.rank0_bcast) + /* Set return value */ + do_rank0_bcast = (*head)->ctx.rank0_bcast; + + FUNC_LEAVE_NOAPI(do_rank0_bcast) } /* end H5CX_get_mpio_rank0_bcast() */ #endif /* H5_HAVE_PARALLEL */ @@ -1853,14 +1896,14 @@ H5CX_get_mpio_rank0_bcast(void) herr_t H5CX_get_btree_split_ratios(double split_ratio[3]) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(split_ratio); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -1889,14 +1932,14 @@ done: herr_t H5CX_get_max_temp_buf(size_t *max_temp_buf) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(max_temp_buf); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -1924,14 +1967,14 @@ done: herr_t H5CX_get_tconv_buf(void **tconv_buf) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(tconv_buf); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -1959,14 +2002,14 @@ done: herr_t H5CX_get_bkgr_buf(void **bkgr_buf) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(bkgr_buf); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -1994,14 +2037,14 @@ done: herr_t H5CX_get_bkgr_buf_type(H5T_bkg_t *bkgr_buf_type) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(bkgr_buf_type); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2029,14 +2072,14 @@ done: herr_t H5CX_get_vec_size(size_t *vec_size) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vec_size); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2066,14 +2109,14 @@ done: herr_t H5CX_get_io_xfer_mode(H5FD_mpio_xfer_t *io_xfer_mode) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(io_xfer_mode); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2101,14 +2144,14 @@ done: herr_t H5CX_get_mpio_coll_opt(H5FD_mpio_collective_opt_t *mpio_coll_opt) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_coll_opt); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2136,14 +2179,14 @@ done: herr_t H5CX_get_mpio_local_no_coll_cause(uint32_t *mpio_local_no_coll_cause) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_local_no_coll_cause); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2172,14 +2215,14 @@ done: herr_t H5CX_get_mpio_global_no_coll_cause(uint32_t *mpio_global_no_coll_cause) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_global_no_coll_cause); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2208,14 +2251,14 @@ done: herr_t H5CX_get_mpio_chunk_opt_mode(H5FD_mpio_chunk_opt_t *mpio_chunk_opt_mode) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_chunk_opt_mode); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2244,14 +2287,14 @@ done: herr_t H5CX_get_mpio_chunk_opt_num(unsigned *mpio_chunk_opt_num) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_chunk_opt_num); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2280,14 +2323,14 @@ done: herr_t H5CX_get_mpio_chunk_opt_ratio(unsigned *mpio_chunk_opt_ratio) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(mpio_chunk_opt_ratio); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2317,14 +2360,14 @@ done: herr_t H5CX_get_err_detect(H5Z_EDC_t *err_detect) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(err_detect); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2352,14 +2395,14 @@ done: herr_t H5CX_get_filter_cb(H5Z_cb_t *filter_cb) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(filter_cb); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2387,14 +2430,14 @@ done: herr_t H5CX_get_data_transform(H5Z_data_xform_t **data_transform) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(data_transform); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2445,14 +2488,14 @@ done: herr_t H5CX_get_vlen_alloc_info(H5T_vlen_alloc_info_t *vl_alloc_info) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vl_alloc_info); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2510,14 +2553,14 @@ done: herr_t H5CX_get_dt_conv_cb(H5T_conv_cb_t *dt_conv_cb) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(dt_conv_cb); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2545,14 +2588,14 @@ done: herr_t H5CX_get_encoding(H5T_cset_t *encoding) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(encoding); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.lcpl_id); @@ -2580,14 +2623,14 @@ done: herr_t H5CX_get_intermediate_group(unsigned *crt_intermed_group) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(crt_intermed_group); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.lcpl_id); @@ -2616,14 +2659,14 @@ done: herr_t H5CX_get_nlinks(size_t *nlinks) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(nlinks); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dxpl_id); @@ -2651,15 +2694,15 @@ done: herr_t H5CX_get_libver_bounds(H5F_libver_t *low_bound, H5F_libver_t *high_bound) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(low_bound); HDassert(high_bound); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.fapl_id); @@ -2690,14 +2733,14 @@ done: herr_t H5CX_get_dset_min_ohdr_flag(hbool_t *dset_min_ohdr_flag) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(dset_min_ohdr_flag); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dcpl_id); @@ -2726,14 +2769,14 @@ done: herr_t H5CX_get_ext_file_prefix(const char **extfile_prefix) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(extfile_prefix); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dapl_id); @@ -2784,14 +2827,14 @@ done: herr_t H5CX_get_vds_prefix(const char **vds_prefix) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vds_prefix); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dapl_id); @@ -2842,12 +2885,12 @@ done: void H5CX_set_tag(haddr_t tag) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); (*head)->ctx.tag = tag; @@ -2870,12 +2913,12 @@ H5CX_set_tag(haddr_t tag) void H5CX_set_ring(H5AC_ring_t ring) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); (*head)->ctx.ring = ring; @@ -2900,12 +2943,12 @@ H5CX_set_ring(H5AC_ring_t ring) void H5CX_set_coll_metadata_read(hbool_t cmdr) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); (*head)->ctx.coll_metadata_read = cmdr; @@ -2930,14 +2973,14 @@ H5CX_set_coll_metadata_read(hbool_t cmdr) herr_t H5CX_set_mpi_coll_datatypes(MPI_Datatype btype, MPI_Datatype ftype) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context values */ @@ -2963,13 +3006,13 @@ done: herr_t H5CX_set_io_xfer_mode(H5FD_mpio_xfer_t io_xfer_mode) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -2997,13 +3040,13 @@ done: herr_t H5CX_set_mpio_coll_opt(H5FD_mpio_collective_opt_t mpio_coll_opt) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -3031,12 +3074,12 @@ done: void H5CX_set_mpi_file_flushing(hbool_t flushing) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); (*head)->ctx.mpi_file_flushing = flushing; @@ -3060,12 +3103,12 @@ H5CX_set_mpi_file_flushing(hbool_t flushing) void H5CX_set_mpio_rank0_bcast(hbool_t rank0_bcast) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); (*head)->ctx.rank0_bcast = rank0_bcast; @@ -3089,13 +3132,13 @@ H5CX_set_mpio_rank0_bcast(hbool_t rank0_bcast) herr_t H5CX_set_vlen_alloc_info(H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free_t free_func, void *free_info) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -3126,13 +3169,13 @@ done: herr_t H5CX_set_nlinks(size_t nlinks) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Set the API context value */ @@ -3162,12 +3205,12 @@ done: void H5CX_set_mpio_actual_chunk_opt(H5D_mpio_actual_chunk_opt_mode_t mpio_actual_chunk_opt) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3193,12 +3236,12 @@ H5CX_set_mpio_actual_chunk_opt(H5D_mpio_actual_chunk_opt_mode_t mpio_actual_chun void H5CX_set_mpio_actual_io_mode(H5D_mpio_actual_io_mode_t mpio_actual_io_mode) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3224,12 +3267,12 @@ H5CX_set_mpio_actual_io_mode(H5D_mpio_actual_io_mode_t mpio_actual_io_mode) void H5CX_set_mpio_local_no_coll_cause(uint32_t mpio_local_no_coll_cause) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert((*head)->ctx.dxpl_id != H5P_DEFAULT); @@ -3258,12 +3301,12 @@ H5CX_set_mpio_local_no_coll_cause(uint32_t mpio_local_no_coll_cause) void H5CX_set_mpio_global_no_coll_cause(uint32_t mpio_global_no_coll_cause) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ FUNC_ENTER_NOAPI_NOINIT_NOERR /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert((*head)->ctx.dxpl_id != H5P_DEFAULT); @@ -3296,13 +3339,13 @@ H5CX_set_mpio_global_no_coll_cause(uint32_t mpio_global_no_coll_cause) herr_t H5CX_test_set_mpio_coll_chunk_link_hard(int mpio_coll_chunk_link_hard) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3329,13 +3372,13 @@ done: herr_t H5CX_test_set_mpio_coll_chunk_multi_hard(int mpio_coll_chunk_multi_hard) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3362,13 +3405,13 @@ done: herr_t H5CX_test_set_mpio_coll_chunk_link_num_true(int mpio_coll_chunk_link_num_true) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3396,13 +3439,13 @@ done: herr_t H5CX_test_set_mpio_coll_chunk_link_num_false(int mpio_coll_chunk_link_num_false) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3430,13 +3473,13 @@ done: herr_t H5CX_test_set_mpio_coll_chunk_multi_ratio_coll(int mpio_coll_chunk_multi_ratio_coll) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3464,13 +3507,13 @@ done: herr_t H5CX_test_set_mpio_coll_chunk_multi_ratio_ind(int mpio_coll_chunk_multi_ratio_ind) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3497,13 +3540,13 @@ done: herr_t H5CX_test_set_mpio_coll_rank0_bcast(hbool_t mpio_coll_rank0_bcast) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity checks */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)); @@ -3530,14 +3573,14 @@ done: herr_t H5CX_get_ohdr_flags(uint8_t *ohdr_flags) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - herr_t ret_value = SUCCEED; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(ohdr_flags); + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); HDassert(H5P_DEFAULT != (*head)->ctx.dcpl_id); @@ -3565,9 +3608,8 @@ done: static H5CX_node_t * H5CX__pop_common(hbool_t update_dxpl_props) { - H5CX_node_t **head = - H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ - H5CX_node_t *ret_value = NULL; /* Return value */ + H5CX_node_t **head = NULL; /* Pointer to head of API context list */ + H5CX_node_t * ret_value = NULL; /* Return value */ #ifdef H5_HAVE_PARALLEL FUNC_ENTER_STATIC @@ -3576,6 +3618,7 @@ H5CX__pop_common(hbool_t update_dxpl_props) #endif /* Sanity check */ + head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */ HDassert(head && *head); /* Check for cached DXPL properties to return to application */ diff --git a/src/H5D.c b/src/H5D.c index ed97bff..7153c7d 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -557,8 +557,9 @@ H5D__get_space_api_common(hid_t dset_id, void **token_ptr, H5VL_object_t **_vol_ { H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = - (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_STATIC @@ -566,11 +567,17 @@ H5D__get_space_api_common(hid_t dset_id, void **token_ptr, H5VL_object_t **_vol_ if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_SPACE; + vol_cb_args.args.get_space.space_id = H5I_INVALID_HID; + /* Get the dataspace */ - if (H5VL_dataset_get(*vol_obj_ptr, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, token_ptr, - &ret_value) < 0) + if (H5VL_dataset_get(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace") + /* Set return value */ + ret_value = vol_cb_args.args.get_space.space_id; + done: FUNC_LEAVE_NOAPI(ret_value) } /* H5D__get_space_api_common() */ @@ -591,7 +598,7 @@ done: hid_t H5Dget_space(hid_t dset_id) { - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", dset_id); @@ -664,8 +671,9 @@ done: herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation /*out*/) { - H5VL_object_t *vol_obj = NULL; /* Dataset structure */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", dset_id, allocation); @@ -674,9 +682,12 @@ H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_SPACE_STATUS; + vol_cb_args.args.get_space_status.status = allocation; + /* Get dataspace status */ - if ((ret_value = H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_SPACE_STATUS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, allocation)) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get space status") done: @@ -699,8 +710,9 @@ done: hid_t H5Dget_type(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", dset_id); @@ -709,11 +721,17 @@ H5Dget_type(hid_t dset_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_TYPE; + vol_cb_args.args.get_type.type_id = H5I_INVALID_HID; + /* Get the datatype */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype") + /* Set return value */ + ret_value = vol_cb_args.args.get_type.type_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_type() */ @@ -737,8 +755,9 @@ done: hid_t H5Dget_create_plist(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", dset_id); @@ -747,11 +766,17 @@ H5Dget_create_plist(hid_t dset_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_DCPL; + vol_cb_args.args.get_dcpl.dcpl_id = H5I_INVALID_HID; + /* Get the dataset creation property list */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_DCPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataset creation properties") + /* Set return value */ + ret_value = vol_cb_args.args.get_dcpl.dcpl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_create_plist() */ @@ -792,8 +817,9 @@ done: hid_t H5Dget_access_plist(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", dset_id); @@ -802,11 +828,17 @@ H5Dget_access_plist(hid_t dset_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_DAPL; + vol_cb_args.args.get_dapl.dapl_id = H5I_INVALID_HID; + /* Get the dataset access property list */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_DAPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataset access properties") + /* Set return value */ + ret_value = vol_cb_args.args.get_dapl.dapl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_access_plist() */ @@ -829,8 +861,10 @@ done: hsize_t H5Dget_storage_size(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - hsize_t ret_value = 0; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hsize_t storage_size = 0; /* Storage size of dataset */ + hsize_t ret_value = 0; /* Return value */ FUNC_ENTER_API(0) H5TRACE1("h", "i", dset_id); @@ -839,11 +873,17 @@ H5Dget_storage_size(hid_t dset_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid dataset identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_STORAGE_SIZE; + vol_cb_args.args.get_storage_size.storage_size = &storage_size; + /* Get the storage size */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_STORAGE_SIZE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, 0, "unable to get storage size") + /* Set return value */ + ret_value = storage_size; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_storage_size() */ @@ -862,8 +902,11 @@ done: haddr_t H5Dget_offset(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - haddr_t ret_value = HADDR_UNDEF; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + haddr_t dset_offset = HADDR_UNDEF; /* Dataset's offset */ + haddr_t ret_value = HADDR_UNDEF; /* Return value */ FUNC_ENTER_API(HADDR_UNDEF) H5TRACE1("a", "i", dset_id); @@ -872,11 +915,18 @@ H5Dget_offset(hid_t dset_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "invalid dataset identifier") + /* Set up VOL callback arguments */ + dset_opt_args.get_offset.offset = &dset_offset; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_OFFSET; + vol_cb_args.args = &dset_opt_args; + /* Get the offset */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_OFFSET, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, HADDR_UNDEF, "unable to get offset") + /* Set return value */ + ret_value = dset_offset; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_offset() */ @@ -941,7 +991,11 @@ done: * * The MEM_SPACE_ID can be the constant H5S_ALL in which case * the memory dataspace is the same as the file dataspace - * defined when the dataset was created. + * defined when the dataset was created. The MEM_SPACE_ID can + * also be the constant H5S_BLOCK, which indicates that the + * buffer provided is a single contiguous block of memory, with + * the same # of elements as specified in the FILE_SPACE_ID + * selection. * * The number of elements in the memory dataspace must match * the number of elements in the file dataspace. @@ -1032,13 +1086,15 @@ done: *--------------------------------------------------------------------------- */ herr_t -H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters, void *buf) +H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *filters, void *buf /*out*/) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE5("e", "ii*h*Iu*x", dset_id, dxpl_id, offset, filters, buf); + H5TRACE5("e", "ii*h*Iux", dset_id, dxpl_id, offset, filters, buf); /* Check arguments */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) @@ -1056,11 +1112,20 @@ H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, uint32_t *fil else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dxpl_id is not a dataset transfer property list ID") + /* Set up VOL callback arguments */ + dset_opt_args.chunk_read.offset = offset; + dset_opt_args.chunk_read.filters = 0; + dset_opt_args.chunk_read.buf = buf; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_CHUNK_READ; + vol_cb_args.args = &dset_opt_args; + /* Read the raw chunk */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_CHUNK_READ, dxpl_id, H5_REQUEST_NULL, offset, - filters, buf) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read unprocessed chunk data") + /* Set return value */ + *filters = dset_opt_args.chunk_read.filters; + done: FUNC_LEAVE_API(ret_value) } /* end H5Dread_chunk() */ @@ -1126,7 +1191,11 @@ done: * * The MEM_SPACE_ID can be the constant H5S_ALL in which case * the memory dataspace is the same as the file dataspace - * defined when the dataset was created. + * defined when the dataset was created. The MEM_SPACE_ID can + * also be the constant H5S_BLOCK, which indicates that the + * buffer provided is a single contiguous block of memory, with + * the same # of elements as specified in the FILE_SPACE_ID + * selection. * * The number of elements in the memory dataspace must match * the number of elements in the file dataspace. @@ -1222,9 +1291,11 @@ herr_t H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, const hsize_t *offset, size_t data_size, const void *buf) { - H5VL_object_t *vol_obj = NULL; - uint32_t data_size_32; /* Chunk data size (limited to 32-bits currently) */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + uint32_t data_size_32; /* Chunk data size (limited to 32-bits currently) */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iiIu*hz*x", dset_id, dxpl_id, filters, offset, data_size, buf); @@ -1250,9 +1321,16 @@ H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, const hsize_t *of else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dxpl_id is not a dataset transfer property list ID") + /* Set up VOL callback arguments */ + dset_opt_args.chunk_write.offset = offset; + dset_opt_args.chunk_write.filters = filters; + dset_opt_args.chunk_write.size = data_size_32; + dset_opt_args.chunk_write.buf = buf; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_CHUNK_WRITE; + vol_cb_args.args = &dset_opt_args; + /* Write chunk */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_CHUNK_WRITE, dxpl_id, H5_REQUEST_NULL, filters, - offset, data_size_32, buf) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write unprocessed chunk data") done: @@ -1348,7 +1426,7 @@ H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id, hid_t dst_space_ done: /* Release selection iterator */ if (iter_init && H5S_SELECT_ITER_RELEASE(iter) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release selection iterator") + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release selection iterator") if (iter) iter = H5FL_FREE(H5S_sel_iter_t, iter); @@ -1447,7 +1525,7 @@ H5Dgather(hid_t src_space_id, const void *src_buf, hid_t type_id, size_t dst_buf done: /* Release selection iterator */ if (iter_init && H5S_SELECT_ITER_RELEASE(iter) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release selection iterator") + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release selection iterator") if (iter) iter = H5FL_FREE(H5S_sel_iter_t, iter); @@ -1642,9 +1720,18 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *s &supported) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't check for 'get vlen buf size' operation") if (supported & H5VL_OPT_QUERY_SUPPORTED) { + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + + /* Set up VOL callback arguments */ + dset_opt_args.get_vlen_buf_size.type_id = type_id; + dset_opt_args.get_vlen_buf_size.space_id = space_id; + dset_opt_args.get_vlen_buf_size.size = size; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE; + vol_cb_args.args = &dset_opt_args; + /* Make the 'get_vlen_buf_size' callback */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, type_id, space_id, size) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get vlen buf size") } /* end if */ else { @@ -1673,7 +1760,8 @@ H5D__set_extent_api_common(hid_t dset_id, const hsize_t size[], void **token_ptr H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_dataset_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1687,9 +1775,12 @@ H5D__set_extent_api_common(hid_t dset_id, const hsize_t size[], void **token_ptr if (H5CX_set_loc(dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_SET_EXTENT; + vol_cb_args.args.set_extent.size = size; + /* Set the extent */ - if ((ret_value = H5VL_dataset_specific(*vol_obj_ptr, H5VL_DATASET_SET_EXTENT, H5P_DATASET_XFER_DEFAULT, - token_ptr, size)) < 0) + if (H5VL_dataset_specific(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set dataset extent") done: @@ -1775,8 +1866,9 @@ done: herr_t H5Dflush(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", dset_id); @@ -1789,12 +1881,15 @@ H5Dflush(hid_t dset_id) if (H5CX_set_loc(dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_FLUSH; + vol_cb_args.args.flush.dset_id = dset_id; + /* Flush dataset information cached in memory * XXX: Note that we need to pass the ID to the VOL since the H5F_flush_cb_t * callback needs it and that's in the public API. */ - if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_FLUSH, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, dset_id)) < 0) + if (H5VL_dataset_specific(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush dataset") done: @@ -1802,41 +1897,6 @@ done: } /* H5Dflush */ /*------------------------------------------------------------------------- - * Function: H5Dwait - * - * Purpose: Wait for all operations on a dataset. - * Tang: added for async - * - * Return: Non-negative on success/Negative on failure - * - *------------------------------------------------------------------------- - */ -herr_t -H5Dwait(hid_t dset_id) -{ - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE1("e", "i", dset_id); - - /* Check args */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dset_id parameter is not a valid dataset identifier") - - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(dset_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") - - if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_WAIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, dset_id)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTOPERATE, FAIL, "unable to wait dataset") - -done: - FUNC_LEAVE_API(ret_value) -} /* H5Dwait*/ - -/*------------------------------------------------------------------------- * Function: H5Drefresh * * Purpose: Refreshes all buffers associated with a dataset. @@ -1848,8 +1908,9 @@ done: herr_t H5Drefresh(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", dset_id); @@ -1862,9 +1923,12 @@ H5Drefresh(hid_t dset_id) if (H5CX_set_loc(dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_REFRESH; + vol_cb_args.args.refresh.dset_id = dset_id; + /* Refresh the dataset object */ - if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_REFRESH, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, dset_id)) < 0) + if (H5VL_dataset_specific(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to refresh dataset") done: @@ -1891,8 +1955,9 @@ done: herr_t H5Dformat_convert(hid_t dset_id) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", dset_id); @@ -1905,9 +1970,12 @@ H5Dformat_convert(hid_t dset_id) if (H5CX_set_loc(dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_DATASET_FORMAT_CONVERT; + vol_cb_args.args = NULL; + /* Convert the dataset */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_FORMAT_CONVERT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_INTERNAL, FAIL, "can't convert dataset format") done: @@ -1929,8 +1997,10 @@ done: herr_t H5Dget_chunk_index_type(hid_t dset_id, H5D_chunk_index_t *idx_type /*out*/) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", dset_id, idx_type); @@ -1941,9 +2011,13 @@ H5Dget_chunk_index_type(hid_t dset_id, H5D_chunk_index_t *idx_type /*out*/) if (NULL == idx_type) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "idx_type parameter cannot be NULL") + /* Set up VOL callback arguments */ + dset_opt_args.get_chunk_idx_type.idx_type = idx_type; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE; + vol_cb_args.args = &dset_opt_args; + /* Get the chunk indexing type */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, idx_type) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk index type") done: @@ -1968,8 +2042,10 @@ done: herr_t H5Dget_chunk_storage_size(hid_t dset_id, const hsize_t *offset, hsize_t *chunk_nbytes /*out*/) { - H5VL_object_t *vol_obj; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "i*hx", dset_id, offset, chunk_nbytes); @@ -1982,9 +2058,14 @@ H5Dget_chunk_storage_size(hid_t dset_id, const hsize_t *offset, hsize_t *chunk_n if (NULL == chunk_nbytes) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "chunk_nbytes parameter cannot be NULL") + /* Set up VOL callback arguments */ + dset_opt_args.get_chunk_storage_size.offset = offset; + dset_opt_args.get_chunk_storage_size.size = chunk_nbytes; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE; + vol_cb_args.args = &dset_opt_args; + /* Get the dataset creation property list */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, offset, chunk_nbytes) < 0) + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get storage size of chunk") done: @@ -2015,8 +2096,10 @@ done: herr_t H5Dget_num_chunks(hid_t dset_id, hid_t fspace_id, hsize_t *nchunks /*out*/) { - H5VL_object_t *vol_obj = NULL; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj = NULL; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE3("e", "iix", dset_id, fspace_id, nchunks); @@ -2027,10 +2110,15 @@ H5Dget_num_chunks(hid_t dset_id, hid_t fspace_id, hsize_t *nchunks /*out*/) if (NULL == nchunks) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument (null)") + /* Set up VOL callback arguments */ + dset_opt_args.get_num_chunks.space_id = fspace_id; + dset_opt_args.get_num_chunks.nchunks = nchunks; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_NUM_CHUNKS; + vol_cb_args.args = &dset_opt_args; + /* Get the number of written chunks */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_NUM_CHUNKS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, fspace_id, nchunks) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't get number of chunks") + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get number of chunks") done: FUNC_LEAVE_API(ret_value); @@ -2062,9 +2150,11 @@ herr_t H5Dget_chunk_info(hid_t dset_id, hid_t fspace_id, hsize_t chk_index, hsize_t *offset /*out*/, unsigned *filter_mask /*out*/, haddr_t *addr /*out*/, hsize_t *size /*out*/) { - H5VL_object_t *vol_obj = NULL; /* Dataset for this operation */ - hsize_t nchunks = 0; - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj = NULL; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + hsize_t nchunks = 0; /* Number of chunks */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE7("e", "iihxxxx", dset_id, fspace_id, chk_index, offset, filter_mask, addr, size); @@ -2076,19 +2166,33 @@ H5Dget_chunk_info(hid_t dset_id, hid_t fspace_id, hsize_t chk_index, hsize_t *of if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + /* Set up VOL callback arguments */ + dset_opt_args.get_num_chunks.space_id = fspace_id; + dset_opt_args.get_num_chunks.nchunks = &nchunks; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_NUM_CHUNKS; + vol_cb_args.args = &dset_opt_args; + /* Get the number of written chunks to check range */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_NUM_CHUNKS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, fspace_id, &nchunks) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't get number of chunks") + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get number of chunks") /* Check range for chunk index */ if (chk_index >= nchunks) HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk index is out of range") + /* Set up VOL callback arguments */ + dset_opt_args.get_chunk_info_by_idx.space_id = fspace_id; + dset_opt_args.get_chunk_info_by_idx.chk_index = chk_index; + dset_opt_args.get_chunk_info_by_idx.offset = offset; + dset_opt_args.get_chunk_info_by_idx.filter_mask = filter_mask; + dset_opt_args.get_chunk_info_by_idx.addr = addr; + dset_opt_args.get_chunk_info_by_idx.size = size; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX; + vol_cb_args.args = &dset_opt_args; + /* Call private function to get the chunk info given the chunk's index */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, fspace_id, chk_index, offset, filter_mask, addr, size) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't get chunk info by index") + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info by index") done: FUNC_LEAVE_API(ret_value); @@ -2119,8 +2223,10 @@ herr_t H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, unsigned *filter_mask /*out*/, haddr_t *addr /*out*/, hsize_t *size /*out*/) { - H5VL_object_t *vol_obj = NULL; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj = NULL; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*hxxx", dset_id, offset, filter_mask, addr, size); @@ -2134,10 +2240,17 @@ H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, unsigned *filte if (NULL == offset) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument (null)") + /* Set up VOL callback arguments */ + dset_opt_args.get_chunk_info_by_coord.offset = offset; + dset_opt_args.get_chunk_info_by_coord.filter_mask = filter_mask; + dset_opt_args.get_chunk_info_by_coord.addr = addr; + dset_opt_args.get_chunk_info_by_coord.size = size; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD; + vol_cb_args.args = &dset_opt_args; + /* Call private function to get the chunk info given the chunk's index */ - if (H5VL_dataset_optional(vol_obj, H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, offset, filter_mask, addr, size) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't get chunk info by its logical coordinates") + if (H5VL_dataset_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info by its logical coordinates") done: FUNC_LEAVE_API(ret_value) @@ -2150,6 +2263,7 @@ done: * * Parameters: * hid_t dset_id; IN: Chunked dataset ID + * hid_t dxpl_id; IN: Dataset transfer property list ID * H5D_chunk_iter_op_t cb IN: User callback function, called for every chunk. * void *op_data IN/OUT: Optional user data passed on to user callback. * @@ -2187,22 +2301,37 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Dchunk_iter(hid_t dset_id, H5D_chunk_iter_op_t cb, void *op_data) +H5Dchunk_iter(hid_t dset_id, hid_t dxpl_id, H5D_chunk_iter_op_t op, void *op_data) { - H5VL_object_t *vol_obj = NULL; /* Dataset for this operation */ - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj = NULL; /* Dataset for this operation */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_dataset_optional_args_t dset_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) - H5TRACE3("e", "ix*x", dset_id, cb, op_data); + H5TRACE4("e", "iix*x", dset_id, dxpl_id, op, op_data); /* Check arguments */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(dset_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + if (NULL == op) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid callback to chunk iteration") - /* Call private function to get the chunk info given the chunk's index */ - if (H5VL_dataset_specific(vol_obj, H5VL_DATASET_CHUNK_ITER, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, cb, - op_data) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't iterate over chunks") + /* Get the default dataset transfer property list if the user didn't provide one */ + if (H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dxpl_id is not a dataset transfer property list ID") + + /* Set up VOL callback arguments */ + dset_opt_args.chunk_iter.op = op; + dset_opt_args.chunk_iter.op_data = op_data; + vol_cb_args.op_type = H5VL_NATIVE_DATASET_CHUNK_ITER; + vol_cb_args.args = &dset_opt_args; + + /* Iterate over the chunks */ + if ((ret_value = H5VL_dataset_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL)) < 0) + HERROR(H5E_BADITER, H5E_BADITER, "error iterating over dataset chunks"); done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 5fc7abb..71a15b0 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -107,9 +107,9 @@ /*#define H5D_CHUNK_DEBUG */ /* Flags for the "edge_chunk_state" field below */ -#define H5D_RDCC_DISABLE_FILTERS 0x01u /* Disable filters on this chunk */ +#define H5D_RDCC_DISABLE_FILTERS 0x01U /* Disable filters on this chunk */ #define H5D_RDCC_NEWLY_DISABLED_FILTERS \ - 0x02u /* Filters have been disabled since \ + 0x02U /* Filters have been disabled since \ * the last flush */ /******************/ @@ -245,10 +245,10 @@ typedef struct H5D_chunk_coll_info_t { } H5D_chunk_coll_info_t; #endif /* H5_HAVE_PARALLEL */ -typedef struct H5D_chunk_iter_cb_data_t { - H5D_chunk_iter_op_t cb; /* User defined callback */ +typedef struct H5D_chunk_iter_ud_t { + H5D_chunk_iter_op_t op; /* User defined callback */ void * op_data; /* User data for user defined callback */ -} H5D_chunk_iter_cb_data_t; +} H5D_chunk_iter_ud_t; /********************/ /* Local Prototypes */ @@ -7515,14 +7515,15 @@ done: static int H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata) { - int ret_value = 0; + const H5D_chunk_iter_ud_t *data = (H5D_chunk_iter_ud_t *)udata; + int ret_value = H5_ITER_CONT; FUNC_ENTER_STATIC_NOERR - const H5D_chunk_iter_cb_data_t *data = (H5D_chunk_iter_cb_data_t *)udata; - - ret_value = (data->cb)(chunk_rec->scaled, chunk_rec->filter_mask, chunk_rec->chunk_addr, - chunk_rec->nbytes, data->op_data); + /* Check for callback failure and pass along return value */ + if ((ret_value = (data->op)(chunk_rec->scaled, chunk_rec->filter_mask, chunk_rec->chunk_addr, + chunk_rec->nbytes, data->op_data)) < 0) + HERROR(H5E_DATASET, H5E_CANTNEXT, "iteration operator failed"); FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__chunk_iter_cb */ @@ -7541,7 +7542,7 @@ H5D__chunk_iter_cb(const H5D_chunk_rec_t *chunk_rec, void *udata) *------------------------------------------------------------------------- */ herr_t -H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data) +H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t op, void *op_data) { const H5O_layout_t *layout = NULL; /* Dataset layout */ const H5D_rdcc_t * rdcc = NULL; /* Raw data chunk cache */ @@ -7576,15 +7577,65 @@ H5D__chunk_iter(const H5D_t *dset, H5D_chunk_iter_op_t cb, void *op_data) /* If the dataset is not written, return without errors */ if (H5F_addr_defined(idx_info.storage->idx_addr)) { - H5D_chunk_iter_cb_data_t data; - data.cb = cb; - data.op_data = op_data; + H5D_chunk_iter_ud_t ud; + + /* Set up info for iteration callback */ + ud.op = op; + ud.op_data = op_data; /* Iterate over the allocated chunks calling the iterator callback */ - if ((dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D__chunk_iter_cb, &data) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to iterate over chunks.") + if ((ret_value = + (dset->shared->layout.storage.u.chunk.ops->iterate)(&idx_info, H5D__chunk_iter_cb, &ud)) < 0) + HERROR(H5E_DATASET, H5E_CANTNEXT, "chunk iteration failed"); } /* end if H5F_addr_defined */ done: FUNC_LEAVE_NOAPI_TAG(ret_value) } /* end H5D__chunk_iter() */ + +/*------------------------------------------------------------------------- + * Function: H5D__chunk_get_offset_copy + * + * Purpose: Copies an offset buffer and performs bounds checks on the + * values. + * + * This helper function ensures that the offset buffer given + * by the user is suitable for use with the rest of the library. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5D__chunk_get_offset_copy(const H5D_t *dset, const hsize_t *offset, hsize_t *offset_copy) +{ + unsigned u; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(dset); + HDassert(offset); + HDassert(offset_copy); + + /* The library's chunking code requires the offset to terminate with a zero. + * So transfer the offset array to an internal offset array that we + * can properly terminate (handled via the memset call). + */ + HDmemset(offset_copy, 0, H5O_LAYOUT_NDIMS * sizeof(hsize_t)); + + for (u = 0; u < dset->shared->ndims; u++) { + /* Make sure the offset doesn't exceed the dataset's dimensions */ + if (offset[u] > dset->shared->curr_dims[u]) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "offset exceeds dimensions of dataset") + + /* Make sure the offset fall right on a chunk's boundary */ + if (offset[u] % dset->shared->layout.u.chunk.dim[u]) + HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "offset doesn't fall on chunks's boundary") + + offset_copy[u] = offset[u]; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D__chunk_get_offset_copy() */ diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 1c66f26..61ecab26 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -233,13 +233,15 @@ done: herr_t H5Dextend(hid_t dset_id, const hsize_t size[]) { - H5VL_object_t *vol_obj = NULL; /* Dataset structure */ - hid_t sid = H5I_INVALID_HID; /* Dataspace ID */ - H5S_t * ds = NULL; /* Dataspace struct */ - int ndims; /* Dataset/space rank */ - hsize_t dset_dims[H5S_MAX_RANK]; /* Current dataset dimensions */ - int i; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_dataset_get_args_t vol_get_cb_args; /* Arguments to VOL callback */ + H5VL_dataset_specific_args_t vol_spec_cb_args; /* Arguments to VOL callback */ + hid_t sid = H5I_INVALID_HID; /* Dataspace ID */ + H5S_t * ds = NULL; /* Dataspace struct */ + int ndims; /* Dataset/space rank */ + hsize_t dset_dims[H5S_MAX_RANK]; /* Current dataset dimensions */ + int i; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*h", dset_id, size); @@ -250,10 +252,14 @@ H5Dextend(hid_t dset_id, const hsize_t size[]) if (!size) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no size specified") + /* Set up VOL callback arguments */ + vol_get_cb_args.op_type = H5VL_DATASET_GET_SPACE; + vol_get_cb_args.args.get_space.space_id = H5I_INVALID_HID; + /* Get the dataspace pointer for the dataset */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &sid) < - 0) + if (H5VL_dataset_get(vol_obj, &vol_get_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get dataspace") + sid = vol_get_cb_args.args.get_space.space_id; if (H5I_INVALID_HID == sid) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "received an invalid dataspace from the dataset") if (NULL == (ds = (H5S_t *)H5I_object_verify(sid, H5I_DATASPACE))) @@ -281,9 +287,12 @@ H5Dextend(hid_t dset_id, const hsize_t size[]) if (H5CX_set_loc(dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_spec_cb_args.op_type = H5VL_DATASET_SET_EXTENT; + vol_spec_cb_args.args.set_extent.size = dset_dims; + /* Increase size */ - if ((ret_value = H5VL_dataset_specific(vol_obj, H5VL_DATASET_SET_EXTENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, dset_dims)) < 0) + if (H5VL_dataset_specific(vol_obj, &vol_spec_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to extend dataset") done: diff --git a/src/H5Dint.c b/src/H5Dint.c index 5e709db..a287ae8 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -2853,13 +2853,14 @@ H5D__vlen_get_buf_size_gen(H5VL_object_t *vol_obj, hid_t type_id, hid_t space_id { H5D_vlen_bufsize_generic_t vlen_bufsize = { NULL, H5I_INVALID_HID, NULL, H5I_INVALID_HID, H5I_INVALID_HID, {NULL, NULL, 0, 0}}; - H5P_genplist_t * dxpl = NULL; /* DXPL for operation */ - H5S_t * mspace = NULL; /* Memory dataspace */ - char bogus; /* Bogus value to pass to H5Diterate() */ - H5S_t * space; /* Dataspace for iteration */ - H5T_t * type; /* Datatype */ - H5S_sel_iter_op_t dset_op; /* Operator for iteration */ - herr_t ret_value = SUCCEED; /* Return value */ + H5P_genplist_t * dxpl = NULL; /* DXPL for operation */ + H5S_t * mspace = NULL; /* Memory dataspace */ + char bogus; /* Bogus value to pass to H5Diterate() */ + H5S_t * space; /* Dataspace for iteration */ + H5T_t * type; /* Datatype */ + H5S_sel_iter_op_t dset_op; /* Operator for iteration */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -2874,10 +2875,14 @@ H5D__vlen_get_buf_size_gen(H5VL_object_t *vol_obj, hid_t type_id, hid_t space_id /* Save the dataset */ vlen_bufsize.dset_vol_obj = vol_obj; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_SPACE; + vol_cb_args.args.get_space.space_id = H5I_INVALID_HID; + /* Get a copy of the dataset's dataspace */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &vlen_bufsize.fspace_id) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataspace") + vlen_bufsize.fspace_id = vol_cb_args.args.get_space.space_id; if (NULL == (vlen_bufsize.fspace = (H5S_t *)H5I_object(vlen_bufsize.fspace_id))) HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataspace") @@ -3943,7 +3948,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D__refresh(hid_t dset_id, H5D_t *dset) +H5D__refresh(H5D_t *dset, hid_t dset_id) { H5D_virtual_held_file_t *head = NULL; /* Pointer to list of files held open */ hbool_t virt_dsets_held = FALSE; /* Whether virtual datasets' files are held open */ @@ -3968,7 +3973,7 @@ H5D__refresh(hid_t dset_id, H5D_t *dset) } /* end if */ /* Refresh dataset object */ - if ((H5O_refresh_metadata(dset_id, dset->oloc)) < 0) + if ((H5O_refresh_metadata(&dset->oloc, dset_id)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to refresh dataset") done: diff --git a/src/H5Dio.c b/src/H5Dio.c index 03400cf..d1861c4 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -69,55 +69,6 @@ H5FL_BLK_DEFINE(type_conv); H5FL_DEFINE(H5D_chunk_map_t); /*------------------------------------------------------------------------- - * Function: H5D__get_offset_copy - * - * Purpose: Copies an offset buffer and performs bounds checks on the - * values. - * - * This helper function ensures that the offset buffer given - * by the user is suitable for use with the rest of the library. - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -herr_t -H5D__get_offset_copy(const H5D_t *dset, const hsize_t *offset, hsize_t *offset_copy) -{ - unsigned u; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(dset); - HDassert(offset); - HDassert(offset_copy); - - /* The library's chunking code requires the offset to terminate with a zero. - * So transfer the offset array to an internal offset array that we - * can properly terminate (handled via the calloc call). - */ - - HDmemset(offset_copy, 0, H5O_LAYOUT_NDIMS * sizeof(hsize_t)); - - for (u = 0; u < dset->shared->ndims; u++) { - /* Make sure the offset doesn't exceed the dataset's dimensions */ - if (offset[u] > dset->shared->curr_dims[u]) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "offset exceeds dimensions of dataset") - - /* Make sure the offset fall right on a chunk's boundary */ - if (offset[u] % dset->shared->layout.u.chunk.dim[u]) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "offset doesn't fall on chunks's boundary") - - offset_copy[u] = offset[u]; - } - -done: - FUNC_LEAVE_NOAPI(ret_value) - -} /* end H5D__get_offset_copy() */ - -/*------------------------------------------------------------------------- * Function: H5D__read * * Purpose: Reads (part of) a DATASET into application memory BUF. See @@ -161,12 +112,8 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t /* check args */ HDassert(dataset && dataset->oloc.file); - - if (!file_space) - file_space = dataset->shared->space; - if (!mem_space) - mem_space = file_space; - nelmts = H5S_GET_SELECT_NPOINTS(mem_space); + HDassert(file_space); + HDassert(mem_space); /* Set up datatype info for operation */ if (H5D__typeinfo_init(dataset, mem_type_id, FALSE, &type_info) < 0) @@ -189,11 +136,12 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t #endif /*H5_HAVE_PARALLEL*/ /* Make certain that the number of elements in each selection is the same */ + nelmts = H5S_GET_SELECT_NPOINTS(mem_space); if (nelmts != H5S_GET_SELECT_NPOINTS(file_space)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest dataspaces have different number of elements selected") - /* Check for a NULL buffer, after the H5S_ALL dataspace selection has been handled */ + /* Check for a NULL buffer */ if (NULL == buf) { /* Check for any elements selected (which is invalid) */ if (nelmts > 0) @@ -225,7 +173,7 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t * Note that in general, this requires us to touch up the memory buffer as * well. */ - if (TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && + if (nelmts > 0 && TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ /* to the beginning of the projected mem space. */ @@ -377,6 +325,8 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_ /* check args */ HDassert(dataset && dataset->oloc.file); + HDassert(file_space); + HDassert(mem_space); /* All filters in the DCPL must have encoding enabled. */ if (!dataset->shared->checked_filters) { @@ -418,20 +368,13 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_ } /* end else */ #endif /*H5_HAVE_PARALLEL*/ - /* Initialize dataspace information */ - if (!file_space) - file_space = dataset->shared->space; - if (!mem_space) - mem_space = file_space; - - nelmts = H5S_GET_SELECT_NPOINTS(mem_space); - /* Make certain that the number of elements in each selection is the same */ + nelmts = H5S_GET_SELECT_NPOINTS(mem_space); if (nelmts != H5S_GET_SELECT_NPOINTS(file_space)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest dataspaces have different number of elements selected") - /* Check for a NULL buffer, after the H5S_ALL dataspace selection has been handled */ + /* Check for a NULL buffer */ if (NULL == buf) { /* Check for any elements selected (which is invalid) */ if (nelmts > 0) @@ -463,7 +406,7 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_ * Note that in general, this requires us to touch up the memory buffer * as well. */ - if (TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && + if (nelmts > 0 && TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { const void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ /* to the beginning of the projected mem space. */ @@ -867,11 +810,19 @@ H5D__ioinfo_adjust(H5D_io_info_t *io_info, const H5D_t *dset, const H5S_t *file_ io_info->io_ops.single_write = H5D__mpio_select_write; } /* end if */ else { + int comm_size = 0; + + /* Retrieve size of MPI communicator used for file */ + if ((comm_size = H5F_shared_mpi_get_size(io_info->f_sh)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MPI communicator size") + /* Check if there are any filters in the pipeline. If there are, - * we cannot break to independent I/O if this is a write operation; - * otherwise there will be metadata inconsistencies in the file. + * we cannot break to independent I/O if this is a write operation + * with multiple ranks involved; otherwise, there will be metadata + * inconsistencies in the file. */ - if (io_info->op_type == H5D_IO_OP_WRITE && io_info->dset->shared->dcpl_cache.pline.nused > 0) { + if (comm_size > 1 && io_info->op_type == H5D_IO_OP_WRITE && + io_info->dset->shared->dcpl_cache.pline.nused > 0) { H5D_mpio_no_collective_cause_t cause; uint32_t local_no_collective_cause; uint32_t global_no_collective_cause; diff --git a/src/H5Dmodule.h b/src/H5Dmodule.h index 595c714..596fd48 100644 --- a/src/H5Dmodule.h +++ b/src/H5Dmodule.h @@ -44,18 +44,18 @@ * <tr><th>Create</th><th>Read</th></tr> * <tr valign="top"> * <td> - * \snippet H5D_examples.c create + * \snippet{lineno} H5D_examples.c create * </td> * <td> - * \snippet H5D_examples.c read + * \snippet{lineno} H5D_examples.c read * </td> * <tr><th>Update</th><th>Delete</th></tr> * <tr valign="top"> * <td> - * \snippet H5D_examples.c update + * \snippet{lineno} H5D_examples.c update * </td> * <td> - * \snippet H5D_examples.c delete + * \snippet{lineno} H5D_examples.c delete * </td> * </tr> * </table> diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 972a67b..92ea120 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -576,7 +576,7 @@ H5_DLL herr_t H5D__flush_sieve_buf(H5D_t *dataset); H5_DLL herr_t H5D__flush_real(H5D_t *dataset); H5_DLL herr_t H5D__flush(H5D_t *dset, hid_t dset_id); H5_DLL herr_t H5D__mark(const H5D_t *dataset, unsigned flags); -H5_DLL herr_t H5D__refresh(hid_t dset_id, H5D_t *dataset); +H5_DLL herr_t H5D__refresh(H5D_t *dataset, hid_t dset_id); /* To convert a dataset's chunk indexing type to v1 B-tree */ H5_DLL herr_t H5D__format_convert(H5D_t *dataset); @@ -651,7 +651,7 @@ H5_DLL herr_t H5D__chunk_copy(H5F_t *f_src, H5O_storage_chunk_t *storage_src, H5 H5_DLL herr_t H5D__chunk_bh_info(const H5O_loc_t *loc, H5O_t *oh, H5O_layout_t *layout, hsize_t *btree_size); H5_DLL herr_t H5D__chunk_dump_index(H5D_t *dset, FILE *stream); H5_DLL herr_t H5D__chunk_delete(H5F_t *f, H5O_t *oh, H5O_storage_t *store); -H5_DLL herr_t H5D__get_offset_copy(const H5D_t *dset, const hsize_t *offset, hsize_t *offset_copy); +H5_DLL herr_t H5D__chunk_get_offset_copy(const H5D_t *dset, const hsize_t *offset, hsize_t *offset_copy); H5_DLL herr_t H5D__chunk_direct_write(const H5D_t *dset, uint32_t filters, hsize_t *offset, uint32_t data_size, const void *buf); H5_DLL herr_t H5D__chunk_direct_read(const H5D_t *dset, hsize_t *offset, uint32_t *filters, void *buf); diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 0b5fac6..c496414 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -32,7 +32,9 @@ #define H5D_CHUNK_CACHE_NBYTES_DEFAULT SIZE_MAX #define H5D_CHUNK_CACHE_W0_DEFAULT (-1.0) -/* Bit flags for the H5Pset_chunk_opts() and H5Pget_chunk_opts() */ +/** + * Bit flags for the H5Pset_chunk_opts() and H5Pget_chunk_opts() + */ #define H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS (0x0002u) /*******************/ @@ -44,13 +46,12 @@ * Values for the H5D_LAYOUT property */ typedef enum H5D_layout_t { - H5D_LAYOUT_ERROR = -1, - - H5D_COMPACT = 0, /**< raw data is very small */ - H5D_CONTIGUOUS = 1, /**< the default */ - H5D_CHUNKED = 2, /**< slow and fancy */ - H5D_VIRTUAL = 3, /**< actual data is stored in other datasets */ - H5D_NLAYOUTS = 4 /**< this one must be last! */ + H5D_LAYOUT_ERROR = -1, /**< error */ + H5D_COMPACT = 0, /**< raw data is small (< 64KB) */ + H5D_CONTIGUOUS = 1, /**< contiguous layout */ + H5D_CHUNKED = 2, /**< chunked or tiled layout */ + H5D_VIRTUAL = 3, /**< actual data is stored in other datasets */ + H5D_NLAYOUTS = 4 /**< this one must be last! */ } H5D_layout_t; //! <!-- [H5D_layout_t_snip] --> @@ -75,11 +76,11 @@ typedef enum H5D_chunk_index_t { * Values for the space allocation time property */ typedef enum H5D_alloc_time_t { - H5D_ALLOC_TIME_ERROR = -1, - H5D_ALLOC_TIME_DEFAULT = 0, - H5D_ALLOC_TIME_EARLY = 1, - H5D_ALLOC_TIME_LATE = 2, - H5D_ALLOC_TIME_INCR = 3 + H5D_ALLOC_TIME_ERROR = -1, /**< Error */ + H5D_ALLOC_TIME_DEFAULT = 0, /**< \todo Define this! */ + H5D_ALLOC_TIME_EARLY = 1, /**< Allocate on creation */ + H5D_ALLOC_TIME_LATE = 2, /**< Allocate on first write */ + H5D_ALLOC_TIME_INCR = 3 /**< Allocate incrementally (by chunk) */ } H5D_alloc_time_t; //! <!-- [H5D_alloc_time_t_snip] --> @@ -88,10 +89,11 @@ typedef enum H5D_alloc_time_t { * Values for the status of space allocation */ typedef enum H5D_space_status_t { - H5D_SPACE_STATUS_ERROR = -1, - H5D_SPACE_STATUS_NOT_ALLOCATED = 0, - H5D_SPACE_STATUS_PART_ALLOCATED = 1, - H5D_SPACE_STATUS_ALLOCATED = 2 + H5D_SPACE_STATUS_ERROR = -1, /**< Error */ + H5D_SPACE_STATUS_NOT_ALLOCATED = 0, /**< Space has not been allocated for this dataset. */ + H5D_SPACE_STATUS_PART_ALLOCATED = 1, /**< Space has been allocated for this dataset. */ + H5D_SPACE_STATUS_ALLOCATED = 2 /**< Space has been partially allocated for this dataset. (Used only for + datasets with chunked storage.) */ } H5D_space_status_t; //! <!-- [H5D_space_status_t_snip] --> @@ -100,10 +102,10 @@ typedef enum H5D_space_status_t { * Values for time of writing fill value property */ typedef enum H5D_fill_time_t { - H5D_FILL_TIME_ERROR = -1, - H5D_FILL_TIME_ALLOC = 0, - H5D_FILL_TIME_NEVER = 1, - H5D_FILL_TIME_IFSET = 2 + H5D_FILL_TIME_ERROR = -1, /**< Error */ + H5D_FILL_TIME_ALLOC = 0, /**< Fill on allocation */ + H5D_FILL_TIME_NEVER = 1, /**< Never write fill values */ + H5D_FILL_TIME_IFSET = 2 /**< Fill if fill-value was set */ } H5D_fill_time_t; //! <!-- [H5D_fill_time_t_snip] --> @@ -112,10 +114,10 @@ typedef enum H5D_fill_time_t { * Values for fill value status */ typedef enum H5D_fill_value_t { - H5D_FILL_VALUE_ERROR = -1, - H5D_FILL_VALUE_UNDEFINED = 0, - H5D_FILL_VALUE_DEFAULT = 1, - H5D_FILL_VALUE_USER_DEFINED = 2 + H5D_FILL_VALUE_ERROR = -1, /**< Error */ + H5D_FILL_VALUE_UNDEFINED = 0, /**< No fill value defined */ + H5D_FILL_VALUE_DEFAULT = 1, /**< Default fill-value */ + H5D_FILL_VALUE_USER_DEFINED = 2 /**< User-defined fill-value */ } H5D_fill_value_t; //! <!-- [H5D_fill_value_t_snip] --> @@ -124,22 +126,40 @@ typedef enum H5D_fill_value_t { * Values for VDS bounds option */ typedef enum H5D_vds_view_t { - H5D_VDS_ERROR = -1, - H5D_VDS_FIRST_MISSING = 0, - H5D_VDS_LAST_AVAILABLE = 1 + H5D_VDS_ERROR = -1, /**< Error */ + H5D_VDS_FIRST_MISSING = 0, /**< \todo Define this! */ + H5D_VDS_LAST_AVAILABLE = 1 /**< \todo Define this! */ } H5D_vds_view_t; //! <!-- [H5D_vds_view_t_snip] --> //! <!-- [H5D_append_cb_t_snip] --> /** - * Callback for H5Pset_append_flush() in a dataset access property list + * \brief Callback for H5Pset_append_flush() + * + * \dset_id{dataset_id} + * \param[in] cur_dims The current extent of the dataset's dimensions + * \param[in,out] op_data User context + * + * \return \herr_t + * */ typedef herr_t (*H5D_append_cb_t)(hid_t dataset_id, hsize_t *cur_dims, void *op_data); //! <!-- [H5D_append_cb_t_snip] --> //! <!-- [H5D_operator_t_snip] --> /** - * Define the operator function pointer for H5Diterate() + * \brief Callback for H5Diterate() + * + * \param[in,out] elem Pointer to the memory buffer containing the current dataset + * element + * \param[in] type_id Datatype identifier of the elements stored in \p elem + * \param[in] ndim Number of dimensions for the \p point array + * \param[in] point Array containing the location of the element within + * the original dataspace + * \param[in,out] operator_data Pointer to any user-defined data associated with + * the operation + * \return \herr_t_iter + * */ typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, unsigned ndim, const hsize_t *point, void *operator_data); @@ -147,7 +167,29 @@ typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, unsigned ndim, const //! <!-- [H5D_scatter_func_t_snip] --> /** - * Define the operator function pointer for H5Dscatter() + * \brief Callback for H5Dscatter() + * + * \param[out] src_buf Pointer to the buffer holding the next set of elements to + * scatter. On entry, the value of where \p src_buf points to + * is undefined. The callback function should set \p src_buf + * to point to the next set of elements. + * \param[out] src_buf_bytes_used Pointer to the number of valid bytes in \p src_buf. + * On entry, the value where \p src_buf_bytes_used points + * to is undefined. The callback function should set + * \p src_buf_bytes_used to the of valid bytes in \p src_buf. + * This number must be a multiple of the datatype size. + * \param[in,out] op_data User-defined pointer to data required by the callback + * function. A pass-through of the \p op_data pointer provided + * with the H5Dscatter() function call. + * \return herr_t + * + * \details The callback function should always return at least one + * element in \p src_buf, and must not return more elements + * than are remaining to be scattered. This function will be + * repeatedly called until all elements to be scattered have + * been returned. The callback function should return zero (0) + * to indicate success, and a negative value to indicate failure. + * */ typedef herr_t (*H5D_scatter_func_t)(const void **src_buf /*out*/, size_t *src_buf_bytes_used /*out*/, void *op_data); @@ -155,18 +197,51 @@ typedef herr_t (*H5D_scatter_func_t)(const void **src_buf /*out*/, size_t *src_b //! <!-- [H5D_gather_func_t_snip] --> /** - * Define the operator function pointer for H5Dgather() + * \brief Callback for H5Dgather() + * + * \param[in] dst_buf Pointer to the destination buffer which has been filled + * with the next set of elements gathered. This will always + * be identical to the \p dst_buf passed to H5Dgather() + * \param[in] dst_buf_bytes_used Pointer to the number of valid bytes in + * \p dst_buf. This number must be a multiple of + * the datatype size. + * \param[in,out] op_data User-defined pointer to data required by the callback + * function; a pass-through of the \p op_data pointer + * provided with the H5Dgather() function call. + * \returns \herr_t + * + * \details The callback function should process, store, or otherwise make use + * of the data returned in dst_buf before it returns, because the + * buffer will be overwritten unless it is the last call to the + * callback. This function will be repeatedly called until all gathered + * elements have been passed to the callback in dst_buf. The callback + * function should return zero (0) to indicate success, and a negative + * value to indicate failure. + * */ typedef herr_t (*H5D_gather_func_t)(const void *dst_buf, size_t dst_buf_bytes_used, void *op_data); //! <!-- [H5D_gather_func_t_snip] --> //! <!-- [H5D_chunk_iter_op_t_snip] --> /** - * Define the operator function pointer for H5Dchunk_iter() + * \brief Callback for H5Dchunk_iter() + * + * \param[in] offset Array of starting logical coordinates of chunk. + * \param[in] filter_mask Filter mask of chunk. + * \param[in] addr Offset in file of chunk data. + * \param[in] nbytes Size in bytes of chunk data in file. + * \param[in,out] op_data Pointer to any user-defined data associated with + * the operation. + * \returns \li Zero (#H5_ITER_CONT) causes the iterator to continue, returning + * zero when all elements have been processed. + * \li A positive value (#H5_ITER_STOP) causes the iterator to + * immediately return that value, indicating short-circuit success. + * \li A negative (#H5_ITER_ERROR) causes the iterator to immediately + * return that value, indicating failure. */ -//! <!-- [H5D_chunk_iter_op_t_snip] --> typedef int (*H5D_chunk_iter_op_t)(const hsize_t *offset, uint32_t filter_mask, haddr_t addr, uint32_t nbytes, void *op_data); +//! <!-- [H5D_chunk_iter_op_t_snip] --> /********************/ /* Public Variables */ @@ -186,7 +261,7 @@ extern "C" { * \brief Creates a new dataset and links it into the file * * \fgdta_loc_id - * \param[in] name Name of the dataset to create + * \param[in] name Name of the dataset to create * \type_id * \space_id * \lcpl_id @@ -211,13 +286,6 @@ extern "C" { * \p name may be either an absolute path in the file or a relative * path from \p loc_id naming the dataset. * - * \p dtype_id specifies the datatype of each data element as stored - * in the file. If \p dtype_id is either a fixed-length or - * variable-length string, it is important to set the string length - * when defining the datatype. String datatypes are derived from - * #H5T_C_S1 (or #H5T_FORTRAN_S1 for Fortran codes), which defaults - * to 1 character in size. - * * If \p dtype_id is a committed datatype, and if the file location * associated with the committed datatype is different from the * file location where the dataset will be created, the datatype @@ -225,7 +293,7 @@ extern "C" { * * The link creation property list, \p lcpl_id, governs creation * of the link(s) by which the new dataset is accessed and the - * creation of any * intermediate groups that may be missing. + * creation of any intermediate groups that may be missing. * * The datatype and dataspace properties and the dataset creation * and access property lists are attached to the dataset, so the @@ -236,8 +304,8 @@ extern "C" { * not previously written, the HDF5 library will return default * or user-defined fill values. * - * To conserve and release resources, the dataset should be closed - * when access is no longer required. + * \par Example + * \snippet H5D_examples.c create * * \since 1.8.0 * @@ -285,34 +353,14 @@ H5_DLL hid_t H5Dcreate_async(const char *app_file, const char *app_func, unsigne * the file, which may differ from the datatype and dataspace * in application memory. * - * Dataset creation property list and dataset access creation - * property list are specified by \p dcpl_id and \p dapl_id. - * * H5Dcreate_anon() returns a new dataset identifier. Using * this identifier, the new dataset must be linked into the * HDF5 file structure with H5Olink() or it will be deleted - * from the file when the file is closed. - * - * See H5Dcreate2() for further details and considerations on - * the use of H5Dcreate2() and H5Dcreate_anon(). - * - * The differences between this function and H5Dcreate2() are - * as follows: - * \li H5Dcreate_anon() explicitly includes a dataset access property - * list. H5Dcreate() always uses default dataset access properties. - * - * \li H5Dcreate_anon() neither provides the new dataset’s name nor - * links it into the HDF5 file structure; those actions must be - * performed separately through a call to H5Olink(), which offers - * greater control over linking. - * - * A dataset created with this function should be closed with - * H5Dclose() when the dataset is no longer needed so that resource - * leaks will not develop. + * when the file is closed. * * \since 1.8.0 * - * \see H5Olink(), H5Dcreate(), Using Identifiers + * \see H5Olink(), H5Dcreate() * */ H5_DLL hid_t H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, hid_t dapl_id); @@ -338,12 +386,6 @@ H5_DLL hid_t H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t d * specified then the dataset will be opened at the location * where the attribute, dataset, or named datatype is attached. * - * The dataset access property list, \p dapl_id, provides - * information regarding access to the dataset. - * - * To conserve and release resources, the dataset should be closed - * when access is no longer required. - * * \since 1.8.0 * * \see H5Dcreate2(), H5Dclose() @@ -377,6 +419,9 @@ H5_DLL hid_t H5Dopen_async(const char *app_file, const char *app_func, unsigned * be released with H5Sclose() when the identifier is no longer * needed so that resource leaks will not occur. * + * \par Example + * \snippet H5D_examples.c update + * * \see H5Sclose() * */ @@ -393,7 +438,19 @@ H5_DLL hid_t H5Dget_space_async(const char *app_file, const char *app_func, unsi /** * -------------------------------------------------------------------------- * \ingroup H5D - * \todo Document this function! + * + * \brief Determines whether space has been allocated for a dataset + * + * \dset_id + * \param[out] allocation Space allocation status + * + * \return \herr_t + * + * \details H5Dget_space_status() determines whether space has been allocated + * for the dataset \p dset_id. + * + * \since 1.6.0 + * */ H5_DLL herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation); @@ -412,27 +469,7 @@ H5_DLL herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation) * * If a dataset has a named datatype, then an identifier to the * opened datatype is returned. Otherwise, the returned datatype - * is read-only. If atomization of the datatype fails, then the - * datatype is closed. - * - * A datatype identifier returned from this function should be - * released with H5Tclose() when the identifier is no longer - * needed to prevent resource leaks. - * - * \note Datatype Identifiers - * - * Please note that the datatype identifier is actually an object - * identifier or a handle returned from opening the datatype. It - * is not persistent and its value can be different from one HDF5 - * session to the next. - * - * H5Tequal() can be used to compare datatypes. - * - * HDF5 High Level APIs that may also be of interest are: - * - * H5LTdtype_to_text() creates a text description of a - * datatype. H5LTtext_to_dtype() creates an HDF5 datatype - * given a text description. + * is read-only. * */ H5_DLL hid_t H5Dget_type(hid_t dset_id); @@ -452,9 +489,6 @@ H5_DLL hid_t H5Dget_type(hid_t dset_id); * a copy of the dataset creation property list associated with * the dataset specified by \p dset_id. * - * The creation property list identifier should be released - * with H5Pclose() to prevent resource leaks. - * */ H5_DLL hid_t H5Dget_create_plist(hid_t dset_id); @@ -488,10 +522,6 @@ H5_DLL hid_t H5Dget_create_plist(hid_t dset_id); * All link access properties in the returned list will be set * to the default values. * - * The access property list identifier should be released with - * H5Pclose() when the identifier is no longer needed so that - * resource leaks will not develop. - * * \since 1.8.3 * */ @@ -510,11 +540,8 @@ H5_DLL hid_t H5Dget_access_plist(hid_t dset_id); * \details H5Dget_storage_size() returns the amount of storage, * in bytes, that is allocated in the file for the raw data of * the dataset specified by \p dset_id. - * - * \note The amount of storage in this case is the storage - * allocated in the written file, which will typically differ - * from the space required to hold a dataset in working memory. - * + * H5Dget_storage_size() reports only the space required to store + * the dataset elements, excluding any metadata. * \li For contiguous datasets, the returned size equals the current * allocated size of the raw data. * \li For unfiltered chunked datasets, the returned size is the @@ -524,21 +551,19 @@ H5_DLL hid_t H5Dget_access_plist(hid_t dset_id); * compression filter is in use, H5Dget_storage_size() will return * the total space required to store the compressed chunks. * - * H5Dget_storage_size() reports only the space required to store - * the data, not including that of any metadata. + * \note Note that H5Dget_storage_size() is not generally an + * appropriate function to use when determining the amount + * of memory required to work with a dataset. In such + * circumstances, you must determine the number of data + * points in a dataset and the size of an individual dataset + * element. H5Sget_simple_extent_npoints() and H5Tget_size() + * can be used to calculate that amount. * - * \attention H5Dget_storage_size() does not differentiate between 0 (zero), + * \warning H5Dget_storage_size() does not differentiate between 0 (zero), * the value returned for the storage size of a dataset * with no stored values, and 0 (zero), the value returned to * indicate an error. * - * \note Note that H5Dget_storage_size() is not generally an - * appropriate function to use when determining the amount - * of memory required to work with a dataset. In such - * circumstances, you must determine the number of data - * points in a dataset and the size of an individual data - * element. H5Sget_simple_extent_npoints() and H5Tget_size() - * can be used to get that information. * */ H5_DLL hsize_t H5Dget_storage_size(hid_t dset_id); @@ -595,7 +620,7 @@ H5_DLL herr_t H5Dget_chunk_storage_size(hid_t dset_id, const hsize_t *offset, hs * effect. Also, the implementation does not handle the #H5S_ALL * macro correctly. As a workaround, application can get * the dataspace for the dataset using H5Dget_space() and pass that - * in for \p fspace_id. This will be fixed in coming releases. + * in for \p fspace_id. This will be fixed in a future release. * * \since 1.10.5 * @@ -638,9 +663,10 @@ H5_DLL herr_t H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, u * -------------------------------------------------------------------------- * \ingroup H5D * - * \brief Iterate over all chunks + * \brief Iterate over all chunks of a chunked dataset * * \dset_id + * \param[in] dxpl_id Identifier of a transfer property list * \param[in] cb User callback function, called for every chunk. * \param[in] op_data User-defined pointer to data required by op * @@ -648,36 +674,19 @@ H5_DLL herr_t H5Dget_chunk_info_by_coord(hid_t dset_id, const hsize_t *offset, u * * \details H5Dget_chunk_iter iterates over all chunks in the dataset, calling the * user supplied callback with the details of the chunk and the supplied - * \p op_data. - * - * Callback information: - * H5D_chunk_iter_op_t is defined as: - * - * typedef int (*H5D_chunk_iter_op_t)( - * const hsize_t *offset, - * uint32_t filter_mask, - * haddr_t addr, - * uint32_t nbytes, - * void *op_data); - * - * H5D_chunk_iter_op_t parameters: - * hsize_t *offset; IN/OUT: Array of starting logical coordinates of chunk. - * uint32_t filter_mask; IN: Filter mask of chunk. - * haddr_t addr; IN: Offset in file of chunk data. - * uint32_t nbytes; IN: Size in number of bytes of chunk data in file. - * void *op_data; IN/OUT: Pointer to any user-defined data - * associated with the operation. - * - * The return values from an operator are: - * Zero (H5_ITER_CONT) causes the iterator to continue, returning zero when all - * elements have been processed. - * Positive (H5_ITER_STOP) causes the iterator to immediately return that positive - * value, indicating short-circuit success. - * Negative (H5_ITER_ERROR) causes the iterator to immediately return that value, - * indicating failure. + * context \p op_data. + * + * \par Example + * For each chunk, print the allocated chunk size (0 for un-allocated chunks). + * \snippet H5D_examples.c H5Dchunk_iter_cb + * Iterate over all chunked datasets and chunks in a file. + * \snippet H5D_examples.c H5Ovisit_cb + * + * \version 1.?.? + * \todo When was this function introduced? * */ -H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, H5D_chunk_iter_op_t cb, void *op_data); +H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, hid_t dxpl_id, H5D_chunk_iter_op_t cb, void *op_data); /** * -------------------------------------------------------------------------- @@ -695,16 +704,16 @@ H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, H5D_chunk_iter_op_t cb, void *op_data * * \return \herr_t * - * \details H5Dget_chunk_info() retrieves the offset coordinates - * offset, filter mask filter_mask, size size and address addr for - * the dataset specified by the identifier dset_id and the chunk - * specified by the index index. The chunk belongs to a set of - * chunks in the selection specified by fspace_id. If the queried + * \details H5Dget_chunk_info() retrieves the offset coordinates, + * \p offset, filter mask, \p filter_mask, size, \p size, and address + * \p addr for the dataset specified by the identifier \p dset_id and the chunk + * specified by the index \p index. The chunk belongs to a set of + * chunks in the selection specified by \p fspace_id. If the queried * chunk does not exist in the file, the size will be set to 0 and - * address to \c HADDR_UNDEF. The value pointed to by filter_mask will - * not be modified. NULL can be passed in for any \p out parameters. + * address to #HADDR_UNDEF. The value pointed to by filter_mask will + * not be modified. \c NULL can be passed in for any \p out parameters. * - * \p chk_idx is the chunk index in the selection. Index value + * \p chk_idx is the chunk index in the selection. The index value * may have a value of 0 up to the number of chunks stored in * the file that have a nonempty intersection with the file * dataspace selection @@ -718,9 +727,9 @@ H5_DLL herr_t H5Dchunk_iter(hid_t dset_id, H5D_chunk_iter_op_t cb, void *op_data * \note Please be aware that this function currently does not * support non-trivial selections, thus \p fspace_id has no * effect. Also, the implementation does not handle the #H5S_ALL - * macro correctly. As a workaround, application can get + * macro correctly. As a workaround, an application can get * the dataspace for the dataset using H5Dget_space() and pass that - * in for \p fspace_id. This will be fixed in coming releases. + * in for \p fspace_id. This will be fixed in a future release. * * \since 1.10.5 * @@ -736,7 +745,7 @@ H5_DLL herr_t H5Dget_chunk_info(hid_t dset_id, hid_t fspace_id, hsize_t chk_idx, * * \dset_id * - * \return Returns the offset in bytes; otherwise, returns \c HADDR_UNDEF, + * \return Returns the offset in bytes; otherwise, returns #HADDR_UNDEF, * a negative value. * * \details H5Dget_offset() returns the address in the file of @@ -785,9 +794,8 @@ H5_DLL haddr_t H5Dget_offset(hid_t dset_id); * used for the memory dataspace and the selection defined with \p * file_space_id is used for the selection within that dataspace. * - * If raw data storage space has not been allocated for the dataset - * and a fill value has been defined, the returned buffer \p buf - * is filled with the fill value. + * The number of elements selected in the memory dataspace \Emph{must} + * be equal to the number of elements selected in the file dataspace. * * The behavior of the library for the various combinations of * valid dataspace identifiers and #H5S_ALL for the \p mem_space_id @@ -832,14 +840,12 @@ H5_DLL haddr_t H5Dget_offset(hid_t dset_id); * </tr> * </table> * - * \details Setting an #H5S_ALL selection indicates that the entire - * dataspace, as defined by the current dimensions of a dataspace, - * will be selected. The number of elements selected in the memory - * dataspace must match the number of elements selected in the - * file dataspace. + * \note If no storage space was allocated for the dataset + * and a fill value is defined, the returned buffer \p buf + * is filled with the fill value. * - * \p dxpl_id can be the constant #H5P_DEFAULT, in which case the - * default data transfer properties are used. + * \par Example + * \snippet H5D_examples.c read * */ H5_DLL herr_t H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, @@ -952,6 +958,8 @@ H5_DLL herr_t H5Dread_async(const char *app_file, const char *app_func, unsigned * time if the dataset's fill time is set to #H5D_FILL_TIME_IFSET * or #H5D_FILL_TIME_ALLOC. * + * \par_compr_note + * * \attention If a dataset's storage layout is 'compact', care must be * taken when writing data to the dataset in parallel. A compact * dataset's raw data is cached in memory and may be flushed @@ -959,6 +967,9 @@ H5_DLL herr_t H5Dread_async(const char *app_file, const char *app_func, unsigned * applications should always attempt to write identical data to * the dataset from all processes. * + * \par Example + * \snippet H5D_examples.c update + * * \see H5Pset_fill_time(), H5Pset_alloc_time() * */ @@ -999,11 +1010,6 @@ H5_DLL herr_t H5Dwrite_async(const char *app_file, const char *app_func, unsigne * pipeline, including filters, and will be written directly to * the file. Only one chunk can be written with this function. * - * H5Dwrite_chunk() replaces the now deprecated H5DOwrite_chunk() - * function, which was located in the high level optimization - * library. The parameters and behavior are identical to the - * original. - * * \p filters is a mask providing a record of which filters are * used with the the chunk. The default value of the mask is * zero (0), indicating that all enabled filters are applied. A @@ -1031,11 +1037,10 @@ H5_DLL herr_t H5Dwrite_async(const char *app_file, const char *app_func, unsigne * in a file. H5Dwrite_chunk() bypasses hyperslab selection, the * conversion of data from one datatype to another, and the filter * pipeline to write the chunk. Developers should have experience - * with these processes before using this function. Please see - * Using the Direct Chunk Write Function for more information. + * with these processes before using this function. * - * \note H5Dread_chunk() and H5Dwrite_chunk() are not supported under - * parallel and do not support variable length types. + * \note H5Dread_chunk() and H5Dwrite_chunk() are currently not supported + * with parallel HDF5 and do not support variable-length types. * * \since 1.10.2 * @@ -1073,10 +1078,10 @@ H5_DLL herr_t H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, con * the dimension limits and must specify a point that falls on * a dataset chunk boundary. * - * The mask \p filters indicates which filters are used with the - * chunk when written. A zero value indicates that all enabled - * filters are applied on the chunk. A filter is skipped if the - * bit corresponding to the filter’s position in the pipeline + * The mask \p filters indicates which filters were used when the + * chunk was written. A zero value (all bits 0) indicates that all + * enabled filters are applied on the chunk. A filter is skipped if + * the bit corresponding to the filter’s position in the pipeline * (0 ≤ position < 32) is turned on. * * \p buf is the memory buffer containing the chunk read from @@ -1090,8 +1095,8 @@ H5_DLL herr_t H5Dwrite_chunk(hid_t dset_id, hid_t dxpl_id, uint32_t filters, con * with these processes before using this function. Please see * Using the Direct Chunk Write Function for more information. * - * \note H5Dread_chunk() and H5Dwrite_chunk() are not supported under - * parallel and do not support variable length types. + * \note H5Dread_chunk() and H5Dwrite_chunk() are currently not supported + * with parallel HDF5 and do not support variable-length datatypes. * * \since 1.10.2 * @@ -1121,52 +1126,9 @@ H5_DLL herr_t H5Dread_chunk(hid_t dset_id, hid_t dxpl_id, const hsize_t *offset, * in the memory buffer \p buf, executing the callback function * \p op once for each such data element. * - * The prototype of the callback function \p op is as follows - * (as defined in the source code file H5Lpublic.h): - * \snippet this H5D_operator_t_snip - * The parameters of this callback function are: - * - * <table> - * <tr><td>\c elem</td> - * <td><tt>[in,out]</tt></td> - * <td>Pointer to the memory buffer containing the current - * data element</td></tr> - * <tr><td>\c type_id</td> - * <td><tt>[in]</tt></td> - * <td>Datatype identifier of the elements stored in elem</td></tr> - * <tr><td>\c ndim</td> - * <td><tt>[in]</tt></td> - * <td>Number of dimensions for the point array</td></tr> - * <tr><td>\c point</td> - * <td><tt>[in]</tt></td> - * <td>Array containing the location of the element within - * the original dataspace</td></tr> - * <tr><td>\c operator_data</td> - * <td><tt>[in,out]</tt></td> - * <td>Pointer to any user-defined data associated with the - * operation</td></tr> - * </table> - * - * The possible return values from the callback function, and - * the effect ofeach,are as follows: - * - * \li Zero causes the iterator to continue, returning zero - * when all data elements have been processed. - * \li A positive value causes the iterator to immediately - * return that positive value, indicating short-circuit success. - * \li A negative value causes the iterator to immediately return - * that value, indicating failure. - * - * The \p operator_data parameter is a user-defined pointer to - * the data required to process dataset elements in the course - * of the iteration. If operator needs to pass data back to the - * application, such data can be returned in this same buffer. This - * pointer is passed back to each step of the iteration in the - * operator callback function’s operator_data parameter. - * - * Unlike other HDF5 iterators, this iteration operation cannot - * be restarted at the point of exit; a second H5Diterate() - * call will always restart at the beginning. + * \attention Unlike other HDF5 iterators, this iteration operation cannot + * be restarted at the point of exit; a second H5Diterate() + * call will always restart at the beginning. * * * \since 1.10.2 @@ -1216,30 +1178,25 @@ H5_DLL herr_t H5Dvlen_get_buf_size(hid_t dset_id, hid_t type_id, hid_t space_id, * * \return \herr_t * - * \details H5Dfill() fills the dataspace selection in memory, \p space_id, + * \details H5Dfill() fills the dataspace selection, \p space_id, in memory * with the fill value specified in \p fill. If \p fill is NULL, * a fill value of 0 (zero) is used. * * \p fill_type_id specifies the datatype of the fill value. - * \p buf specifies the buffer in which the dataspace elements - * will be written. - * \p buf_type_id specifies the datatype of those data elements. + * \p buf specifies the buffer in which the fill elements + * will be written. \p buf_type_id specifies the datatype of + * those data elements. * * \note Note that if the fill value datatype differs from the memory - * buffer datatype, the fill value will be converted to the memory - * buffer datatype before filling the selection. + * buffer datatype, the fill value will be converted to the memory + * buffer datatype before filling the selection. * * \note Applications sometimes write data only to portions of an - * allocated dataset. It is often useful in such cases to fill - * the unused space with a known fill value. See the following - * function for more information: - * - H5Pset_fill_value() - * - H5Pget_fill_value() - * - H5Pfill_value_defined() - * - H5Pset_fill_time() - * - H5Pget_fill_time() - * - H5Pcreate() - * - H5Pcreate_anon() + * allocated dataset. It is often useful in such cases to fill + * the unused space with a known fill value. + * + * \see H5Pset_fill_value(), H5Pget_fill_value(), H5Pfill_value_defined(), + * H5Pset_fill_time(), H5Pget_fill_time(), H5Pcreate(), H5Dcreate_anon() * */ H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf_type_id, hid_t space_id); @@ -1286,22 +1243,21 @@ H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf * - If the dataset’s fill time is set to #H5D_FILL_TIME_ALLOC * (see H5Pset_alloc_time()) * - * \note - * \li If the sizes specified in \p size array are smaller than - * the dataset’s current dimension sizes, H5Dset_extent() will reduce - * the dataset’s dimension sizes to the specified values. It is the - * user application’s responsibility to ensure that valuable data is - * not lost as H5Dset_extent() does not check. + * \note If the sizes specified in \p size array are smaller than the dataset’s + * current dimension sizes, H5Dset_extent() will reduce the dataset’s + * dimension sizes to the specified values. It is the user application’s + * responsibility to ensure that valuable data is not lost as + * H5Dset_extent() does not check. * - * \li Except for external datasets, H5Dset_extent() is for use with - * chunked datasets only, not contiguous datasets. + * \note Except for external datasets, H5Dset_extent() is for use with + * chunked datasets only, not contiguous datasets. * - * \li A call to H5Dset_extent() affects the dataspace of a dataset. - * If a dataspace handle was opened for a dataset prior to a call to - * H5Dset_extent() then that dataspace handle will no longer reflect - * the correct dataspace extent of the dataset. H5Dget_space() must - * be called (after closing the previous handle) to obtain the current - * dataspace extent. + * \note A call to H5Dset_extent() affects the dataspace of a dataset. If a + * dataspace handle was opened for a dataset prior to a call to + * H5Dset_extent() then that dataspace handle will no longer reflect the + * correct dataspace extent of the dataset. H5Dget_space() must be called + * (after closing the previous handle) to obtain the current dataspace + * extent. * * \since 1.8.0 * @@ -1336,11 +1292,11 @@ H5_DLL herr_t H5Dset_extent_async(const char *app_file, const char *app_func, un * open files. After that, the OS is responsible for ensuring * that the data is actually flushed to disk. * + * \since 1.10.0 + * */ H5_DLL herr_t H5Dflush(hid_t dset_id); -H5_DLL herr_t H5Dwait(hid_t dset_id); - /** * -------------------------------------------------------------------------- * \ingroup H5D @@ -1396,40 +1352,7 @@ H5_DLL herr_t H5Drefresh(hid_t dset_id); * * To retrieve the data to be scattered, H5Dscatter() repeatedly * calls \p op, which should return a valid source buffer, until - * enough data to fill the selection has been retrieved. The - * prototype of the callback function \p op is as follows (as - * defined in the source code file H5Dpublic.h): - * \snippet this H5D_scatter_func_t_snip - * The parameters of this callback function are described below: - * - * <table> - * <tr><td>\c src_buf</td> - * <td><tt>[out]</tt></td> - * <td>Pointer to the buffer holding the next set of elements to - * scatter. On entry, the value of where \c src_buf points to - * is undefined. The callback function should set \c src_buf - * to point to the next set of elements.</td></tr> - * <tr><td>\c src_buf_bytes_used</td> - * <td><tt>[out]</tt></td> - * <td>Pointer to the number of valid bytes in \c src_buf. On - * entry, the value where \c src_buf_bytes_used points to is - * undefined. The callback function should set - * \c src_buf_bytes_used to the of valid bytes in \c src_buf. - * This number must be a multiple of the datatype size. - * </td></tr> - * <tr><td>\c op_data</td> - * <td><tt>[in,out]</tt></td> - * <td>User-defined pointer to data required by the callback - * function. A pass-through of the \c op_data pointer provided - * with the H5Dscatter() function call.</td></tr> - * </table> - * - * The callback function should always return at least one - * element in \p src_buf, and must not return more elements - * than are remaining to be scattered. This function will be - * repeatedly called until all elements to be scattered have - * been returned. The callback function should return zero (0) - * to indicate success, and a negative value to indicate failure. + * enough data to fill the selection has been retrieved. * * \since 1.10.2 * @@ -1481,27 +1404,9 @@ H5_DLL herr_t H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id, hi * If no callback function is provided, H5Dgather() simply gathers * the data into \p dst_buf and returns. If a callback function is * provided, H5Dgather() repeatedly gathers up to \p dst_buf_size - * bytes to process the serialized data. The prototype of the - * callback function \p op is as follows (as defined in the source - * code file H5Dpublic.h): - * \snippet this H5D_gather_func_t_snip - * The parameters of this callback function are described in the - * table below. - * <table> - * <tr><td>\c dst_buf</td> - * <td>Pointer to the destination buffer which has been filled - * with the next set of elements gathered. This will always be - * identical to the \p dst_buf passed to H5Dgather().</td></tr> - * <tr><td>\c dst_buf_bytes_used</td> - * <td>Pointer to the number of valid bytes in \p dst_buf. - * This number must be a multiple of the datatype - * size.</td></tr> - * <tr><td>\c op_data</td> - * <td>User-defined pointer to data required by the callback - * function; a pass-through of the \p op_data pointer - * provided with the H5Dgather() function call.</td></tr> - * </table> - * The callback function should process, store, or otherwise, + * bytes to process the serialized data. + * + * The callback function \p op should process, store, or otherwise, * make use of the data returned in \p dst_buf before it returns, * because the buffer will be overwritten unless it is the last * call to the callback. This function will be repeatedly called @@ -1525,11 +1430,11 @@ H5_DLL herr_t H5Dgather(hid_t src_space_id, const void *src_buf, hid_t type_id, * * \return \herr_t * - * \details H5Dclose() ends access to a dataset specified by \p dset_id - * and releases resources used by it. + * \details H5Dclose() terminates access to a dataset via the identifier + * \p dset_id and releases the underlying resources. * - * \attention Further use of a released dataset identifier is illegal; a - * function using such an identifier will generate an error. + * \par Example + * \snippet H5D_examples.c read * * \since 1.8.0 * @@ -1545,12 +1450,14 @@ H5_DLL herr_t H5Dclose(hid_t dset_id); */ H5_DLL herr_t H5Dclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, hid_t es_id); - +/// \cond DEV /* Internal API routines */ H5_DLL herr_t H5Ddebug(hid_t dset_id); H5_DLL herr_t H5Dformat_convert(hid_t dset_id); H5_DLL herr_t H5Dget_chunk_index_type(hid_t did, H5D_chunk_index_t *idx_type); +/// \endcond +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -1574,6 +1481,7 @@ H5_DLL herr_t H5Dget_chunk_index_type(hid_t did, H5D_chunk_index_t *idx_type); #define H5Dset_extent_async_wrap H5_NO_EXPAND(H5Dset_extent_async) #define H5Dclose_async_wrap H5_NO_EXPAND(H5Dclose_async) #endif /* H5D_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * @@ -1614,8 +1522,7 @@ H5_DLL herr_t H5Dget_chunk_index_type(hid_t did, H5D_chunk_index_t *idx_type); * * \return \hid_t{dataset} * - * \deprecated This function is deprecated in favor of the function H5Dcreate2() - * or the macro H5Dcreate(). + * \deprecation_note{H5Dcreate2() or the macro H5Dcreate()} * * \details H5Dcreate1() creates a data set with a name, \p name, in the * location specified by the identifier \p loc_id. \p loc_id may be a @@ -1681,8 +1588,7 @@ H5_DLL hid_t H5Dcreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t spa * * \return \hid_t{dataset} * - * \deprecated This function is deprecated in favor of the function H5Dopen2() - * or the macro H5Dopen(). + * \deprecation_note{H5Dopen2() or the macro H5Dopen()} * * \details H5Dopen1() opens an existing dataset for access at the location * specified by \p loc_id. \p loc_id may be a file, group, dataset, @@ -1712,10 +1618,10 @@ H5_DLL hid_t H5Dopen1(hid_t loc_id, const char *name); * * \return \herr_t * - * \deprecated This function is deprecated in favor of the function H5Dset_extent(). + * \deprecation_note{H5Dset_extent()} * * \details H5Dextend() verifies that the dataset is at least of size \p size, - * extending it if necessary. The dimensionality of size is the same as + * extending it if necessary. The length of \p size is the same as * that of the dataspace of the dataset being changed. * * This function can be applied to the following datasets: @@ -1735,7 +1641,7 @@ H5_DLL hid_t H5Dopen1(hid_t loc_id, const char *name); * the sizes specified in size. The function H5Dset_extent() must be * used if the dataset dimension sizes are are to be reduced. * - * \version 1.8.0 Function Function deprecated in this release. Parameter size + * \version 1.8.0 Function deprecated in this release. Parameter size * syntax changed to \Code{const hsize_t size[]} in this release. * */ @@ -1753,8 +1659,7 @@ H5_DLL herr_t H5Dextend(hid_t dset_id, const hsize_t size[]); * * \return \herr_t * - * \deprecated This function has been deprecated in HDF5-1.12 in favor of the - * function H5Treclaim(). + * \deprecation_note{H5Treclaim()} * * \details H5Dvlen_reclaim() reclaims memory buffers created to store VL * datatypes. @@ -1772,7 +1677,7 @@ H5_DLL herr_t H5Dextend(hid_t dset_id, const hsize_t size[]); * frees them from the bottom up, releasing all the memory without * creating memory leaks. * - * \version 1.12.0 Routine was deprecated + * \version 1.12.0 Function was deprecated * */ H5_DLL herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t dxpl_id, void *buf); diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c index d1c0266..d5375c1 100644 --- a/src/H5Dvirtual.c +++ b/src/H5Dvirtual.c @@ -3129,7 +3129,7 @@ H5D__virtual_refresh_source_dset(H5D_t **dset) HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register (temporary) source dataset ID") /* Refresh source dataset */ - if (H5D__refresh(temp_id, *dset) < 0) + if (H5D__refresh(*dset, temp_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to refresh source dataset") /* Discard the identifier & replace the dataset */ diff --git a/src/H5E.c b/src/H5E.c index b8e17a4..a5a9a2e 100644 --- a/src/H5E.c +++ b/src/H5E.c @@ -639,7 +639,7 @@ H5E__get_class_name(const H5E_cls_t *cls, char *name, size_t size) /* Set the user's buffer, if provided */ if (name) { - HDstrncpy(name, cls->cls_name, MIN((size_t)(len + 1), size)); + HDstrncpy(name, cls->cls_name, size); if ((size_t)len >= size) name[size - 1] = '\0'; } /* end if */ @@ -996,11 +996,12 @@ H5E__get_current_stack(void) if (H5I_inc_ref(current_error->min_num, FALSE) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, NULL, "unable to increment ref count on error message") new_error->min_num = current_error->min_num; - if (NULL == (new_error->func_name = H5MM_xstrdup(current_error->func_name))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - if (NULL == (new_error->file_name = H5MM_xstrdup(current_error->file_name))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - new_error->line = current_error->line; + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + new_error->func_name = current_error->func_name; + new_error->file_name = current_error->file_name; + new_error->line = current_error->line; if (NULL == (new_error->desc = H5MM_xstrdup(current_error->desc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") } /* end for */ @@ -1116,11 +1117,12 @@ H5E__set_current_stack(H5E_t *estack) if (H5I_inc_ref(new_error->min_num, FALSE) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error class") current_error->min_num = new_error->min_num; - if (NULL == (current_error->func_name = H5MM_xstrdup(new_error->func_name))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - if (NULL == (current_error->file_name = H5MM_xstrdup(new_error->file_name))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - current_error->line = new_error->line; + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + current_error->func_name = new_error->func_name; + current_error->file_name = new_error->file_name; + current_error->line = new_error->line; if (NULL == (current_error->desc = H5MM_xstrdup(new_error->desc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") } /* end for */ @@ -1813,11 +1815,12 @@ H5E__append_stack(H5E_t *dst_stack, const H5E_t *src_stack) if (H5I_inc_ref(src_error->min_num, FALSE) < 0) HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "unable to increment ref count on error message") dst_error->min_num = src_error->min_num; - if (NULL == (dst_error->func_name = H5MM_xstrdup(src_error->func_name))) - HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed") - if (NULL == (dst_error->file_name = H5MM_xstrdup(src_error->file_name))) - HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed") - dst_error->line = src_error->line; + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + dst_error->func_name = src_error->func_name; + dst_error->file_name = src_error->file_name; + dst_error->line = src_error->line; if (NULL == (dst_error->desc = H5MM_xstrdup(src_error->desc))) HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "memory allocation failed") diff --git a/src/H5ES.c b/src/H5ES.c index 2ba8a72..ccc0dd8 100644 --- a/src/H5ES.c +++ b/src/H5ES.c @@ -34,11 +34,12 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ #include "H5ESpkg.h" /* Event Sets */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ /****************/ /* Local Macros */ @@ -103,10 +104,61 @@ done: } /* end H5EScreate() */ /*------------------------------------------------------------------------- + * Function: H5ESinsert_request + * + * Purpose: Insert a request from a VOL connector into an event set. + * + * Note: This function is primarily targeted at VOL connector + * authors and is _not_ designed for general-purpose application use. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESinsert_request(hid_t es_id, hid_t connector_id, void *request) +{ + H5ES_t *es; /* Event set */ + H5VL_t *connector = NULL; /* VOL connector */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "ii*x", es_id, connector_id, request); + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (NULL == request) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL request pointer") + + /* Create new VOL connector object, using the connector ID */ + if (NULL == (connector = H5VL_new_connector(connector_id))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCREATE, FAIL, "can't create VOL connector object") + + /* Insert request into event set */ + if (H5ES__insert_request(es, connector, request) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINSERT, FAIL, "can't insert request into event set") + +done: + /* Clean up on error */ + if (ret_value < 0) + /* Release newly created connector */ + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "unable to decrement ref count on VOL connector") + + FUNC_LEAVE_API(ret_value) +} /* end H5ESinsert_request() */ + +/*------------------------------------------------------------------------- * Function: H5ESget_count * * Purpose: Retrieve the # of events in an event set * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -117,19 +169,23 @@ done: herr_t H5ESget_count(hid_t es_id, size_t *count /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", es_id, count); - /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") - /* Retrieve the count, if non-NULL */ - if (count) - *count = H5ES__list_count(&es->active); + /* Retrieve the count, if non-NULL */ + if (count) + *count = H5ES__list_count(&es->active); + } /* end if */ done: FUNC_LEAVE_API(ret_value) @@ -145,6 +201,8 @@ done: * mechanism for matching operations inserted into the event * set with [possible] errors that occur. * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -155,19 +213,23 @@ done: herr_t H5ESget_op_counter(hid_t es_id, uint64_t *op_counter /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", es_id, op_counter); - /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ - /* Retrieve the operation counter, if non-NULL */ - if (op_counter) - *op_counter = es->op_counter; + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + + /* Retrieve the operation counter, if non-NULL */ + if (op_counter) + *op_counter = es->op_counter; + } /* end if */ done: FUNC_LEAVE_API(ret_value) @@ -192,6 +254,8 @@ done: * value returned for the # of operations in progress may be * inaccurate. * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -202,33 +266,82 @@ done: herr_t H5ESwait(hid_t es_id, uint64_t timeout, size_t *num_in_progress /*out*/, hbool_t *op_failed /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "iULxx", es_id, timeout, num_in_progress, op_failed); - /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") - if (NULL == num_in_progress) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL num_in_progress pointer") - if (NULL == op_failed) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL op_failed pointer") - - /* Wait for operations */ - if (H5ES__wait(es, timeout, num_in_progress, op_failed) < 0) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTWAIT, FAIL, "can't wait on operations") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (NULL == num_in_progress) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL num_in_progress pointer") + if (NULL == op_failed) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL op_failed pointer") + + /* Wait for operations */ + if (H5ES__wait(es, timeout, num_in_progress, op_failed) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTWAIT, FAIL, "can't wait on operations") + } /* end if */ done: FUNC_LEAVE_API(ret_value) } /* end H5ESwait() */ /*------------------------------------------------------------------------- + * Function: H5EScancel + * + * Purpose: Attempt to cancel operations in an event set + * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, December 10, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5EScancel(hid_t es_id, size_t *num_not_canceled /*out*/, hbool_t *op_failed /*out*/) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "ixx", es_id, num_not_canceled, op_failed); + + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (NULL == num_not_canceled) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL num_not_canceled pointer") + if (NULL == op_failed) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL op_failed pointer") + + /* Cancel operations */ + if (H5ES__cancel(es, num_not_canceled, op_failed) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCANCEL, FAIL, "can't cancel operations") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5EScancel() */ + +/*------------------------------------------------------------------------- * Function: H5ESget_err_status * * Purpose: Check if event set has failed operations * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -239,19 +352,23 @@ done: herr_t H5ESget_err_status(hid_t es_id, hbool_t *err_status /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", es_id, err_status); - /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ - /* Retrieve the error flag, if non-NULL */ - if (err_status) - *err_status = es->err_occurred; + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + + /* Retrieve the error flag, if non-NULL */ + if (err_status) + *err_status = es->err_occurred; + } /* end if */ done: FUNC_LEAVE_API(ret_value) @@ -265,6 +382,8 @@ done: * Note: Does not wait for active operations to complete, so count may * not include all failures. * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -275,23 +394,27 @@ done: herr_t H5ESget_err_count(hid_t es_id, size_t *num_errs /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", es_id, num_errs); - /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ - /* Retrieve the error flag, if non-NULL */ - if (num_errs) { - if (es->err_occurred) - *num_errs = H5ES__list_count(&es->failed); - else - *num_errs = 0; - } /* end if */ + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + + /* Retrieve the error flag, if non-NULL */ + if (num_errs) { + if (es->err_occurred) + *num_errs = H5ES__list_count(&es->failed); + else + *num_errs = 0; + } /* end if */ + } /* end if */ done: FUNC_LEAVE_API(ret_value) @@ -305,6 +428,8 @@ done: * Note: The strings retrieved for each error info must be released * by calling H5free_memory(). * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -316,29 +441,164 @@ herr_t H5ESget_err_info(hid_t es_id, size_t num_err_info, H5ES_err_info_t err_info[] /*out*/, size_t *num_cleared /*out*/) { - H5ES_t *es; /* Event set */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "izxx", es_id, num_err_info, err_info, num_cleared); + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (0 == num_err_info) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "err_info array size is 0") + if (NULL == err_info) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL err_info array pointer") + if (NULL == num_cleared) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL errors cleared pointer") + + /* Retrieve the error information */ + if (H5ES__get_err_info(es, num_err_info, err_info, num_cleared) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't retrieve error info for failed operation(s)") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESget_err_info() */ + +/*------------------------------------------------------------------------- + * Function: H5ESfree_err_info + * + * Purpose: Convenience routine to free 1+ H5ES_err_info_t structs. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, March 5, 2021 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESfree_err_info(size_t num_err_info, H5ES_err_info_t err_info[]) +{ + size_t u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "z*#", num_err_info, err_info); + /* Check arguments */ - if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") if (0 == num_err_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "err_info array size is 0") if (NULL == err_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL err_info array pointer") - if (NULL == num_cleared) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL errors cleared pointer") - /* Retrieve the error information */ - if (H5ES__get_err_info(es, num_err_info, err_info, num_cleared) < 0) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't retrieve error info for failed operation(s)") + /* Iterate over array, releasing error information */ + for (u = 0; u < num_err_info; u++) { + H5MM_xfree(err_info[u].api_name); + H5MM_xfree(err_info[u].api_args); + H5MM_xfree(err_info[u].app_file_name); + H5MM_xfree(err_info[u].app_func_name); + if (H5I_dec_app_ref(err_info[u].err_stack_id) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "can't close error stack for err_info #%zu", u) + } /* end for */ done: FUNC_LEAVE_API(ret_value) -} /* end H5ESget_err_info() */ +} /* end H5ESfree_err_info() */ + +/*------------------------------------------------------------------------- + * Function: H5ESregister_insert_func + * + * Purpose: Registers a callback to invoke when a new operation is inserted + * into an event set. + * + * Note: Only one insert callback can be registered for each event set. + * Registering a new callback will replace the existing one. + * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESregister_insert_func(hid_t es_id, H5ES_event_insert_func_t func, void *ctx) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "iEI*x", es_id, func, ctx); + + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (NULL == func) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL function callback pointer") + + /* Set the event set's insert callback */ + es->ins_func = func; + es->ins_ctx = ctx; + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESregister_insert_func() */ + +/*------------------------------------------------------------------------- + * Function: H5ESregister_complete_func + * + * Purpose: Registers a callback to invoke when an operation completes + * within an event set. + * + * Note: Only one complete callback can be registered for each event set. + * Registering a new callback will replace the existing one. + * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ESregister_complete_func(hid_t es_id, H5ES_event_complete_func_t func, void *ctx) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "iEC*x", es_id, func, ctx); + + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + H5ES_t *es; /* Event set */ + + /* Check arguments */ + if (NULL == (es = H5I_object_verify(es_id, H5I_EVENTSET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid event set identifier") + if (NULL == func) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL function callback pointer") + + /* Set the event set's completion callback */ + es->comp_func = func; + es->comp_ctx = ctx; + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5ESregister_complete_func() */ /*------------------------------------------------------------------------- * Function: H5ESclose @@ -347,6 +607,8 @@ done: * * Note: Fails if active operations are present. * + * Note: H5ES_NONE is a valid value for 'es_id', but functions as a no-op + * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol @@ -362,16 +624,19 @@ H5ESclose(hid_t es_id) FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", es_id); - /* Check arguments */ - if (H5I_EVENTSET != H5I_get_type(es_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an event set") - - /* - * Decrement the counter on the object. It will be freed if the count - * reaches zero. - */ - if (H5I_dec_app_ref(es_id) < 0) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "unable to decrement ref count on event set") + /* Passing H5ES_NONE is valid, but a no-op */ + if (H5ES_NONE != es_id) { + /* Check arguments */ + if (H5I_EVENTSET != H5I_get_type(es_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an event set") + + /* + * Decrement the counter on the object. It will be freed if the count + * reaches zero. + */ + if (H5I_dec_app_ref(es_id) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, "unable to decrement ref count on event set") + } /* end if */ done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5ESdevelop.h b/src/H5ESdevelop.h new file mode 100644 index 0000000..5a0f2b4 --- /dev/null +++ b/src/H5ESdevelop.h @@ -0,0 +1,50 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This file contains public declarations for the H5ES (event set) developer + * support routines. + */ + +#ifndef _H5ESdevelop_H +#define _H5ESdevelop_H + +/* Include package's public header */ +#include "H5ESpublic.h" + +/*****************/ +/* Public Macros */ +/*****************/ + +/*******************/ +/* Public Typedefs */ +/*******************/ + +/********************/ +/* Public Variables */ +/********************/ + +/*********************/ +/* Public Prototypes */ +/*********************/ + +#ifdef __cplusplus +extern "C" { +#endif + +H5_DLL herr_t H5ESinsert_request(hid_t es_id, hid_t connector_id, void *request); + +#ifdef __cplusplus +} +#endif + +#endif /* _H5ESdevelop_H */ diff --git a/src/H5ESevent.c b/src/H5ESevent.c index b0c3578..aafc785 100644 --- a/src/H5ESevent.c +++ b/src/H5ESevent.c @@ -139,14 +139,14 @@ H5ES__event_free(H5ES_event_t *ev) /* Sanity check */ HDassert(ev); - if (ev->api_name) - H5MM_xfree_const(ev->api_name); - if (ev->api_args) - H5MM_xfree_const(ev->api_args); - if (ev->app_file) - H5MM_xfree_const(ev->app_file); - if (ev->app_func) - H5MM_xfree_const(ev->app_func); + /* The 'app_func_name', 'app_file_name', and 'api_name' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + ev->op_info.api_name = NULL; + if (ev->op_info.api_args) + H5MM_xfree_const(ev->op_info.api_args); + ev->op_info.app_file_name = NULL; + ev->op_info.app_func_name = NULL; if (ev->request) { /* Free the request */ if (H5VL_request_free(ev->request) < 0) diff --git a/src/H5ESint.c b/src/H5ESint.c index da3f779..6f9efe9 100644 --- a/src/H5ESint.c +++ b/src/H5ESint.c @@ -53,11 +53,18 @@ /* Callback context for wait operations */ typedef struct H5ES_wait_ctx_t { H5ES_t * es; /* Event set being operated on */ - uint64_t timeout; /* Timeout for wait operation */ + uint64_t timeout; /* Timeout for wait operation (in ns) */ size_t * num_in_progress; /* Count of # of operations that have not completed */ hbool_t *op_failed; /* Flag to indicate an operation failed */ } H5ES_wait_ctx_t; +/* Callback context for cancel operations */ +typedef struct H5ES_cancel_ctx_t { + H5ES_t * es; /* Event set being operated on */ + size_t * num_not_canceled; /* Count of # of operations were not canceled */ + hbool_t *op_failed; /* Flag to indicate an operation failed */ +} H5ES_cancel_ctx_t; + /* Callback context for get error info (gei) operations */ typedef struct H5ES_gei_ctx_t { H5ES_t * es; /* Event set being operated on */ @@ -73,9 +80,14 @@ typedef struct H5ES_gei_ctx_t { /********************/ /* Local Prototypes */ /********************/ +static herr_t H5ES__close(H5ES_t *es); static herr_t H5ES__close_cb(void *es, void **request_token); +static herr_t H5ES__insert(H5ES_t *es, H5VL_t *connector, void *request_token, const char *app_file, + const char *app_func, unsigned app_line, const char *caller, const char *api_args); static herr_t H5ES__handle_fail(H5ES_t *es, H5ES_event_t *ev); +static herr_t H5ES__op_complete(H5ES_t *es, H5ES_event_t *ev, H5VL_request_status_t ev_status); static int H5ES__wait_cb(H5ES_event_t *ev, void *_ctx); +static int H5ES__cancel_cb(H5ES_event_t *ev, void *_ctx); static int H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx); static int H5ES__close_failed_cb(H5ES_event_t *ev, void *_ctx); @@ -233,6 +245,81 @@ done: } /* end H5ES__create() */ /*------------------------------------------------------------------------- + * Function: H5ES__insert + * + * Purpose: Insert a request token into an event set + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5ES__insert(H5ES_t *es, H5VL_t *connector, void *request_token, const char *app_file, const char *app_func, + unsigned app_line, const char *caller, const char *api_args) +{ + H5ES_event_t *ev = NULL; /* Event for request */ + hbool_t ev_inserted = FALSE; /* Flag to indicate that event is in active list */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(es); + + /* Create new event */ + if (NULL == (ev = H5ES__event_new(connector, request_token))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCREATE, FAIL, "can't create event object") + + /* Copy the app source information */ + /* The 'app_func' & 'app_file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + ev->op_info.app_file_name = app_file; + ev->op_info.app_func_name = app_func; + ev->op_info.app_line_num = app_line; + + /* Set the event's operation counter */ + ev->op_info.op_ins_count = es->op_counter++; + + /* Set the event's timestamp & execution time */ + ev->op_info.op_ins_ts = H5_now_usec(); + ev->op_info.op_exec_ts = UINT64_MAX; + ev->op_info.op_exec_time = UINT64_MAX; + + /* Copy the API routine's name & arguments */ + /* The 'caller' string is also statically allocated (by the compiler) + * there's no need to duplicate it. + */ + ev->op_info.api_name = caller; + if (NULL == (ev->op_info.api_args = H5MM_xstrdup(api_args))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine arguments") + + /* Append fully initialized event onto the event set's 'active' list */ + H5ES__list_append(&es->active, ev); + ev_inserted = TRUE; + + /* Invoke the event set's 'insert' callback, if present */ + if (es->ins_func) + if ((es->ins_func)(&ev->op_info, es->ins_ctx) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CALLBACK, FAIL, "'insert' callback for event set failed") + +done: + /* Release resources on error */ + if (ret_value < 0) + if (ev) { + if (ev_inserted) + H5ES__list_remove(&es->active, ev); + if (H5ES__event_free(ev) < 0) + HDONE_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, FAIL, "unable to release event") + } + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__insert() */ + +/*------------------------------------------------------------------------- * Function: H5ES_insert * * Purpose: Insert a request token into an event set @@ -247,15 +334,15 @@ done: herr_t H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, const char *caller_args, ...) { - H5ES_t * es = NULL; /* Event set for the operation */ - H5ES_event_t *ev = NULL; /* Event for request */ - H5RS_str_t * rs = NULL; /* Ref-counted string to compose formatted argument string in */ - const char * app_file; /* Application source file name */ - const char * app_func; /* Application source function name */ - const char * s; /* Pointer to internal string from ref-counted string */ - va_list ap; /* Varargs for caller */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ - herr_t ret_value = SUCCEED; /* Return value */ + H5ES_t * es = NULL; /* Event set for the operation */ + const char *app_file; /* Application source file name */ + const char *app_func; /* Application source function name */ + unsigned app_line; /* Application source line number */ + H5RS_str_t *rs = NULL; /* Ref-counted string to compose formatted argument string in */ + const char *api_args; /* Pointer to api_args string from ref-counted string */ + va_list ap; /* Varargs for caller */ + hbool_t arg_started = FALSE; /* Whether the va_list has been started */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -273,10 +360,6 @@ H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, con if (es->err_occurred) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINSERT, FAIL, "event set has failed operations") - /* Create new event */ - if (NULL == (ev = H5ES__event_new(connector, token))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCREATE, FAIL, "can't create event object") - /* Start working on the API routines arguments */ HDva_start(ap, caller_args); arg_started = TRUE; @@ -284,24 +367,10 @@ H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, con /* Copy the app source information */ (void)HDva_arg(ap, char *); /* Toss the 'app_file' parameter name */ app_file = HDva_arg(ap, char *); - if (NULL == (ev->app_file = H5MM_strdup(app_file))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy app source file name") (void)HDva_arg(ap, char *); /* Toss the 'app_func' parameter name */ app_func = HDva_arg(ap, char *); - if (NULL == (ev->app_func = H5MM_strdup(app_func))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy app source function name") (void)HDva_arg(ap, char *); /* Toss the 'app_line' parameter name */ - ev->app_line = HDva_arg(ap, unsigned); - - /* Set the event's operation counter */ - ev->ev_count = es->op_counter++; - - /* Set the event's timestamp */ - ev->ev_time = H5_now_usec(); - - /* Copy the API routine's name */ - if (NULL == (ev->api_name = H5MM_strdup(caller))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine name") + app_line = HDva_arg(ap, unsigned); /* Create the string for the API routine's arguments */ if (NULL == (rs = H5RS_create(NULL))) @@ -312,13 +381,12 @@ H5ES_insert(hid_t es_id, H5VL_t *connector, void *token, const char *caller, con HDassert(0 == HDstrncmp(caller_args, "*s*sIu", 6)); if (H5_trace_args(rs, caller_args + 6, ap) < 0) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, FAIL, "can't create formatted API arguments") - if (NULL == (s = H5RS_get_str(rs))) + if (NULL == (api_args = H5RS_get_str(rs))) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "can't get pointer to formatted API arguments") - if (NULL == (ev->api_args = H5MM_strdup(s))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, FAIL, "can't copy API routine arguments") - /* Append fully initialized event onto the event set's 'active' list */ - H5ES__list_append(&es->active, ev); + /* Insert the operation into the event set */ + if (H5ES__insert(es, connector, token, app_file, app_func, app_line, caller, api_args) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINSERT, FAIL, "event set has failed operations") done: /* Clean up */ @@ -327,15 +395,42 @@ done: if (rs) H5RS_decr(rs); - /* Release resources on error */ - if (ret_value < 0) - if (ev && H5ES__event_free(ev) < 0) - HDONE_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, FAIL, "unable to release event") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5ES_insert() */ /*------------------------------------------------------------------------- + * Function: H5ES__insert_request + * + * Purpose: Directly insert a request token into an event set + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES__insert_request(H5ES_t *es, H5VL_t *connector, void *token) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(es); + HDassert(connector); + HDassert(token); + + /* Insert an 'anonymous' operation into the event set */ + if (H5ES__insert(es, connector, token, NULL, NULL, 0, NULL, NULL) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTINSERT, FAIL, "event set has failed operations") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__insert_request() */ + +/*------------------------------------------------------------------------- * Function: H5ES__handle_fail * * Purpose: Handle a failed event @@ -370,6 +465,101 @@ H5ES__handle_fail(H5ES_t *es, H5ES_event_t *ev) } /* end H5ES__handle_fail() */ /*------------------------------------------------------------------------- + * Function: H5ES__op_complete + * + * Purpose: Handle an operation completing + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, December 11, 2020 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5ES__op_complete(H5ES_t *es, H5ES_event_t *ev, H5VL_request_status_t ev_status) +{ + H5VL_request_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t err_stack_id = H5I_INVALID_HID; /* Error stack for failed operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(es); + HDassert(ev); + HDassert(H5VL_REQUEST_STATUS_SUCCEED == ev_status || H5VL_REQUEST_STATUS_FAIL == ev_status || + H5VL_REQUEST_STATUS_CANCELED == ev_status); + + /* Handle each form of event completion */ + if (H5VL_REQUEST_STATUS_SUCCEED == ev_status || H5VL_REQUEST_STATUS_CANCELED == ev_status) { + /* Invoke the event set's 'complete' callback, if present */ + if (es->comp_func) { + H5ES_status_t op_status; /* Status for complete callback */ + + /* Set appropriate info for callback */ + if (H5VL_REQUEST_STATUS_SUCCEED == ev_status) { + /* Translate status */ + op_status = H5ES_STATUS_SUCCEED; + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_REQUEST_GET_EXEC_TIME; + vol_cb_args.args.get_exec_time.exec_ts = &ev->op_info.op_exec_ts; + vol_cb_args.args.get_exec_time.exec_time = &ev->op_info.op_exec_time; + + /* Retrieve the execution time info */ + if (H5VL_request_specific(ev->request, &vol_cb_args) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, + "unable to retrieve execution time info for operation") + } + else + /* Translate status */ + op_status = H5ES_STATUS_CANCELED; + + if ((es->comp_func)(&ev->op_info, op_status, H5I_INVALID_HID, es->comp_ctx) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CALLBACK, FAIL, "'complete' callback for event set failed") + } /* end if */ + + /* Event success or cancellation */ + if (H5ES__event_completed(ev, &es->active) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, FAIL, "unable to release completed event") + } /* end if */ + else if (H5VL_REQUEST_STATUS_FAIL == ev_status) { + /* Invoke the event set's 'complete' callback, if present */ + if (es->comp_func) { + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_REQUEST_GET_ERR_STACK; + vol_cb_args.args.get_err_stack.err_stack_id = H5I_INVALID_HID; + + /* Retrieve the error stack for the operation */ + if (H5VL_request_specific(ev->request, &vol_cb_args) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, FAIL, "unable to retrieve error stack for operation") + + /* Set values */ + err_stack_id = vol_cb_args.args.get_err_stack.err_stack_id; + + if ((es->comp_func)(&ev->op_info, H5ES_STATUS_FAIL, err_stack_id, es->comp_ctx) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CALLBACK, FAIL, "'complete' callback for event set failed") + } /* end if */ + + /* Handle failure */ + if (H5ES__handle_fail(es, ev) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, FAIL, "unable to handle failed event") + } /* end else-if */ + else + HGOTO_ERROR(H5E_EVENTSET, H5E_BADVALUE, FAIL, "unknown event status?!?") + +done: + /* Clean up */ + if (H5I_INVALID_HID != err_stack_id) + if (H5I_dec_ref(err_stack_id) < 0) + HDONE_ERROR(H5E_EVENTSET, H5E_CANTDEC, FAIL, + "unable to decrement ref count on error stack for failed operation") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__op_complete() */ + +/*------------------------------------------------------------------------- * Function: H5ES__wait_cb * * Purpose: Common routine for testing / waiting on an operation @@ -405,9 +595,9 @@ H5ES__wait_cb(H5ES_event_t *ev, void *_ctx) /* Check for status values that indicate we should break out of the loop */ if (ev_status == H5VL_REQUEST_STATUS_FAIL) { - /* Handle failure */ - if (H5ES__handle_fail(ctx->es, ev) < 0) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, H5_ITER_ERROR, "unable to handle failed event") + /* Handle event completion */ + if (H5ES__op_complete(ctx->es, ev, ev_status) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release completed event") /* Record the error */ *ctx->op_failed = TRUE; @@ -415,13 +605,15 @@ H5ES__wait_cb(H5ES_event_t *ev, void *_ctx) /* Exit from the iteration */ ret_value = H5_ITER_STOP; } /* end if */ - else if (ev_status == H5VL_REQUEST_STATUS_SUCCEED) { - if (H5ES__event_completed(ev, &ctx->es->active) < 0) + else if (ev_status == H5VL_REQUEST_STATUS_SUCCEED || ev_status == H5VL_REQUEST_STATUS_CANCELED) { + /* Handle event completion */ + if (H5ES__op_complete(ctx->es, ev, ev_status) < 0) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release completed event") } /* end else-if */ - else if (ev_status == H5VL_REQUEST_STATUS_CANCELED) - /* Should never get a status of 'cancel' back from test / wait operation */ - HGOTO_ERROR(H5E_EVENTSET, H5E_BADVALUE, H5_ITER_ERROR, "received 'cancel' status for operation") + else if (ev_status == H5VL_REQUEST_STATUS_CANT_CANCEL) + /* Should never get a status of 'can't cancel' back from test / wait operation */ + HGOTO_ERROR(H5E_EVENTSET, H5E_BADVALUE, H5_ITER_ERROR, + "received \"can't cancel\" status for operation") else { /* Sanity check */ HDassert(ev_status == H5VL_REQUEST_STATUS_IN_PROGRESS); @@ -489,6 +681,114 @@ done: } /* end H5ES__wait() */ /*------------------------------------------------------------------------- + * Function: H5ES__cancel_cb + * + * Purpose: Callback for canceling operations + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, December 10, 2020 + * + *------------------------------------------------------------------------- + */ +static int +H5ES__cancel_cb(H5ES_event_t *ev, void *_ctx) +{ + H5ES_cancel_ctx_t * ctx = (H5ES_cancel_ctx_t *)_ctx; /* Callback context */ + H5VL_request_status_t ev_status = H5VL_REQUEST_STATUS_SUCCEED; /* Status from event's operation */ + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(ev); + HDassert(ctx); + + /* Attempt to cancel the request */ + if (H5VL_request_cancel(ev->request, &ev_status) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTCANCEL, H5_ITER_ERROR, "unable to cancel operation") + + /* Check for status values that indicate we should break out of the loop */ + if (ev_status == H5VL_REQUEST_STATUS_FAIL) { + /* Handle event completion */ + if (H5ES__op_complete(ctx->es, ev, ev_status) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTSET, H5_ITER_ERROR, "unable to handle failed event") + + /* Record the error */ + *ctx->op_failed = TRUE; + + /* Exit from the iteration */ + ret_value = H5_ITER_STOP; + } /* end if */ + else if (ev_status == H5VL_REQUEST_STATUS_SUCCEED) { + /* Increment "not canceled" counter */ + (*ctx->num_not_canceled)++; + + /* Handle event completion */ + if (H5ES__op_complete(ctx->es, ev, ev_status) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release completed event") + } /* end else-if */ + else if (ev_status == H5VL_REQUEST_STATUS_CANT_CANCEL || ev_status == H5VL_REQUEST_STATUS_IN_PROGRESS) { + /* Increment "not canceled" counter */ + (*ctx->num_not_canceled)++; + } /* end else-if */ + else { + /* Sanity check */ + HDassert(ev_status == H5VL_REQUEST_STATUS_CANCELED); + + /* Handle event completion */ + if (H5ES__op_complete(ctx->es, ev, ev_status) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTRELEASE, H5_ITER_ERROR, "unable to release completed event") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__cancel_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5ES__cancel + * + * Purpose: Cancel operations in event set + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Thursday, December 10, 2020 + * + *------------------------------------------------------------------------- + */ +herr_t +H5ES__cancel(H5ES_t *es, size_t *num_not_canceled, hbool_t *op_failed) +{ + H5ES_cancel_ctx_t ctx; /* Iterator callback context info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity check */ + HDassert(es); + HDassert(num_not_canceled); + HDassert(op_failed); + + /* Set user's parameters to known values */ + *num_not_canceled = 0; + *op_failed = FALSE; + + /* Set up context for iterator callbacks */ + ctx.es = es; + ctx.num_not_canceled = num_not_canceled; + ctx.op_failed = op_failed; + + /* Iterate over the events in the set, attempting to cancel them */ + if (H5ES__list_iterate(&es->active, H5ES__cancel_cb, &ctx) < 0) + HGOTO_ERROR(H5E_EVENTSET, H5E_BADITER, FAIL, "iteration failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5ES__cancel() */ + +/*------------------------------------------------------------------------- * Function: H5ES__get_err_info_cb * * Purpose: Retrieve information about a failed operation @@ -503,8 +803,9 @@ done: static int H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx) { - H5ES_gei_ctx_t *ctx = (H5ES_gei_ctx_t *)_ctx; /* Callback context */ - int ret_value = H5_ITER_CONT; /* Return value */ + H5VL_request_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5ES_gei_ctx_t * ctx = (H5ES_gei_ctx_t *)_ctx; /* Callback context */ + int ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_STATIC @@ -513,22 +814,35 @@ H5ES__get_err_info_cb(H5ES_event_t *ev, void *_ctx) HDassert(ctx); /* Copy operation info for event */ - if (NULL == (ctx->curr_err_info->api_name = H5MM_strdup(ev->api_name))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API name") - if (NULL == (ctx->curr_err_info->api_args = H5MM_strdup(ev->api_args))) + /* The 'app_func_name', 'app_file_name', and 'api_name' strings are statically allocated (by the compiler) + * so there's no need to duplicate them internally, but they are duplicated + * here, when they are given back to the user. + */ + if (NULL == (ctx->curr_err_info->api_name = H5MM_strdup(ev->op_info.api_name))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API routine name") + if (NULL == (ctx->curr_err_info->api_args = H5MM_strdup(ev->op_info.api_args))) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 API routine arguments") - if (NULL == (ctx->curr_err_info->app_file_name = H5MM_strdup(ev->app_file))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy app source file name") - if (NULL == (ctx->curr_err_info->app_func_name = H5MM_strdup(ev->app_func))) - HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy app function name") - ctx->curr_err_info->app_line_num = ev->app_line; - ctx->curr_err_info->op_ins_count = ev->ev_count; - ctx->curr_err_info->op_ins_ts = ev->ev_time; + if (NULL == (ctx->curr_err_info->app_file_name = H5MM_strdup(ev->op_info.app_file_name))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 application file name") + if (NULL == (ctx->curr_err_info->app_func_name = H5MM_strdup(ev->op_info.app_func_name))) + HGOTO_ERROR(H5E_EVENTSET, H5E_CANTALLOC, H5_ITER_ERROR, "can't copy HDF5 application function name") + ctx->curr_err_info->app_line_num = ev->op_info.app_line_num; + ctx->curr_err_info->op_ins_count = ev->op_info.op_ins_count; + ctx->curr_err_info->op_ins_ts = ev->op_info.op_ins_ts; + ctx->curr_err_info->op_exec_ts = ev->op_info.op_exec_ts; + ctx->curr_err_info->op_exec_time = ev->op_info.op_exec_time; + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_REQUEST_GET_ERR_STACK; + vol_cb_args.args.get_err_stack.err_stack_id = H5I_INVALID_HID; /* Get error stack for event */ - if (H5VL_request_specific(ev->request, H5VL_REQUEST_GET_ERR_STACK, &ctx->curr_err_info->err_stack_id) < 0) + if (H5VL_request_specific(ev->request, &vol_cb_args) < 0) HGOTO_ERROR(H5E_EVENTSET, H5E_CANTGET, H5_ITER_ERROR, "unable to retrieve error stack for operation") + /* Set value */ + ctx->curr_err_info->err_stack_id = vol_cb_args.args.get_err_stack.err_stack_id; + /* Remove event from event set's failed list */ H5ES__list_remove(&ctx->es->failed, ev); diff --git a/src/H5ESmodule.h b/src/H5ESmodule.h index cbc812e..5169b52 100644 --- a/src/H5ESmodule.h +++ b/src/H5ESmodule.h @@ -29,8 +29,10 @@ #define H5_MY_PKG_ERR H5E_EVENTSET #define H5_MY_PKG_INIT YES -/** - * \defgroup H5ES H5ES +/**\defgroup H5ES H5ES + * + * \todo Add the event set life cycle. + * * \brief Event Set Interface * * \details \Bold{This interface can be only used with the HDF5 VOL connectors that diff --git a/src/H5ESpkg.h b/src/H5ESpkg.h index 339ce1d..a7a8e20 100644 --- a/src/H5ESpkg.h +++ b/src/H5ESpkg.h @@ -43,14 +43,7 @@ typedef struct H5ES_event_t { H5VL_object_t * request; /* Request token for event */ struct H5ES_event_t *prev, *next; /* Previous and next event nodes */ - /* Useful info for debugging and error reporting */ - const char *api_name; /* Name of API routine for event */ - const char *api_args; /* Arguments to API routine */ - const char *app_file; /* Name of source file from application */ - const char *app_func; /* Name of source function from application */ - unsigned app_line; /* Line # of source file from application */ - uint64_t ev_count; /* This event is the n'th operation in the event set */ - uint64_t ev_time; /* Timestamp for this event (in ms from UNIX epoch) */ + H5ES_op_info_t op_info; /* Useful info about operation */ } H5ES_event_t; /* Typedef for lists of event set operations */ @@ -61,7 +54,11 @@ typedef struct H5ES_event_list_t { /* Typedef for event set objects */ struct H5ES_t { - uint64_t op_counter; /* Count of operations inserted into this set */ + uint64_t op_counter; /* Count of operations inserted into this set */ + H5ES_event_insert_func_t ins_func; /* Callback to invoke for operation inserts */ + void * ins_ctx; /* Context for callback to invoke for operation inserts */ + H5ES_event_complete_func_t comp_func; /* Callback to invoke for operation completions */ + void * comp_ctx; /* Context for callback to invoke for operation inserts */ /* Active events */ H5ES_event_list_t active; /* List of active events in set */ @@ -82,10 +79,11 @@ typedef int (*H5ES_list_iter_func_t)(H5ES_event_t *ev, void *ctx); /* Package Private Prototypes */ /******************************/ H5_DLL H5ES_t *H5ES__create(void); +H5_DLL herr_t H5ES__insert_request(H5ES_t *es, H5VL_t *connector, void *token); H5_DLL herr_t H5ES__wait(H5ES_t *es, uint64_t timeout, size_t *num_in_progress, hbool_t *op_failed); +H5_DLL herr_t H5ES__cancel(H5ES_t *es, size_t *num_not_canceled, hbool_t *op_failed); H5_DLL herr_t H5ES__get_err_info(H5ES_t *es, size_t num_err_info, H5ES_err_info_t err_info[], size_t *num_cleared); -H5_DLL herr_t H5ES__close(H5ES_t *es); /* Event list operations */ H5_DLL void H5ES__list_append(H5ES_event_list_t *el, H5ES_event_t *ev); diff --git a/src/H5ESprivate.h b/src/H5ESprivate.h index 4f843ba..3d9ce9f 100644 --- a/src/H5ESprivate.h +++ b/src/H5ESprivate.h @@ -24,8 +24,9 @@ #ifndef H5ESprivate_H #define H5ESprivate_H -/* Include package's public header */ -#include "H5ESpublic.h" /* Event Sets */ +/* Include package's public headers */ +#include "H5ESpublic.h" +#include "H5ESdevelop.h" /* Private headers needed by this file */ #include "H5VLprivate.h" /* Virtual Object Layer */ diff --git a/src/H5ESpublic.h b/src/H5ESpublic.h index 409282c..4cf71c5 100644 --- a/src/H5ESpublic.h +++ b/src/H5ESpublic.h @@ -42,24 +42,49 @@ /* Asynchronous operation status */ typedef enum H5ES_status_t { - H5ES_STATUS_IN_PROGRESS, /* Operation(s) have not yet completed */ - H5ES_STATUS_SUCCEED, /* Operation(s) have completed, successfully */ - H5ES_STATUS_FAIL /* An operation has completed, but failed */ + H5ES_STATUS_IN_PROGRESS, /* Operation(s) have not yet completed */ + H5ES_STATUS_SUCCEED, /* Operation(s) have completed, successfully */ + H5ES_STATUS_CANCELED, /* Operation(s) has been canceled */ + H5ES_STATUS_FAIL /* An operation has completed, but failed */ } H5ES_status_t; +/* Information about operations in an event set */ +typedef struct H5ES_op_info_t { + /* API call info */ + char *api_name; /* Name of HDF5 API routine called */ + char *api_args; /* "Argument string" for arguments to HDF5 API routine called */ + + /* Application info */ + char * app_file_name; /* Name of source file where the HDF5 API routine was called */ + char * app_func_name; /* Name of function where the HDF5 API routine was called */ + unsigned app_line_num; /* Line # of source file where the HDF5 API routine was called */ + + /* Operation info */ + uint64_t op_ins_count; /* Counter of operation's insertion into event set */ + uint64_t op_ins_ts; /* Timestamp for when the operation was inserted into the event set */ + uint64_t op_exec_ts; /* Timestamp for when the operation began execution */ + uint64_t op_exec_time; /* Execution time for operation (in ns) */ +} H5ES_op_info_t; + //! <!-- [H5ES_err_info_t_snip] --> /** * Information about failed operations in event set */ typedef struct H5ES_err_info_t { - /* Operation info */ - char * api_name; /**< Name of HDF5 API routine called */ - char * api_args; /**< "Argument string" for arguments to HDF5 API routine called */ + /* API call info */ + char *api_name; /**< Name of HDF5 API routine called */ + char *api_args; /**< "Argument string" for arguments to HDF5 API routine called */ + + /* Application info */ char * app_file_name; /**< Name of source file where the HDF5 API routine was called */ char * app_func_name; /**< Name of function where the HDF5 API routine was called */ unsigned app_line_num; /**< Line # of source file where the HDF5 API routine was called */ - uint64_t op_ins_count; /**< Counter of operation's insertion into event set */ - uint64_t op_ins_ts; /**< Timestamp for when the operation was inserted into the event set */ + + /* Operation info */ + uint64_t op_ins_count; /**< Counter of operation's insertion into event set */ + uint64_t op_ins_ts; /**< Timestamp for when the operation was inserted into the event set */ + uint64_t op_exec_ts; /**< Timestamp for when the operation began execution */ + uint64_t op_exec_time; /**< Execution time for operation (in ns) */ /* Error info */ hid_t err_stack_id; /**< ID for error stack from failed operation */ @@ -67,25 +92,11 @@ typedef struct H5ES_err_info_t { //! <!-- [H5ES_err_info_t_snip] --> /* -H5ES_op_info_t: - const char *: API name (H5Dwrite_async, ...) - const char *: Arg string - const char *: Appl. source file name - const char *: Appl. source function - unsigned: Appl. source file line - uint64_t: Insert Time Timestamp - uint64_t: "event count" - n'th event inserted into event set - uint64_t: Execution Time timestamp (*) - More Possible Info for H5ES_op_info_t: Parent Operation's request token (*) -> "parent event count"? -- Could be used to "prune" child operations from reported errors, with flag to H5ESget_err_info? -H5ES_err_info_t: - H5ES_op_info_t: (above) - hid_t: Error stack (*) - Possible debugging routines: (Should also be configured from Env Var) H5ESdebug_signal(hid_t es_id, signal_t sig, uint64_t <event count>); H5ESdebug_err_trace_log(hid_t es_id, const char *filename); @@ -102,15 +113,12 @@ Possible debugging routines: (Should also be configured from Env Var) How to Trace Async Operations? <Example of stacking Logging VOL Connector w/Async VOL Connector> -"Library / wrapper developer" version of API routines: (Auto-generated) - H5Dwrite_async_wrap(const char *app_file, const char *app_func, - unsigned app_line_num, dset_id, mem_type_id, mem_space_id, ..., es_id); - - vs. - - H5Dwrite_async(dset_id, mem_type_id, mem_space_id, ..., es_id); */ +typedef int (*H5ES_event_insert_func_t)(const H5ES_op_info_t *op_info, void *ctx); +typedef int (*H5ES_event_complete_func_t)(const H5ES_op_info_t *op_info, H5ES_status_t status, + hid_t err_stack, void *ctx); + /********************/ /* Public Variables */ /********************/ @@ -170,6 +178,7 @@ H5_DLL hid_t H5EScreate(void); * */ H5_DLL herr_t H5ESwait(hid_t es_id, uint64_t timeout, size_t *num_in_progress, hbool_t *err_occurred); +H5_DLL herr_t H5EScancel(hid_t es_id, size_t *num_not_canceled, hbool_t *err_occurred); /** * \ingroup H5ES @@ -260,6 +269,9 @@ H5_DLL herr_t H5ESget_err_count(hid_t es_id, size_t *num_errs); */ H5_DLL herr_t H5ESget_err_info(hid_t es_id, size_t num_err_info, H5ES_err_info_t err_info[], size_t *err_cleared); +H5_DLL herr_t H5ESfree_err_info(size_t num_err_info, H5ES_err_info_t err_info[]); +H5_DLL herr_t H5ESregister_insert_func(hid_t es_id, H5ES_event_insert_func_t func, void *ctx); +H5_DLL herr_t H5ESregister_complete_func(hid_t es_id, H5ES_event_complete_func_t func, void *ctx); /** * \ingroup H5ES diff --git a/src/H5Eint.c b/src/H5Eint.c index 3fd4099..6438cd9 100644 --- a/src/H5Eint.c +++ b/src/H5Eint.c @@ -129,7 +129,7 @@ H5E__get_msg(const H5E_msg_t *msg, H5E_type_t *type, char *msg_str, size_t size) /* Copy the message into the user's buffer, if given */ if (msg_str) { - HDstrncpy(msg_str, msg->msg, MIN((size_t)(len + 1), size)); + HDstrncpy(msg_str, msg->msg, size); if ((size_t)len >= size) msg_str[size - 1] = '\0'; } /* end if */ @@ -772,11 +772,12 @@ H5E__push_stack(H5E_t *estack, const char *file, const char *func, unsigned line if (H5I_inc_ref(min_id, FALSE) < 0) HGOTO_DONE(FAIL) estack->slot[estack->nused].min_num = min_id; - if (NULL == (estack->slot[estack->nused].func_name = H5MM_xstrdup(func))) - HGOTO_DONE(FAIL) - if (NULL == (estack->slot[estack->nused].file_name = H5MM_xstrdup(file))) - HGOTO_DONE(FAIL) - estack->slot[estack->nused].line = line; + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + estack->slot[estack->nused].func_name = func; + estack->slot[estack->nused].file_name = file; + estack->slot[estack->nused].line = line; if (NULL == (estack->slot[estack->nused].desc = H5MM_xstrdup(desc))) HGOTO_DONE(FAIL) estack->nused++; @@ -826,10 +827,11 @@ H5E__clear_entries(H5E_t *estack, size_t nentries) HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error class") /* Release strings */ - if (error->func_name) - error->func_name = (const char *)H5MM_xfree_const(error->func_name); - if (error->file_name) - error->file_name = (const char *)H5MM_xfree_const(error->file_name); + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + error->func_name = NULL; + error->file_name = NULL; if (error->desc) error->desc = (const char *)H5MM_xfree_const(error->desc); } diff --git a/src/H5Emodule.h b/src/H5Emodule.h index 43d5d36..58a3517 100644 --- a/src/H5Emodule.h +++ b/src/H5Emodule.h @@ -29,33 +29,54 @@ #define H5_MY_PKG_ERR H5E_ERROR #define H5_MY_PKG_INIT YES -/** - * \defgroup H5E H5E - * \brief Error Handling Interface - * - * \details The Error interface provides error handling in the form of a stack. - * The \Code{FUNC_ENTER} macro clears the error stack whenever an - * interface function is entered. When an error is detected, an entry - * is pushed onto the stack. As the functions unwind, additional - * entries are pushed onto the stack. The API function will return some - * indication that an error occurred and the application can print the - * error stack. - * - * Certain API functions in the \c H5E package, such as H5Eprint1(), do - * not clear the error stack. Otherwise, any function which does not - * have an underscore immediately after the package name will clear the - * error stack. For instance, H5Fopen() clears the error stack while - * \Code{H5F_open} does not. - * - * An error stack has a fixed maximum size. If this size is exceeded - * then the stack will be truncated and only the inner-most functions - * will have entries on the stack. This is expected to be a rare - * condition. - * - * Each thread has its own error stack, but since multi-threading has - * not been added to the library yet, this package maintains a single - * error stack. The error stack is statically allocated to reduce the - * complexity of handling errors within the \c H5E package. +/**\defgroup H5E H5E + * + * Use the functions in this module to manage HDF5 error stacks and error + * messages. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5E_examples.c create + * </td> + * <td> + * \snippet{lineno} H5E_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5E_examples.c update + * </td> + * <td> + * \snippet{lineno} H5E_examples.c delete + * </td> + * </tr> + * </table> + * + * \internal The \c FUNC_ENTER macro clears the error stack whenever an + * interface function is entered. When an error is detected, an entry + * is pushed onto the stack. As the functions unwind, additional + * entries are pushed onto the stack. The API function will return + * some indication that an error occurred and the application can + * print the error stack. + * + * \internal Certain API functions in the \ref H5E package, such as H5Eprint(), + * do not clear the error stack. Otherwise, any function which does + * not have an underscore immediately after the package name will + * clear the error stack. For instance, H5Fopen() clears the error + * stack while \Code{H5F_open} does not. + * + * \internal An error stack has a fixed maximum size. If this size is exceeded + * then the stack will be truncated and only the inner-most functions + * will have entries on the stack. This is expected to be a rare + * condition. + * + * \internal Each thread has its own error stack, but since multi-threading has + * not been added to the library yet, this package maintains a single + * error stack. The error stack is statically allocated to reduce the + * complexity of handling errors within the \ref H5E package. + * */ #endif /* H5Emodule_H */ diff --git a/src/H5Epublic.h b/src/H5Epublic.h index 0294023..9dfd1fc 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -716,12 +716,13 @@ typedef herr_t (*H5E_auto1_t)(void *client_data); * * \return \herr_t * + * \deprecated 1.8.0 Function H5Eclear() renamed to H5Eclear1() and deprecated + * in this release. + * * \details H5Eclear1() clears the error stack for the current thread.\n * The stack is also cleared whenever an API function is called, with * certain exceptions (for instance, H5Eprint1()). * - * \deprecated 1.8.0 Function H5Eclear() renamed to H5Eclear1() and deprecated - * in this release. */ H5_DLL herr_t H5Eclear1(void); /** @@ -737,6 +738,9 @@ H5_DLL herr_t H5Eclear1(void); * function * \return \herr_t * + * \deprecated 1.8.0 Function H5Eget_auto() renamed to H5Eget_auto1() and + * deprecated in this release. + * * \details H5Eget_auto1() returns the current settings for the automatic error * stack traversal function, \p func, and its data, * \p client_data. Either or both arguments may be \c NULL, in which case the @@ -763,8 +767,6 @@ H5_DLL herr_t H5Eclear1(void); * H5Eprint2(), mixing H5Eset_auto1() and H5Eget_auto2() or mixing * H5Eset_auto2() and H5Eget_auto1() does not fail. * - * \deprecated 1.8.0 Function H5Eget_auto() renamed to H5Eget_auto1() and - * deprecated in this release. */ H5_DLL herr_t H5Eget_auto1(H5E_auto1_t *func, void **client_data); /** @@ -781,6 +783,9 @@ H5_DLL herr_t H5Eget_auto1(H5E_auto1_t *func, void **client_data); * \param[in] str Error description string * \return \herr_t * + * \deprecated 1.8.0 Function H5Epush() renamed to H5Epush1() and + * deprecated in this release. + * * \details H5Epush1() pushes a new error record onto the error stack for the * current thread.\n * The error has major and minor numbers \p maj_num @@ -791,8 +796,6 @@ H5_DLL herr_t H5Eget_auto1(H5E_auto1_t *func, void **client_data); * allocated. * * \since 1.4.0 - * \deprecated 1.8.0 Function H5Epush() renamed to H5Epush1() and - * deprecated in this release. */ H5_DLL herr_t H5Epush1(const char *file, const char *func, unsigned line, H5E_major_t maj, H5E_minor_t min, const char *str); @@ -805,6 +808,9 @@ H5_DLL herr_t H5Epush1(const char *file, const char *func, unsigned line, H5E_ma * \param[in] stream File pointer, or \c NULL for \c stderr * \return \herr_t * + * \deprecated 1.8.0 Function H5Eprint() renamed to H5Eprint1() and + * deprecated in this release. + * * \details H5Eprint1() prints prints the error stack for the current thread * on the specified stream, \p stream. Even if the error stack is empty, a * one-line message of the following form will be printed: @@ -815,8 +821,6 @@ H5_DLL herr_t H5Epush1(const char *file, const char *func, unsigned line, H5E_ma * that prints error messages. Users are encouraged to write their own * more specific error handlers. * - * \deprecated 1.8.0 Function H5Eprint() renamed to H5Eprint1() and - * deprecated in this release. */ H5_DLL herr_t H5Eprint1(FILE *stream); /** @@ -829,6 +833,9 @@ H5_DLL herr_t H5Eprint1(FILE *stream); * \param[in] client_data Data passed to the error function * \return \herr_t * + * \deprecated 1.8.0 Function H5Eset_auto() renamed to H5Eset_auto1() and + * deprecated in this release. + * * \details H5Eset_auto1() turns on or off automatic printing of errors. When * turned on (non-null \p func pointer), any API function which returns * an error indication will first call \p func, passing it \p @@ -845,8 +852,6 @@ H5_DLL herr_t H5Eprint1(FILE *stream); * Automatic stack traversal is always in the #H5E_WALK_DOWNWARD * direction. * - * \deprecated 1.8.0 Function H5Eset_auto() renamed to H5Eset_auto1() and - * deprecated in this release. */ H5_DLL herr_t H5Eset_auto1(H5E_auto1_t func, void *client_data); /** @@ -860,6 +865,9 @@ H5_DLL herr_t H5Eset_auto1(H5E_auto1_t func, void *client_data); * \param[in] client_data Data to be passed to \p func * \return \herr_t * + * \deprecated 1.8.0 Function H5Ewalk() renamed to H5Ewalk1() and + * deprecated in this release. + * * \details H5Ewalk1() walks the error stack for the current thread and calls * the function specified in \p func for each error along the way. * @@ -877,8 +885,6 @@ H5_DLL herr_t H5Eset_auto1(H5E_auto1_t func, void *client_data); * is as follows: * \snippet this H5E_walk1_t_snip * - * \deprecated 1.8.0 Function H5Ewalk() renamed to H5Ewalk1() and - * deprecated in this release. */ H5_DLL herr_t H5Ewalk1(H5E_direction_t direction, H5E_walk1_t func, void *client_data); /** @@ -891,6 +897,8 @@ H5_DLL herr_t H5Ewalk1(H5E_direction_t direction, H5E_walk1_t func, void *client * \param[in] maj Major error number * \return \herr_t * + * \deprecated 1.8.0 Function deprecated in this release. + * * \details Given a major error number, H5Eget_major() returns a constant * character string that describes the error. * @@ -898,7 +906,6 @@ H5_DLL herr_t H5Ewalk1(H5E_direction_t direction, H5E_walk1_t func, void *client * array). An application calling this function must free the memory * associated with the return value to prevent a memory leak. * - * \deprecated 1.8.0 Function deprecated in this release. */ H5_DLL char *H5Eget_major(H5E_major_t maj); /** @@ -911,6 +918,8 @@ H5_DLL char *H5Eget_major(H5E_major_t maj); * \param[in] min Minor error number * \return \herr_t * + * \deprecated 1.8.0 Function deprecated and return type changed in this release. + * * \details Given a minor error number, H5Eget_minor() returns a constant * character string that describes the error. * @@ -920,7 +929,6 @@ H5_DLL char *H5Eget_major(H5E_major_t maj); * the memory associated with the return value to prevent a memory * leak. This is a change from the 1.6.x release series. * - * \deprecated 1.8.0 Function deprecated and return type changed in this release. */ H5_DLL char *H5Eget_minor(H5E_minor_t min); #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5F.c b/src/H5F.c index 0baf399..46c8c0e 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -112,8 +112,9 @@ H5FL_EXTERN(H5VL_object_t); hid_t H5Fget_create_plist(hid_t file_id) { - H5VL_object_t *vol_obj; /* File info */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* File for file_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", file_id); @@ -122,10 +123,17 @@ H5Fget_create_plist(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_FCPL; + vol_cb_args.args.get_fcpl.fcpl_id = H5I_INVALID_HID; + /* Retrieve the file creation property list */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_FCPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, H5I_INVALID_HID, "unable to retrieve file creation properties") + /* Set return value */ + ret_value = vol_cb_args.args.get_fcpl.fcpl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_create_plist() */ @@ -151,8 +159,9 @@ done: hid_t H5Fget_access_plist(hid_t file_id) { - H5VL_object_t *vol_obj; /* File info */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* File for file_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", file_id); @@ -161,10 +170,17 @@ H5Fget_access_plist(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_FAPL; + vol_cb_args.args.get_fapl.fapl_id = H5I_INVALID_HID; + /* Retrieve the file's access property list */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_FAPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get file access property list") + /* Set return value */ + ret_value = vol_cb_args.args.get_fapl.fapl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_access_plist() */ @@ -222,16 +238,25 @@ H5Fget_obj_count(hid_t file_id, unsigned types) * count the IDs in the file. */ if (file_id != (hid_t)H5F_OBJ_ALL) { - H5VL_object_t *vol_obj; + H5VL_object_t * vol_obj; /* File for file_id */ + size_t count = 0; /* Object count */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ /* Get the file object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not a file id") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_OBJ_COUNT; + vol_cb_args.args.get_obj_count.types = types; + vol_cb_args.args.get_obj_count.count = &count; + /* Get the count */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_OBJ_COUNT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, types, - &ret_value) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get object count in file(s)") + + /* Set return value */ + ret_value = (ssize_t)count; } /* If we passed in the 'special' ID, get the count for everything open in the * library, iterating over all open files and getting the object count for each. @@ -333,16 +358,27 @@ H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list / * get the IDs from the file. */ if (file_id != (hid_t)H5F_OBJ_ALL) { - H5VL_object_t *vol_obj; + H5VL_object_t * vol_obj; /* File for file_id */ + size_t count = 0; /* Object count */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ /* get the file object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_OBJ_IDS; + vol_cb_args.args.get_obj_ids.types = types; + vol_cb_args.args.get_obj_ids.max_objs = max_objs; + vol_cb_args.args.get_obj_ids.oid_list = oid_list; + vol_cb_args.args.get_obj_ids.count = &count; + /* Get the IDs */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_OBJ_IDS, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, types, - max_objs, oid_list, &ret_value) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get object ids in file(s)") + + /* Set return value */ + ret_value = (ssize_t)count; } /* end if */ /* If we passed in the 'special' ID, get the count for everything open in the * library, iterating over all open files and getting the object count for each. @@ -396,8 +432,10 @@ done: herr_t H5Fget_vfd_handle(hid_t file_id, hid_t fapl_id, void **file_handle /*out*/) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "iix", file_id, fapl_id, file_handle); @@ -410,9 +448,14 @@ H5Fget_vfd_handle(hid_t file_id, hid_t fapl_id, void **file_handle /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + file_opt_args.get_vfd_handle.fapl_id = fapl_id; + file_opt_args.get_vfd_handle.file_handle = file_handle; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_VFD_HANDLE; + vol_cb_args.args = &file_opt_args; + /* Retrieve the VFD handle for the file */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_VFD_HANDLE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, file_handle, fapl_id) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get VFD handle") done: @@ -432,7 +475,9 @@ done: htri_t H5Fis_accessible(const char *filename, hid_t fapl_id) { - htri_t ret_value; /* Return value */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + hbool_t is_accessible = FALSE; /* Whether file is accessible */ + htri_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("t", "*si", filename, fapl_id); @@ -447,11 +492,19 @@ H5Fis_accessible(const char *filename, hid_t fapl_id) else if (TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_IS_ACCESSIBLE; + vol_cb_args.args.is_accessible.filename = filename; + vol_cb_args.args.is_accessible.fapl_id = fapl_id; + vol_cb_args.args.is_accessible.accessible = &is_accessible; + /* Check if file is accessible */ - if (H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, fapl_id, - filename, &ret_value) < 0) + if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to determine if file is accessible as HDF5") + /* Set return value */ + ret_value = (htri_t)is_accessible; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fis_accessible() */ @@ -477,10 +530,17 @@ H5F__post_open_api_common(H5VL_object_t *vol_obj, void **token_ptr) supported = 0; if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't check for 'post open' operation") - if (supported & H5VL_OPT_QUERY_SUPPORTED) + if (supported & H5VL_OPT_QUERY_SUPPORTED) { + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_POST_OPEN; + vol_cb_args.args = NULL; + /* Make the 'post open' callback */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to make file 'post open' callback") + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -870,8 +930,9 @@ H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr, H5VL H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5I_type_t obj_type; /* Type of object to use */ - herr_t ret_value = SUCCEED; /* Return value */ + H5I_type_t obj_type; /* Type of object to use */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -885,9 +946,13 @@ H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr, H5VL if (NULL == (*vol_obj_ptr = H5VL_vol_object(object_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_FLUSH; + vol_cb_args.args.flush.obj_type = obj_type; + vol_cb_args.args.flush.scope = scope; + /* Flush the object */ - if (H5VL_file_specific(*vol_obj_ptr, H5VL_FILE_FLUSH, H5P_DATASET_XFER_DEFAULT, token_ptr, (int)obj_type, - (int)scope) < 0) + if (H5VL_file_specific(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file") done: @@ -1072,10 +1137,11 @@ done: herr_t H5Fdelete(const char *filename, hid_t fapl_id) { - H5P_genplist_t * plist; /* Property list pointer */ - H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ - htri_t is_hdf5 = FAIL; - herr_t ret_value = SUCCEED; + H5P_genplist_t * plist; /* Property list pointer */ + H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + hbool_t is_accessible = FALSE; /* Whether file is accessible */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE2("e", "*si", filename, fapl_id); @@ -1100,16 +1166,25 @@ H5Fdelete(const char *filename, hid_t fapl_id) if (H5CX_set_vol_connector_prop(&connector_prop) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set VOL connector info in API context") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_IS_ACCESSIBLE; + vol_cb_args.args.is_accessible.filename = filename; + vol_cb_args.args.is_accessible.fapl_id = fapl_id; + vol_cb_args.args.is_accessible.accessible = &is_accessible; + /* Make sure this is HDF5 storage for this VOL connector */ - if (H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, fapl_id, - filename, &is_hdf5) < 0) + if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to determine if file is accessible as HDF5") - if (!is_hdf5) + if (!is_accessible) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "not an HDF5 file") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_DELETE; + vol_cb_args.args.del.filename = filename; + vol_cb_args.args.del.fapl_id = fapl_id; + /* Delete the file */ - if (H5VL_file_specific(NULL, H5VL_FILE_DELETE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, fapl_id, - filename, &ret_value) < 0) + if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "unable to delete the file") done: @@ -1129,11 +1204,13 @@ done: herr_t H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id) { - H5VL_object_t *loc_vol_obj = NULL; /* Parent object */ - H5VL_object_t *child_vol_obj = NULL; /* Child object */ - H5I_type_t loc_type; /* ID type of location */ - H5I_type_t child_type; /* ID type of child */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * loc_vol_obj = NULL; /* Parent object */ + H5VL_object_t * child_vol_obj = NULL; /* Child object */ + H5VL_group_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + void * grp = NULL; /* Root group opened */ + H5I_type_t loc_type; /* ID type of location */ + int same_connector = 0; /* Whether parent and child files use the same connector */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*sii", loc_id, name, child_id, plist_id); @@ -1146,8 +1223,7 @@ H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL") if (!*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be the empty string") - child_type = H5I_get_type(child_id); - if (H5I_FILE != child_type) + if (H5I_FILE != H5I_get_type(child_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "child_id parameter not a file ID") if (H5P_DEFAULT == plist_id) plist_id = H5P_FILE_MOUNT_DEFAULT; @@ -1159,23 +1235,71 @@ H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") /* Get the location object */ - if (NULL == (loc_vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get location object") + /* Need to open the root group of a file, if a file ID was given as the + * 'loc_id', because the 'mount' operation is a group specific operation. + */ + if (H5I_FILE == loc_type) { + H5VL_object_t * vol_obj; /* Object for loc_id (file) */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + + /* Get the location object */ + if (NULL == (vol_obj = (H5VL_object_t *)H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = loc_type; + + /* Open the root group object */ + if (NULL == (grp = H5VL_group_open(vol_obj, &loc_params, "/", H5P_GROUP_ACCESS_DEFAULT, + H5P_DATASET_XFER_DEFAULT, NULL))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open group") + + /* Create a VOL object for the root group */ + if (NULL == (loc_vol_obj = H5VL_create_object(grp, vol_obj->connector))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "can't create VOL object for root group") + } /* end if */ + else { + HDassert(H5I_GROUP == loc_type); + if (NULL == (loc_vol_obj = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get location object") + } /* end else */ /* Get the child object */ if (NULL == (child_vol_obj = (H5VL_object_t *)H5I_object(child_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get child object") /* Check if both objects are associated with the same VOL connector */ - if (loc_vol_obj->connector->cls->value != child_vol_obj->connector->cls->value) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Can't mount file onto object from different VOL connector") + if (H5VL_cmp_connector_cls(&same_connector, loc_vol_obj->connector->cls, child_vol_obj->connector->cls) < + 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOMPARE, FAIL, "can't compare connector classes") + if (same_connector) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't mount file onto object from different VOL connector") + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_MOUNT; + vol_cb_args.args.mount.name = name; + vol_cb_args.args.mount.child_file = + child_vol_obj->data; /* Don't unwrap fully, so each connector can see its object */ + vol_cb_args.args.mount.fmpl_id = plist_id; /* Perform the mount operation */ - if (H5VL_file_specific(loc_vol_obj, H5VL_FILE_MOUNT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - (int)loc_type, name, child_vol_obj->data, plist_id) < 0) + /* (This is on a group, so that the VOL framework always sees groups for + * the 'mount' operation, instead of mixing files and groups) + */ + if (H5VL_group_specific(loc_vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file") done: + /* Clean up if we temporarily opened the root group for a file */ + if (grp) { + HDassert(loc_vol_obj); + if (H5VL_group_close(loc_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "unable to release group") + if (H5VL_free_object(loc_vol_obj) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to free VOL object") + } /* end if */ + FUNC_LEAVE_API(ret_value) } /* end H5Fmount() */ @@ -1198,9 +1322,11 @@ done: herr_t H5Funmount(hid_t loc_id, const char *name) { - H5VL_object_t *vol_obj = NULL; /* Parent object */ - H5I_type_t loc_type; /* ID type of location */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * loc_vol_obj = NULL; /* Parent object */ + H5VL_group_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + void * grp = NULL; /* Root group opened */ + H5I_type_t loc_type; /* ID type of location */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*s", loc_id, name); @@ -1219,15 +1345,57 @@ H5Funmount(hid_t loc_id, const char *name) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") /* Get the location object */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get location object") + /* Need to open the root group of a file, if a file ID was given as the + * 'loc_id', because the 'mount' operation is a group specific operation. + */ + if (H5I_FILE == loc_type) { + H5VL_object_t * vol_obj; /* Object for loc_id (file) */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + + /* Get the location object */ + if (NULL == (vol_obj = (H5VL_object_t *)H5VL_vol_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + + /* Set location parameters */ + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = loc_type; + + /* Open the root group object */ + if (NULL == (grp = H5VL_group_open(vol_obj, &loc_params, "/", H5P_GROUP_ACCESS_DEFAULT, + H5P_DATASET_XFER_DEFAULT, NULL))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open group") + + /* Create a VOL object for the root group */ + if (NULL == (loc_vol_obj = H5VL_create_object(grp, vol_obj->connector))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "can't create VOL object for root group") + } /* end if */ + else { + HDassert(H5I_GROUP == loc_type); + if (NULL == (loc_vol_obj = (H5VL_object_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get location object") + } /* end else */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_UNMOUNT; + vol_cb_args.args.unmount.name = name; /* Perform the unmount operation */ - if (H5VL_file_specific(vol_obj, H5VL_FILE_UNMOUNT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - (int)loc_type, name) < 0) + /* (This is on a group, so that the VOL framework always sees groups for + * the 'unmount' operation, instead of mixing files and groups) + */ + if (H5VL_group_specific(loc_vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to unmount file") done: + /* Clean up if we temporarily opened the root group for a file */ + if (grp) { + HDassert(loc_vol_obj); + if (H5VL_group_close(loc_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "unable to release group") + if (H5VL_free_object(loc_vol_obj) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to free VOL object") + } /* end if */ + FUNC_LEAVE_API(ret_value) } /* end H5Funmount() */ @@ -1245,9 +1413,10 @@ done: static hid_t H5F__reopen_api_common(hid_t file_id, void **token_ptr) { - void * file = NULL; /* File struct for new file */ - H5VL_object_t *vol_obj = NULL; /* Object for loc_id */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + void * reopen_file = NULL; /* Pointer to the re-opened file object */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_STATIC @@ -1255,16 +1424,20 @@ H5F__reopen_api_common(hid_t file_id, void **token_ptr) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_REOPEN; + vol_cb_args.args.reopen.file = &reopen_file; + /* Reopen the file */ - if (H5VL_file_specific(vol_obj, H5VL_FILE_REOPEN, H5P_DATASET_XFER_DEFAULT, token_ptr, &file) < 0) + if (H5VL_file_specific(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file via the VOL connector") /* Make sure that worked */ - if (NULL == file) + if (NULL == reopen_file) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file") /* Get an ID for the file */ - if ((ret_value = H5VL_register(H5I_FILE, file, vol_obj->connector, TRUE)) < 0) + if ((ret_value = H5VL_register(H5I_FILE, reopen_file, vol_obj->connector, TRUE)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle") done: @@ -1398,15 +1571,19 @@ H5Fget_intent(hid_t file_id, unsigned *intent_flags /*out*/) /* If no intent flags were passed in, exit quietly */ if (intent_flags) { - H5VL_object_t *vol_obj; /* File info */ + H5VL_object_t * vol_obj; /* File for file_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ /* Get the internal file structure */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_INTENT; + vol_cb_args.args.get_intent.flags = intent_flags; + /* Get the flags */ - if ((ret_value = H5VL_file_get(vol_obj, H5VL_FILE_GET_INTENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, intent_flags)) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file's intent flags") } /* end if */ @@ -1434,15 +1611,19 @@ H5Fget_fileno(hid_t file_id, unsigned long *fnumber /*out*/) /* If no fnumber pointer was passed in, exit quietly */ if (fnumber) { - H5VL_object_t *vol_obj; /* File info */ + H5VL_object_t * vol_obj; /* File for file_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ /* Get the internal file structure */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Get the flags */ - if ((ret_value = H5VL_file_get(vol_obj, H5VL_FILE_GET_FILENO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, fnumber)) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_FILENO; + vol_cb_args.args.get_fileno.fileno = fnumber; + + /* Get the 'file number' */ + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file's 'file number'") } /* end if */ @@ -1462,8 +1643,11 @@ done: hssize_t H5Fget_freespace(hid_t file_id) { - H5VL_object_t *vol_obj = NULL; - hssize_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + hsize_t file_freespace = 0; /* Size of freespace in the file */ + hssize_t ret_value; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE1("Hs", "i", file_id); @@ -1472,11 +1656,18 @@ H5Fget_freespace(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier") + /* Set up VOL callback arguments */ + file_opt_args.get_freespace.size = &file_freespace; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_FREE_SPACE; + vol_cb_args.args = &file_opt_args; + /* Get the amount of free space in the file */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_FREE_SPACE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file free space") + /* Set return value */ + ret_value = (hssize_t)file_freespace; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_freespace() */ @@ -1495,8 +1686,10 @@ done: herr_t H5Fget_filesize(hid_t file_id, hsize_t *size /*out*/) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", file_id, size); @@ -1507,9 +1700,13 @@ H5Fget_filesize(hid_t file_id, hsize_t *size /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_size.size = size; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_SIZE; + vol_cb_args.args = &file_opt_args; + /* Get the file size */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_SIZE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - size) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") done: @@ -1556,8 +1753,11 @@ done: ssize_t H5Fget_file_image(hid_t file_id, void *buf /*out*/, size_t buf_len) { - H5VL_object_t *vol_obj; /* File object for file ID */ - ssize_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* File object for file ID */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + size_t image_len = 0; /* Size of image buffer */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "ixz", file_id, buf, buf_len); @@ -1566,11 +1766,20 @@ H5Fget_file_image(hid_t file_id, void *buf /*out*/, size_t buf_len) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_file_image.buf_size = buf_len; + file_opt_args.get_file_image.buf = buf; + file_opt_args.get_file_image.image_len = &image_len; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_FILE_IMAGE; + vol_cb_args.args = &file_opt_args; + /* Get the file image */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_FILE_IMAGE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, buf, &ret_value, buf_len) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file image") + /* Set return value */ + ret_value = (ssize_t)image_len; + done: FUNC_LEAVE_API(ret_value) } /* H5Fget_file_image() */ @@ -1592,8 +1801,10 @@ done: herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config /*out*/) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", file_id, config); @@ -1606,9 +1817,13 @@ H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + file_opt_args.get_mdc_config.config = config; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MDC_CONF; + vol_cb_args.args = &file_opt_args; + /* Get the metadata cache configuration */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MDC_CONF, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - config) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get metadata cache configuration") done: @@ -1627,10 +1842,12 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr) +H5Fset_mdc_config(hid_t file_id, const H5AC_cache_config_t *config_ptr) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*Cc", file_id, config_ptr); @@ -1639,9 +1856,13 @@ H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + file_opt_args.set_mdc_config.config = config_ptr; + vol_cb_args.op_type = H5VL_NATIVE_FILE_SET_MDC_CONFIG; + vol_cb_args.args = &file_opt_args; + /* Set the metadata cache configuration */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_SET_MDC_CONFIG, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, config_ptr) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set metadata cache configuration") done: @@ -1663,8 +1884,10 @@ done: herr_t H5Fget_mdc_hit_rate(hid_t file_id, double *hit_rate /*out*/) { - H5VL_object_t *vol_obj; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", file_id, hit_rate); @@ -1675,9 +1898,13 @@ H5Fget_mdc_hit_rate(hid_t file_id, double *hit_rate /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_mdc_hit_rate.hit_rate = hit_rate; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MDC_HR; + vol_cb_args.args = &file_opt_args; + /* Get the current hit rate */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MDC_HR, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - hit_rate) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get MDC hit rate") done: @@ -1701,8 +1928,11 @@ herr_t H5Fget_mdc_size(hid_t file_id, size_t *max_size /*out*/, size_t *min_clean_size /*out*/, size_t *cur_size /*out*/, int *cur_num_entries /*out*/) { - H5VL_object_t *vol_obj; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + uint32_t index_len = 0; /* Size of cache index */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "ixxxx", file_id, max_size, min_clean_size, cur_size, cur_num_entries); @@ -1711,11 +1941,22 @@ H5Fget_mdc_size(hid_t file_id, size_t *max_size /*out*/, size_t *min_clean_size if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_mdc_size.max_size = max_size; + file_opt_args.get_mdc_size.min_clean_size = min_clean_size; + file_opt_args.get_mdc_size.cur_size = cur_size; + file_opt_args.get_mdc_size.cur_num_entries = &index_len; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MDC_SIZE; + vol_cb_args.args = &file_opt_args; + /* Get the size data */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MDC_SIZE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - max_size, min_clean_size, cur_size, cur_num_entries) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get MDC size") + /* Set mis-matched return value */ + if (cur_num_entries) + *cur_num_entries = (int)index_len; + done: FUNC_LEAVE_API(ret_value) } /* H5Fget_mdc_size() */ @@ -1739,8 +1980,9 @@ done: herr_t H5Freset_mdc_hit_rate_stats(hid_t file_id) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -1749,9 +1991,12 @@ H5Freset_mdc_hit_rate_stats(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE; + vol_cb_args.args = NULL; + /* Reset the hit rate statistic */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't reset cache hit rate") done: @@ -1780,9 +2025,11 @@ done: ssize_t H5Fget_name(hid_t obj_id, char *name /*out*/, size_t size) { - H5VL_object_t *vol_obj = NULL; - H5I_type_t type; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj; /* File for file_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5I_type_t type; + size_t file_name_len = 0; /* Length of file name */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "ixz", obj_id, name, size); @@ -1797,11 +2044,20 @@ H5Fget_name(hid_t obj_id, char *name /*out*/, size_t size) if (NULL == (vol_obj = H5VL_vol_object(obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_NAME; + vol_cb_args.args.get_name.type = type; + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = name; + vol_cb_args.args.get_name.file_name_len = &file_name_len; + /* Get the filename via the VOL */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)type, size, - name, &ret_value) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file name") + /* Set the return value */ + ret_value = (ssize_t)file_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_name() */ @@ -1822,9 +2078,11 @@ done: herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo /*out*/) { - H5VL_object_t *vol_obj = NULL; - H5I_type_t type; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + H5I_type_t type; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", obj_id, finfo); @@ -1843,9 +2101,14 @@ H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo /*out*/) if (NULL == (vol_obj = H5VL_vol_object(obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + file_opt_args.get_info.type = type; + file_opt_args.get_info.finfo = finfo; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_INFO; + vol_cb_args.args = &file_opt_args; + /* Get the file information */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - (int)type, finfo) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve file info") done: @@ -1865,8 +2128,10 @@ done: herr_t H5Fget_metadata_read_retry_info(hid_t file_id, H5F_retry_info_t *info /*out*/) { - H5VL_object_t *vol_obj = NULL; /* File object for file ID */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File object for file ID */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", file_id, info); @@ -1879,10 +2144,14 @@ H5Fget_metadata_read_retry_info(hid_t file_id, H5F_retry_info_t *info /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_metadata_read_retry_info.info = info; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO; + vol_cb_args.args = &file_opt_args; + /* Get the retry info */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, info) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't get metadata read retry info") + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get metadata read retry info") done: FUNC_LEAVE_API(ret_value) @@ -1903,8 +2172,11 @@ done: ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, H5F_sect_info_t *sect_info /*out*/) { - H5VL_object_t *vol_obj = NULL; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + size_t sect_count = 0; /* Number of sections */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE4("Zs", "iFmzx", file_id, type, nsects, sect_info); @@ -1915,11 +2187,21 @@ H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, H5F_sect_info if (sect_info && nsects == 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "nsects must be > 0") + /* Set up VOL callback arguments */ + file_opt_args.get_free_sections.type = type; + file_opt_args.get_free_sections.sect_info = sect_info; + file_opt_args.get_free_sections.nsects = nsects; + file_opt_args.get_free_sections.sect_count = §_count; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_FREE_SECTIONS; + vol_cb_args.args = &file_opt_args; + /* Get the free-space section information in the file */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_FREE_SECTIONS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, sect_info, &ret_value, (int)type, nsects) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file free sections") + /* Set return value */ + ret_value = (ssize_t)sect_count; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_free_sections() */ @@ -1938,8 +2220,9 @@ done: herr_t H5Fclear_elink_file_cache(hid_t file_id) { - H5VL_object_t *vol_obj; /* File */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -1948,9 +2231,12 @@ H5Fclear_elink_file_cache(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_CLEAR_ELINK_CACHE; + vol_cb_args.args = NULL; + /* Release the EFC */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_CLEAR_ELINK_CACHE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") done: @@ -1994,8 +2280,9 @@ done: herr_t H5Fstart_swmr_write(hid_t file_id) { - H5VL_object_t *vol_obj = NULL; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2008,9 +2295,12 @@ H5Fstart_swmr_write(hid_t file_id) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_START_SWMR_WRITE; + vol_cb_args.args = NULL; + /* Start SWMR writing */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_START_SWMR_WRITE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "unable to start SWMR writing") done: @@ -2030,8 +2320,9 @@ done: herr_t H5Fstart_mdc_logging(hid_t file_id) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2040,9 +2331,12 @@ H5Fstart_mdc_logging(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_START_MDC_LOGGING; + vol_cb_args.args = NULL; + /* Call mdc logging function */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_START_MDC_LOGGING, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to start mdc logging") done: @@ -2063,8 +2357,9 @@ done: herr_t H5Fstop_mdc_logging(hid_t file_id) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2073,9 +2368,12 @@ H5Fstop_mdc_logging(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_STOP_MDC_LOGGING; + vol_cb_args.args = NULL; + /* Call mdc logging function */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_STOP_MDC_LOGGING, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to stop mdc logging") done: @@ -2096,8 +2394,10 @@ done: herr_t H5Fget_mdc_logging_status(hid_t file_id, hbool_t *is_enabled /*out*/, hbool_t *is_currently_logging /*out*/) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ixx", file_id, is_enabled, is_currently_logging); @@ -2106,9 +2406,14 @@ H5Fget_mdc_logging_status(hid_t file_id, hbool_t *is_enabled /*out*/, hbool_t *i if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_mdc_logging_status.is_enabled = is_enabled; + file_opt_args.get_mdc_logging_status.is_currently_logging = is_currently_logging; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS; + vol_cb_args.args = &file_opt_args; + /* Call mdc logging function */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, is_enabled, is_currently_logging) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to get logging status") done: @@ -2130,8 +2435,10 @@ done: herr_t H5Fset_libver_bounds(hid_t file_id, H5F_libver_t low, H5F_libver_t high) { - H5VL_object_t *vol_obj; /* File as VOL object */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File as VOL object */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "iFvFv", file_id, low, high); @@ -2144,9 +2451,14 @@ H5Fset_libver_bounds(hid_t file_id, H5F_libver_t low, H5F_libver_t high) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + file_opt_args.set_libver_bounds.low = low; + file_opt_args.set_libver_bounds.high = high; + vol_cb_args.op_type = H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS; + vol_cb_args.args = &file_opt_args; + /* Set the library's version bounds */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, low, high) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set library version bounds") done: @@ -2167,8 +2479,9 @@ done: herr_t H5Fformat_convert(hid_t file_id) { - H5VL_object_t *vol_obj = NULL; /* File */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2181,9 +2494,12 @@ H5Fformat_convert(hid_t file_id) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_FORMAT_CONVERT; + vol_cb_args.args = NULL; + /* Convert the format */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_FORMAT_CONVERT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCONVERT, FAIL, "can't convert file format") done: @@ -2202,8 +2518,9 @@ done: herr_t H5Freset_page_buffering_stats(hid_t file_id) { - H5VL_object_t *vol_obj; /* File to reset stats on */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File to reset stats on */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2212,9 +2529,12 @@ H5Freset_page_buffering_stats(hid_t file_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_RESET_PAGE_BUFFERING_STATS; + vol_cb_args.args = NULL; + /* Reset the statistics */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_RESET_PAGE_BUFFERING_STATS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't reset stats for page buffering") done: @@ -2235,8 +2555,10 @@ H5Fget_page_buffering_stats(hid_t file_id, unsigned accesses[2] /*out*/, unsigne unsigned misses[2] /*out*/, unsigned evictions[2] /*out*/, unsigned bypasses[2] /*out*/) { - H5VL_object_t *vol_obj; /* File object */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File object */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "ixxxxx", file_id, accesses, hits, misses, evictions, bypasses); @@ -2247,9 +2569,17 @@ H5Fget_page_buffering_stats(hid_t file_id, unsigned accesses[2] /*out*/, unsigne if (NULL == accesses || NULL == hits || NULL == misses || NULL == evictions || NULL == bypasses) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL input parameters for stats") + /* Set up VOL callback arguments */ + file_opt_args.get_page_buffering_stats.accesses = accesses; + file_opt_args.get_page_buffering_stats.hits = hits; + file_opt_args.get_page_buffering_stats.misses = misses; + file_opt_args.get_page_buffering_stats.evictions = evictions; + file_opt_args.get_page_buffering_stats.bypasses = bypasses; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS; + vol_cb_args.args = &file_opt_args; + /* Get the statistics */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, accesses, hits, misses, evictions, bypasses) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stats for page buffering") done: @@ -2272,8 +2602,10 @@ done: herr_t H5Fget_mdc_image_info(hid_t file_id, haddr_t *image_addr /*out*/, hsize_t *image_len /*out*/) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ixx", file_id, image_addr, image_len); @@ -2282,9 +2614,14 @@ H5Fget_mdc_image_info(hid_t file_id, haddr_t *image_addr /*out*/, hsize_t *image if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.get_mdc_image_info.addr = image_addr; + file_opt_args.get_mdc_image_info.len = image_len; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO; + vol_cb_args.args = &file_opt_args; + /* Go get the address and size of the cache image */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, image_addr, image_len) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve cache image info") done: @@ -2317,9 +2654,16 @@ H5Fget_eoa(hid_t file_id, haddr_t *eoa /*out*/) /* Only do work if valid pointer to fill in */ if (eoa) { + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + + /* Set up VOL callback arguments */ + file_opt_args.get_eoa.eoa = eoa; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_EOA; + vol_cb_args.args = &file_opt_args; + /* Retrieve the EOA for the file */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_EOA, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - eoa) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get EOA") } /* end if */ @@ -2339,8 +2683,10 @@ done: herr_t H5Fincrement_filesize(hid_t file_id, hsize_t increment) { - H5VL_object_t *vol_obj; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ih", file_id, increment); @@ -2349,9 +2695,13 @@ H5Fincrement_filesize(hid_t file_id, hsize_t increment) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + /* Set up VOL callback arguments */ + file_opt_args.increment_filesize.increment = increment; + vol_cb_args.op_type = H5VL_NATIVE_FILE_INCR_FILESIZE; + vol_cb_args.args = &file_opt_args; + /* Increment the file size */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_INCR_FILESIZE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - increment) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to increment file size") done: @@ -2371,21 +2721,27 @@ done: herr_t H5Fget_dset_no_attrs_hint(hid_t file_id, hbool_t *minimize /*out*/) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", file_id, minimize); + /* Check args */ if (NULL == minimize) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "out pointer 'minimize' cannot be NULL") - - vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE); - if (NULL == vol_obj) + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MIN_DSET_OHDR_FLAG, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, minimize) < 0) + /* Set up VOL callback arguments */ + file_opt_args.get_min_dset_ohdr_flag.minimize = minimize; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MIN_DSET_OHDR_FLAG; + vol_cb_args.args = &file_opt_args; + + /* Get the dataset object header minimum size flag */ + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set file's dataset header minimization flag") done: @@ -2405,18 +2761,25 @@ done: herr_t H5Fset_dset_no_attrs_hint(hid_t file_id, hbool_t minimize) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ib", file_id, minimize); - vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE); - if (NULL == vol_obj) + /* Check args */ + if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_SET_MIN_DSET_OHDR_FLAG, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, minimize) < 0) + /* Set up VOL callback arguments */ + file_opt_args.set_min_dset_ohdr_flag.minimize = minimize; + vol_cb_args.op_type = H5VL_NATIVE_FILE_SET_MIN_DSET_OHDR_FLAG; + vol_cb_args.args = &file_opt_args; + + /* Set the 'minimize dataset object headers flag' */ + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set file's dataset header minimization flag") done: @@ -2424,43 +2787,6 @@ done: } /* H5Fset_dset_no_attrs_hint */ /*------------------------------------------------------------------------- - * Function: H5Fwait - * - * Purpose: Wait for all operations on a dataset. - * Tang: added for async - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -herr_t -H5Fwait(hid_t file_id) -{ - H5VL_object_t *vol_obj; /* File for this operation */ - H5I_type_t obj_type; /* Type of object */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(FAIL) - H5TRACE1("e", "i", file_id); - - /* Get the type of object we're flushing + sanity check */ - obj_type = H5I_get_type(file_id); - if (H5I_FILE != obj_type && H5I_GROUP != obj_type && H5I_DATATYPE != obj_type && - H5I_DATASET != obj_type && H5I_ATTR != obj_type) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "file_id parameter is not a valid file identifier") - - if ((ret_value = H5VL_file_specific(vol_obj, H5VL_FILE_WAIT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - file_id)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPERATE, FAIL, "unable to wait file") - -done: - FUNC_LEAVE_API(ret_value) -} /* H5Fwait() */ - -/*------------------------------------------------------------------------- * Function: H5Fvfd_swmr_end_tick() * * Purpose: To trigger end of tick processing @@ -2471,8 +2797,9 @@ done: herr_t H5Fvfd_swmr_end_tick(hid_t file_id) { - H5VL_object_t *vol_obj = NULL; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ /* Note: use the version of FUNC_ENTER_API without EOT processing */ FUNC_ENTER_API_NO_EOT(FAIL) @@ -2487,8 +2814,11 @@ H5Fvfd_swmr_end_tick(hid_t file_id) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_VFD_SWMR_END_TICK, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_VFD_SWMR_END_TICK; + vol_cb_args.args = NULL; + + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "unable to trigger end of tick processing for VFD SWMR") done: @@ -2507,9 +2837,9 @@ done: herr_t H5Fvfd_swmr_disable_end_of_tick(hid_t file_id) { - - H5VL_object_t *vol_obj = NULL; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2523,8 +2853,11 @@ H5Fvfd_swmr_disable_end_of_tick(hid_t file_id) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_VFD_SWMR_DISABLE_EOT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_VFD_SWMR_DISABLE_EOT; + vol_cb_args.args = NULL; + + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "unable to disable EOT for VFD SWMR") done: @@ -2542,9 +2875,9 @@ done: herr_t H5Fvfd_swmr_enable_end_of_tick(hid_t file_id) { - - H5VL_object_t *vol_obj = NULL; /* File info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* File */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -2558,8 +2891,11 @@ H5Fvfd_swmr_enable_end_of_tick(hid_t file_id) if (H5CX_set_loc(file_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_VFD_SWMR_ENABLE_EOT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_VFD_SWMR_ENABLE_EOT; + vol_cb_args.args = NULL; + + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "unable to enable EOT for VFD SWMR") done: diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index b265e1d..8cf9f9e 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -582,7 +582,7 @@ done: * memb_name & temp in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static H5FD_t * H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { @@ -735,7 +735,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__family_open() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: H5FD__family_close @@ -905,7 +905,7 @@ H5FD__family_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) * memb_name in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static herr_t H5FD__family_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t abs_eoa) { @@ -974,7 +974,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: H5FD__family_get_eof diff --git a/src/H5FDhdfs.c b/src/H5FDhdfs.c index 102a3ab..2c4bff6 100644 --- a/src/H5FDhdfs.c +++ b/src/H5FDhdfs.c @@ -1,15 +1,13 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Read-Only HDFS Virtual File Driver (VFD) * - * Copyright (c) 2018, The HDF Group. * - * * + * Copyright by The HDF Group. * * All rights reserved. * * * - * NOTICE: * - * All information contained herein is, and remains, the property of The HDF * - * Group. The intellectual and technical concepts contained herein are * - * proprietary to The HDF Group. Dissemination of this information or * - * reproduction of this material is strictly forbidden unless prior written * - * permission is obtained from The HDF Group. * + * 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://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* @@ -20,8 +18,10 @@ * File System (HDFS). */ +#ifdef H5_HAVE_LIBHDFS /* This source code file is part of the H5FD driver module */ #include "H5FDdrvr_module.h" +#endif #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ diff --git a/src/H5FDhdfs.h b/src/H5FDhdfs.h index 8d65ac7..7c871a4 100644 --- a/src/H5FDhdfs.h +++ b/src/H5FDhdfs.h @@ -1,15 +1,14 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Read-Only HDFS Virtual File Driver (VFD) * - * Copyright (c) 2018, The HDF Group. * + * Copyright by The HDF Group. * * * * All rights reserved. * * * - * NOTICE: * - * All information contained herein is, and remains, the property of The HDF * - * Group. The intellectual and technical concepts contained herein are * - * proprietary to The HDF Group. Dissemination of this information or * - * reproduction of this material is strictly forbidden unless prior written * - * permission is obtained from The HDF Group. * + * 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://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* diff --git a/src/H5FDlog.c b/src/H5FDlog.c index 707c97b..f996b9e 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -1218,7 +1218,6 @@ H5FD__log_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, had #ifndef H5_HAVE_PREADWRITE /* Seek to the correct location (if we don't have pread) */ if (addr != file->pos || OP_READ != file->op) { - H5_timer_t seek_timer; /* Timer for seek operation */ H5_timevals_t seek_times; /* Elapsed time for seek operation */ @@ -1441,7 +1440,6 @@ H5FD__log_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, ha #ifndef H5_HAVE_PREADWRITE /* Seek to the correct location (if we don't have pwrite) */ if (addr != file->pos || OP_WRITE != file->op) { - H5_timer_t seek_timer; /* Timer for seek operation */ H5_timevals_t seek_times; /* Elapsed time for seek operation */ diff --git a/src/H5FDmirror.c b/src/H5FDmirror.c index cf14c90..8cbeff6 100644 --- a/src/H5FDmirror.c +++ b/src/H5FDmirror.c @@ -15,12 +15,12 @@ * a remote host. */ -#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ - #include "H5private.h" /* Generic Functions */ #ifdef H5_HAVE_MIRROR_VFD +#include "H5FDdrvr_module.h" /* This source code file is part of the H5FD driver module */ + #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ #include "H5FDprivate.h" /* File drivers */ diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index 86f7664..cae4174 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -44,7 +44,7 @@ #define my_strdup strdup #endif -/* Macros for enabling/disabling particular GCC warnings +/* Macros for enabling/disabling particular GCC / clang warnings * * These are (renamed) duplicates of macros in H5private.h. If you make changes * here, be sure to update those as well. @@ -646,7 +646,7 @@ H5FD_multi_sb_encode(H5FD_t *_file, char *name /*out*/, unsigned char *buf /*out H5Eclear2(H5E_DEFAULT); /* Name and version number */ - strncpy(name, "NCSAmulti", (size_t)8); + strncpy(name, "NCSAmult", (size_t)9); name[8] = '\0'; assert(7 == H5FD_MEM_NTYPES); @@ -682,7 +682,7 @@ H5FD_multi_sb_encode(H5FD_t *_file, char *name /*out*/, unsigned char *buf /*out p = buf + 8 + nseen * 2 * 8; UNIQUE_MEMBERS (file->fa.memb_map, mt) { size_t n = strlen(file->fa.memb_name[mt]) + 1; - strncpy((char *)p, file->fa.memb_name[mt], n); + strcpy((char *)p, file->fa.memb_name[mt]); p += n; for (i = n; i % 8; i++) *p++ = '\0'; @@ -2019,6 +2019,7 @@ open_members(H5FD_multi_t *file) return 0; } +H5_MULTI_GCC_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: H5FD_multi_delete @@ -2029,6 +2030,7 @@ open_members(H5FD_multi_t *file) * *------------------------------------------------------------------------- */ +H5_MULTI_GCC_DIAG_OFF("format-nonliteral") static herr_t H5FD_multi_delete(const char *filename, hid_t fapl_id) { diff --git a/src/H5FDros3.c b/src/H5FDros3.c index 6e116ee..c0361f9 100644 --- a/src/H5FDros3.c +++ b/src/H5FDros3.c @@ -22,8 +22,10 @@ * Relies on "s3comms" utility layer to implement the AWS REST API. */ +#ifdef H5_HAVE_ROS3_VFD /* This source code file is part of the H5FD driver module */ #include "H5FDdrvr_module.h" +#endif #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ diff --git a/src/H5FDsplitter.c b/src/H5FDsplitter.c index c27cd1b..73c898a 100644 --- a/src/H5FDsplitter.c +++ b/src/H5FDsplitter.c @@ -340,10 +340,12 @@ H5Pset_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *vfd_config) HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate file access property list struct") info->ignore_wo_errs = vfd_config->ignore_wo_errs; - HDstrncpy(info->wo_path, vfd_config->wo_path, H5FD_SPLITTER_PATH_MAX); - HDstrncpy(info->log_file_path, vfd_config->log_file_path, H5FD_SPLITTER_PATH_MAX); - info->rw_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */ - info->wo_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */ + HDstrncpy(info->wo_path, vfd_config->wo_path, H5FD_SPLITTER_PATH_MAX + 1); + info->wo_path[H5FD_SPLITTER_PATH_MAX] = '\0'; + HDstrncpy(info->log_file_path, vfd_config->log_file_path, H5FD_SPLITTER_PATH_MAX + 1); + info->log_file_path[H5FD_SPLITTER_PATH_MAX] = '\0'; + info->rw_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */ + info->wo_fapl_id = H5P_FILE_ACCESS_DEFAULT; /* pre-set value */ /* Set non-default channel FAPL IDs in splitter configuration info */ if (H5P_DEFAULT != vfd_config->rw_fapl_id) { @@ -412,8 +414,8 @@ H5Pget_fapl_splitter(hid_t fapl_id, H5FD_splitter_vfd_config_t *config /*out*/) if (NULL == (fapl_ptr = (const H5FD_splitter_fapl_t *)H5P_peek_driver_info(plist_ptr))) HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unable to get specific-driver info") - HDstrncpy(config->wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX); - HDstrncpy(config->log_file_path, fapl_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX); + HDstrncpy(config->wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX + 1); + HDstrncpy(config->log_file_path, fapl_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX + 1); config->ignore_wo_errs = fapl_ptr->ignore_wo_errs; /* Copy R/W and W/O FAPLs */ @@ -587,8 +589,8 @@ H5FD__splitter_fapl_copy(const void *_old_fa) HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate log file FAPL") H5MM_memcpy(new_fa_ptr, old_fa_ptr, sizeof(H5FD_splitter_fapl_t)); - HDstrncpy(new_fa_ptr->wo_path, old_fa_ptr->wo_path, H5FD_SPLITTER_PATH_MAX); - HDstrncpy(new_fa_ptr->log_file_path, old_fa_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX); + HDstrncpy(new_fa_ptr->wo_path, old_fa_ptr->wo_path, H5FD_SPLITTER_PATH_MAX + 1); + HDstrncpy(new_fa_ptr->log_file_path, old_fa_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX + 1); /* Copy R/W and W/O FAPLs */ if (H5FD__copy_plist(old_fa_ptr->rw_fapl_id, &(new_fa_ptr->rw_fapl_id)) < 0) @@ -688,8 +690,8 @@ H5FD__splitter_open(const char *name, unsigned flags, hid_t splitter_fapl_id, ha HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get VFL driver info") /* Copy simpler info */ - HDstrncpy(file_ptr->fa.wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX); - HDstrncpy(file_ptr->fa.log_file_path, fapl_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX); + HDstrncpy(file_ptr->fa.wo_path, fapl_ptr->wo_path, H5FD_SPLITTER_PATH_MAX + 1); + HDstrncpy(file_ptr->fa.log_file_path, fapl_ptr->log_file_path, H5FD_SPLITTER_PATH_MAX + 1); file_ptr->fa.ignore_wo_errs = fapl_ptr->ignore_wo_errs; /* Copy R/W and W/O channel FAPLs. */ diff --git a/src/H5FL.c b/src/H5FL.c index fbeb9d2..cb58868 100644 --- a/src/H5FL.c +++ b/src/H5FL.c @@ -337,8 +337,11 @@ H5FL_reg_free(H5FL_reg_head_t *head, void *obj) /* Free tracking information about the allocation location */ H5CS_close_stack(trk->stack); - trk->file = H5MM_xfree(trk->file); - trk->func = H5MM_xfree(trk->func); + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + trk->file = NULL; + trk->func = NULL; /* Remove from "outstanding allocations" list */ if (trk == H5FL_out_head_g) { @@ -443,8 +446,11 @@ H5FL_reg_malloc(H5FL_reg_head_t *head H5FL_TRACK_PARAMS) /* Copy allocation location information */ ((H5FL_track_t *)ret_value)->stack = H5CS_copy_stack(); HDassert(((H5FL_track_t *)ret_value)->stack); - ((H5FL_track_t *)ret_value)->file = H5MM_strdup(call_file); - ((H5FL_track_t *)ret_value)->func = H5MM_strdup(call_func); + /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + ((H5FL_track_t *)ret_value)->file = call_file; + ((H5FL_track_t *)ret_value)->func = call_func; ((H5FL_track_t *)ret_value)->line = call_line; /* Add to "outstanding allocations" list */ @@ -908,8 +914,11 @@ H5FL_blk_malloc(H5FL_blk_head_t *head, size_t size H5FL_TRACK_PARAMS) /* Copy allocation location information */ ((H5FL_track_t *)ret_value)->stack = H5CS_copy_stack(); HDassert(((H5FL_track_t *)ret_value)->stack); - ((H5FL_track_t *)ret_value)->file = H5MM_strdup(call_file); - ((H5FL_track_t *)ret_value)->func = H5MM_strdup(call_func); + /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + ((H5FL_track_t *)ret_value)->file = call_file; + ((H5FL_track_t *)ret_value)->func = call_func; ((H5FL_track_t *)ret_value)->line = call_line; /* Add to "outstanding allocations" list */ @@ -1004,8 +1013,11 @@ H5FL_blk_free(H5FL_blk_head_t *head, void *block) /* Free tracking information about the allocation location */ H5CS_close_stack(trk->stack); - trk->file = H5MM_xfree(trk->file); - trk->func = H5MM_xfree(trk->func); + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + trk->file = NULL; + trk->func = NULL; /* Remove from "outstanding allocations" list */ if (trk == H5FL_out_head_g) { @@ -1120,14 +1132,20 @@ H5FL_blk_realloc(H5FL_blk_head_t *head, void *block, size_t new_size H5FL_TRACK_ /* Release previous tracking information */ H5CS_close_stack(trk->stack); - trk->file = H5MM_xfree(trk->file); - trk->func = H5MM_xfree(trk->func); + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + trk->file = NULL; + trk->func = NULL; /* Store new tracking information */ trk->stack = H5CS_copy_stack(); HDassert(trk->stack); - trk->file = H5MM_strdup(call_file); - trk->func = H5MM_strdup(call_func); + /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + trk->file = call_file; + trk->func = call_func; trk->line = call_line; } #endif /* H5FL_TRACK */ @@ -2017,8 +2035,11 @@ H5FL_fac_free(H5FL_fac_head_t *head, void *obj) /* Free tracking information about the allocation location */ H5CS_close_stack(trk->stack); - trk->file = H5MM_xfree(trk->file); - trk->func = H5MM_xfree(trk->func); + /* The 'func' & 'file' strings are statically allocated (by the compiler) + * and are not allocated, so there's no need to free them. + */ + trk->file = NULL; + trk->func = NULL; /* Remove from "outstanding allocations" list */ if (trk == H5FL_out_head_g) { @@ -2120,8 +2141,11 @@ H5FL_fac_malloc(H5FL_fac_head_t *head H5FL_TRACK_PARAMS) /* Copy allocation location information */ ((H5FL_track_t *)ret_value)->stack = H5CS_copy_stack(); HDassert(((H5FL_track_t *)ret_value)->stack); - ((H5FL_track_t *)ret_value)->file = H5MM_strdup(call_file); - ((H5FL_track_t *)ret_value)->func = H5MM_strdup(call_func); + /* The 'call_func' & 'call_file' strings are statically allocated (by the compiler) + * there's no need to duplicate them. + */ + ((H5FL_track_t *)ret_value)->file = call_file; + ((H5FL_track_t *)ret_value)->func = call_func; ((H5FL_track_t *)ret_value)->line = call_line; /* Add to "outstanding allocations" list */ diff --git a/src/H5Faccum.c b/src/H5Faccum.c index aed5812..4821272 100644 --- a/src/H5Faccum.c +++ b/src/H5Faccum.c @@ -36,7 +36,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ +#include "H5FDprivate.h" /* File drivers */ #include "H5MMprivate.h" /* Memory management */ #include "H5VMprivate.h" /* Vectors and arrays */ diff --git a/src/H5Fdeprec.c b/src/H5Fdeprec.c index b482961..ff6b4a0 100644 --- a/src/H5Fdeprec.c +++ b/src/H5Fdeprec.c @@ -89,10 +89,12 @@ herr_t H5Fget_info1(hid_t obj_id, H5F_info1_t *finfo /*out*/) { - H5VL_object_t *vol_obj = NULL; - H5I_type_t type; - H5F_info2_t finfo2; /* Current file info struct */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + H5I_type_t type; + H5F_info2_t finfo2; /* Current file info struct */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", obj_id, finfo); @@ -111,9 +113,14 @@ H5Fget_info1(hid_t obj_id, H5F_info1_t *finfo /*out*/) if (NULL == (vol_obj = H5VL_vol_object(obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + file_opt_args.get_info.type = type; + file_opt_args.get_info.finfo = &finfo2; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_INFO; + vol_cb_args.args = &file_opt_args; + /* Get the file information */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - type, &finfo2) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve file info") /* Copy the compatible fields into the older struct */ @@ -141,7 +148,9 @@ done: htri_t H5Fis_hdf5(const char *name) { - htri_t ret_value; /* Return value */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + hbool_t is_accessible = FALSE; /* Whether file is accessible */ + htri_t ret_value; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE1("t", "*s", name); @@ -150,11 +159,19 @@ H5Fis_hdf5(const char *name) if (!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, (-1), "no file name specified") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_IS_ACCESSIBLE; + vol_cb_args.args.is_accessible.filename = name; + vol_cb_args.args.is_accessible.fapl_id = H5P_FILE_ACCESS_DEFAULT; + vol_cb_args.args.is_accessible.accessible = &is_accessible; + /* Check if file is accessible */ - if (H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - H5P_FILE_ACCESS_DEFAULT, name, &ret_value) < 0) + if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, (-1), "unable to determine if file is accessible as HDF5") + /* Set return value */ + ret_value = (htri_t)is_accessible; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fis_hdf5() */ @@ -196,10 +213,11 @@ done: herr_t H5Fset_latest_format(hid_t file_id, hbool_t latest_format) { - H5VL_object_t *vol_obj; /* File as VOL object */ - H5F_libver_t low = H5F_LIBVER_LATEST; /* Low bound */ - H5F_libver_t high = H5F_LIBVER_LATEST; /* High bound */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* File as VOL object */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + H5F_libver_t low = H5F_LIBVER_LATEST; /* Low bound */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ib", file_id, latest_format); @@ -218,9 +236,14 @@ H5Fset_latest_format(hid_t file_id, hbool_t latest_format) if (!latest_format) low = H5F_LIBVER_EARLIEST; + /* Set up VOL callback arguments */ + file_opt_args.set_libver_bounds.low = low; + file_opt_args.set_libver_bounds.high = H5F_LIBVER_LATEST; + vol_cb_args.op_type = H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS; + vol_cb_args.args = &file_opt_args; + /* Set the library's version bounds */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)low, (int)high) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set library version bounds") done: diff --git a/src/H5Fefc.c b/src/H5Fefc.c index 3f9a22f..2d4eff2 100644 --- a/src/H5Fefc.c +++ b/src/H5Fefc.c @@ -36,10 +36,10 @@ #include "H5Pprivate.h" /* Property lists */ /* Special values for the "tag" field below */ -#define H5F_EFC_TAG_DEFAULT -1 -#define H5F_EFC_TAG_LOCK -2 -#define H5F_EFC_TAG_CLOSE -3 -#define H5F_EFC_TAG_DONTCLOSE -4 +#define H5F_EFC_TAG_DEFAULT (-1) +#define H5F_EFC_TAG_LOCK (-2) +#define H5F_EFC_TAG_CLOSE (-3) +#define H5F_EFC_TAG_DONTCLOSE (-4) /* Structure for each entry in a file's external file cache */ typedef struct H5F_efc_ent_t { diff --git a/src/H5Fint.c b/src/H5Fint.c index 247a047..e650878 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -82,6 +82,7 @@ static herr_t H5F__build_name(const char *prefix, const char *file_name, char ** static char * H5F__getenv_prefix_name(char **env_prefix /*in,out*/); static H5F_t *H5F__new(H5F_shared_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf); static herr_t H5F__check_if_using_file_locks(H5P_genplist_t *fapl, hbool_t *use_file_locking); +static herr_t H5F__dest(H5F_t *f, hbool_t flush); static herr_t H5F__build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name, char ** /*out*/ actual_name); static herr_t H5F__flush_phase1(H5F_t *f); @@ -1403,12 +1404,12 @@ done: * Return: SUCCEED/FAIL *------------------------------------------------------------------------- */ -herr_t +static herr_t H5F__dest(H5F_t *f, hbool_t flush) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_STATIC /* Sanity check */ HDassert(f); @@ -2487,11 +2488,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_delete(const char *filename, hid_t fapl_id) +H5F__delete(const char *filename, hid_t fapl_id) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_PACKAGE HDassert(filename); @@ -2501,7 +2502,7 @@ H5F_delete(const char *filename, hid_t fapl_id) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_delete() */ +} /* end H5F__delete() */ /*------------------------------------------------------------------------- * Function: H5F_try_close @@ -3241,27 +3242,28 @@ done: /*------------------------------------------------------------------------- * Function: H5F__get_file_image * - * Purpose: Private version of H5Fget_file_image + * Purpose: Private version of H5Fget_file_image, returns bytes copied/ + * number of bytes needed in *image_len. + * + * Return: SUCCEED/FAIL * - * Return: Success: Bytes copied / number of bytes needed. - * Failure: -1 *------------------------------------------------------------------------- */ -ssize_t -H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) +herr_t +H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len, size_t *image_len) { - H5FD_t *fd_ptr; /* file driver */ - haddr_t eoa; /* End of file address */ - ssize_t ret_value = -1; /* Return value */ + H5FD_t *fd_ptr; /* file driver */ + haddr_t eoa; /* End of file address */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Check args */ if (!file || !file->shared || !file->shared->lf) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "file_id yields invalid file pointer") + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file_id yields invalid file pointer") fd_ptr = file->shared->lf; if (!fd_ptr->cls) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "fd_ptr yields invalid class pointer") + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "fd_ptr yields invalid class pointer") /* the address space used by the split and multi file drivers is not * a good fit for this call. Since the plan is to depreciate these @@ -3282,7 +3284,7 @@ H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) * JRM -- 11/11/22 */ if (HDstrcmp(fd_ptr->cls->name, "multi") == 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "Not supported for multi file driver.") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Not supported for multi file driver.") /* While the family file driver is conceptually fully compatible * with the get file image operation, it sets a file driver message @@ -3290,7 +3292,7 @@ H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) * driver other than the family file driver. Needless to say, this * rather defeats the purpose of the get file image operation. * - * While this problem is quire solvable, the required time and + * While this problem is quite solvable, the required time and * resources are lacking at present. Hence, for now, we don't * allow the get file image operation to be perfomed on files * opened with the family file driver. @@ -3304,30 +3306,24 @@ H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) * JRM -- 12/21/11 */ if (HDstrcmp(fd_ptr->cls->name, "family") == 0) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "Not supported for family file driver.") + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "Not supported for family file driver.") /* Go get the actual file size */ if (HADDR_UNDEF == (eoa = H5FD_get_eoa(file->shared->lf, H5FD_MEM_DEFAULT))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file size") - - /* set ret_value = to eoa -- will overwrite this if appropriate */ - ret_value = (ssize_t)eoa; + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") - /* test to see if a buffer was provided -- if not, we are done */ + /* Test to see if a buffer was provided */ if (buf_ptr != NULL) { - size_t space_needed; /* size of file image */ unsigned tmp, tmp_size; /* Check for buffer too small */ if ((haddr_t)buf_len < eoa) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "supplied buffer too small") + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "supplied buffer too small") - space_needed = (size_t)eoa; - - /* read in the file image */ + /* Read in the file image */ /* (Note compensation for base address addition in internal routine) */ - if (H5FD_read(fd_ptr, H5FD_MEM_DEFAULT, 0, space_needed, buf_ptr) < 0) - HGOTO_ERROR(H5E_FILE, H5E_READERROR, (-1), "file image read request failed") + if (H5FD_read(fd_ptr, H5FD_MEM_DEFAULT, 0, (size_t)eoa, buf_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "file image read request failed") /* Offset to "status_flags" in the superblock */ tmp = H5F_SUPER_STATUS_FLAGS_OFF(file->shared->sblock->super_vers); @@ -3339,6 +3335,9 @@ H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) HDmemset((uint8_t *)buf_ptr + tmp, 0, tmp_size); } /* end if */ + /* Set *image_len = to EOA */ + *image_len = (size_t)eoa; + done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F__get_file_image() */ @@ -4043,11 +4042,12 @@ done: hid_t H5F_get_file_id(H5VL_object_t *vol_obj, H5I_type_t obj_type, hbool_t app_ref) { - void * vol_obj_file = NULL; /* File object pointer */ - H5VL_loc_params_t loc_params; /* Location parameters */ - hid_t file_id = H5I_INVALID_HID; /* File ID for object */ - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + void * vol_obj_file = NULL; /* File object pointer */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + hid_t file_id = H5I_INVALID_HID; /* File ID for object */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_NOAPI(H5I_INVALID_HID) @@ -4055,9 +4055,12 @@ H5F_get_file_id(H5VL_object_t *vol_obj, H5I_type_t obj_type, hbool_t app_ref) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = obj_type; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_FILE; + vol_cb_args.args.get_file.file = &vol_obj_file; + /* Retrieve VOL file from object */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_FILE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &vol_obj_file) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't retrieve file from object") /* Check if the file's ID already exists */ diff --git a/src/H5Fmodule.h b/src/H5Fmodule.h index 7f0299a..81c1ede 100644 --- a/src/H5Fmodule.h +++ b/src/H5Fmodule.h @@ -29,8 +29,7 @@ #define H5_MY_PKG_ERR H5E_FILE #define H5_MY_PKG_INIT YES -/** - * \defgroup H5F H5F +/**\defgroup H5F H5F * * Use the functions in this module to manage HDF5 files. * @@ -41,15 +40,23 @@ * creation or access \c mode control the interaction with the underlying * storage such as file systems. * - * \Emph{Proper error handling is part of the life cycle.} * <table> - * <tr><th>Create</th><th>Open</th></tr> + * <tr><th>Create</th><th>Read</th></tr> * <tr valign="top"> * <td> - * \snippet H5F_examples.c life_cycle + * \snippet{lineno} H5F_examples.c create * </td> * <td> - * \snippet H5F_examples.c life_cycle_w_open + * \snippet{lineno} H5F_examples.c read + * </td> + * </tr> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5F_examples.c update + * </td> + * <td> + * \snippet{lineno} H5F_examples.c delete * </td> * </tr> * </table> diff --git a/src/H5Fmount.c b/src/H5Fmount.c index f107c98..4b90ea3 100644 --- a/src/H5Fmount.c +++ b/src/H5Fmount.c @@ -83,7 +83,7 @@ done: } /* end H5F__close_mounts() */ /*------------------------------------------------------------------------- - * Function: H5F__mount + * Function: H5F_mount * * Purpose: Mount file CHILD onto the group specified by LOC and NAME, * using mount properties in PLIST. CHILD must not already be @@ -97,7 +97,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F__mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t H5_ATTR_UNUSED plist_id) +H5F_mount(const H5G_loc_t *loc, const char *name, H5F_t *child, hid_t H5_ATTR_UNUSED plist_id) { H5G_t * mount_point = NULL; /*mount point group */ H5F_t * ancestor = NULL; /*ancestor files */ @@ -110,7 +110,7 @@ H5F__mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t H5_ATTR_UNUSED H5G_loc_t root_loc; /* Group location of root of file to mount */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_NOAPI(FAIL) HDassert(loc); HDassert(name && *name); @@ -157,10 +157,9 @@ H5F__mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t H5_ATTR_UNUSED HDassert(mp_loc.oloc); mp_loc.path = H5G_nameof(mount_point); HDassert(mp_loc.path); - for (ancestor = parent; ancestor; ancestor = ancestor->parent) { + for (ancestor = parent; ancestor; ancestor = ancestor->parent) if (ancestor->shared == child->shared) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount would introduce a cycle") - } /* Make certain that the parent & child files have the same "file close degree" */ if (parent->shared->fc_degree != child->shared->fc_degree) @@ -240,10 +239,10 @@ done: } FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F__mount() */ +} /* end H5F_mount() */ /*------------------------------------------------------------------------- - * Function: H5F__unmount + * Function: H5F_unmount * * Purpose: Unmount the child which is mounted at the group specified by * LOC and NAME or fail if nothing is mounted there. Neither @@ -261,7 +260,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F__unmount(H5G_loc_t *loc, const char *name) +H5F_unmount(const H5G_loc_t *loc, const char *name) { H5G_t * child_group = NULL; /* Child's group in parent mtab */ H5F_t * child = NULL; /*mounted file */ @@ -275,7 +274,7 @@ H5F__unmount(H5G_loc_t *loc, const char *name) int child_idx; /* Index of child in parent's mtab */ herr_t ret_value = SUCCEED; /*return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_NOAPI(FAIL) HDassert(loc); HDassert(name && *name); @@ -291,7 +290,7 @@ H5F__unmount(H5G_loc_t *loc, const char *name) * then we must have found the mount point. */ if (H5G_loc_find(loc, name, &mp_loc /*out*/) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") + HGOTO_ERROR(H5E_FILE, H5E_NOTFOUND, FAIL, "group not found") mp_loc_setup = TRUE; child = mp_loc.oloc->file; mnt_oloc = H5G_oloc(child->shared->root_grp); @@ -364,7 +363,7 @@ H5F__unmount(H5G_loc_t *loc, const char *name) /* Search the open IDs replace names to reflect unmount operation */ if (H5G_name_replace(NULL, H5G_NAME_UNMOUNT, mp_loc.oloc->file, mp_loc.path->full_path_r, root_loc.oloc->file, root_loc.path->full_path_r) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name") + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to replace name") /* Eliminate the mount point from the table */ HDmemmove(parent->shared->mtab.child + (unsigned)child_idx, @@ -376,7 +375,7 @@ H5F__unmount(H5G_loc_t *loc, const char *name) /* Unmount the child file from the parent file */ if (H5G_unmount(child_group) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to reset group mounted flag") + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to reset group mounted flag") if (H5G_close(child_group) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close unmounted group") @@ -391,7 +390,7 @@ done: H5G_loc_free(&mp_loc); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F__unmount() */ +} /* end H5F_unmount() */ /*------------------------------------------------------------------------- * Function: H5F_is_mount diff --git a/src/H5Fmpi.c b/src/H5Fmpi.c index 4b5283e..53d2d78 100644 --- a/src/H5Fmpi.c +++ b/src/H5Fmpi.c @@ -193,7 +193,7 @@ done: } /* end H5F_mpi_get_size() */ /*------------------------------------------------------------------------- - * Function: H5F_set_mpi_atomicity + * Function: H5F__set_mpi_atomicity * * Purpose: Private call to set the atomicity mode * @@ -202,11 +202,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_set_mpi_atomicity(H5F_t *file, hbool_t flag) +H5F__set_mpi_atomicity(H5F_t *file, hbool_t flag) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL); + FUNC_ENTER_PACKAGE /* Check args */ HDassert(file); @@ -222,7 +222,7 @@ H5F_set_mpi_atomicity(H5F_t *file, hbool_t flag) done: FUNC_LEAVE_NOAPI(ret_value); -} /* end H5F_set_mpi_atomicity() */ +} /* end H5F__set_mpi_atomicity() */ /*------------------------------------------------------------------------- * Function: H5Fset_mpi_atomicity @@ -240,9 +240,10 @@ done: herr_t H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag) { - H5VL_object_t *vol_obj = NULL; - int va_flag = (int)flag; /* C is grumpy about passing hbool_t via va_arg */ - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE2("e", "ib", file_id, flag); @@ -251,9 +252,13 @@ H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier"); + /* Set up VOL callback arguments */ + file_opt_args.set_mpi_atomicity.flag = flag; + vol_cb_args.op_type = H5VL_NATIVE_FILE_SET_MPI_ATOMICITY; + vol_cb_args.args = &file_opt_args; + /* Set atomicity value */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_SET_MPI_ATOMICITY, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, va_flag) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set MPI atomicity"); done: @@ -261,7 +266,7 @@ done: } /* end H5Fset_mpi_atomicity() */ /*------------------------------------------------------------------------- - * Function: H5F_get_mpi_atomicity + * Function: H5F__get_mpi_atomicity * * Purpose: Private call to get the atomicity mode * @@ -270,11 +275,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_get_mpi_atomicity(H5F_t *file, hbool_t *flag) +H5F__get_mpi_atomicity(const H5F_t *file, hbool_t *flag) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL); + FUNC_ENTER_PACKAGE /* Check args */ HDassert(file); @@ -291,7 +296,7 @@ H5F_get_mpi_atomicity(H5F_t *file, hbool_t *flag) done: FUNC_LEAVE_NOAPI(ret_value); -} /* end H5F_get_mpi_atomicity() */ +} /* end H5F__get_mpi_atomicity() */ /*------------------------------------------------------------------------- * Function: H5Fget_mpi_atomicity @@ -309,8 +314,10 @@ done: herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag /*out*/) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj; /* File info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE2("e", "ix", file_id, flag); @@ -319,9 +326,13 @@ H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier"); + /* Set up VOL callback arguments */ + file_opt_args.get_mpi_atomicity.flag = flag; + vol_cb_args.op_type = H5VL_NATIVE_FILE_GET_MPI_ATOMICITY; + vol_cb_args.args = &file_opt_args; + /* Get atomicity value */ - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_GET_MPI_ATOMICITY, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, flag) < 0) + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get MPI atomicity"); done: diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 71c27f2..c94c5af 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -519,25 +519,23 @@ H5_DLLVAR htri_t use_locks_env_g; /* General routines */ H5_DLL herr_t H5F__post_open(H5F_t *f); -H5_DLL H5F_t * H5F__reopen(H5F_t *f); -H5_DLL herr_t H5F__dest(H5F_t *f, hbool_t flush); -H5_DLL herr_t H5F__flush(H5F_t *f); -H5_DLL htri_t H5F__is_hdf5(const char *name, hid_t fapl_id); -H5_DLL ssize_t H5F__get_file_image(H5F_t *f, void *buf_ptr, size_t buf_len); -H5_DLL herr_t H5F__get_info(H5F_t *f, H5F_info2_t *finfo); -H5_DLL herr_t H5F__format_convert(H5F_t *f); -H5_DLL herr_t H5F__start_swmr_write(H5F_t *f); -H5_DLL herr_t H5F__close(H5F_t *f); -H5_DLL herr_t H5F__set_libver_bounds(H5F_t *f, H5F_libver_t low, H5F_libver_t high); -H5_DLL herr_t H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info); -H5_DLL herr_t H5F__parse_file_lock_env_var(htri_t *use_locks); -H5_DLL herr_t H5F__vfd_swmr_end_tick(H5F_t *f); -H5_DLL herr_t H5F__vfd_swmr_disable_end_of_tick(H5F_t *f); -H5_DLL herr_t H5F__vfd_swmr_enable_end_of_tick(H5F_t *f); +H5_DLL H5F_t *H5F__reopen(H5F_t *f); +H5_DLL herr_t H5F__flush(H5F_t *f); +H5_DLL htri_t H5F__is_hdf5(const char *name, hid_t fapl_id); +H5_DLL herr_t H5F__get_file_image(H5F_t *f, void *buf_ptr, size_t buf_len, size_t *image_len); +H5_DLL herr_t H5F__get_info(H5F_t *f, H5F_info2_t *finfo); +H5_DLL herr_t H5F__format_convert(H5F_t *f); +H5_DLL herr_t H5F__start_swmr_write(H5F_t *f); +H5_DLL herr_t H5F__close(H5F_t *f); +H5_DLL herr_t H5F__set_libver_bounds(H5F_t *f, H5F_libver_t low, H5F_libver_t high); +H5_DLL herr_t H5F__get_cont_info(const H5F_t *f, H5VL_file_cont_info_t *info); +H5_DLL herr_t H5F__parse_file_lock_env_var(htri_t *use_locks); +H5_DLL herr_t H5F__delete(const char *filename, hid_t fapl_id); +H5_DLL herr_t H5F__vfd_swmr_end_tick(H5F_t *f); +H5_DLL herr_t H5F__vfd_swmr_disable_end_of_tick(H5F_t *f); +H5_DLL herr_t H5F__vfd_swmr_enable_end_of_tick(H5F_t *f); /* File mount related routines */ -H5_DLL herr_t H5F__mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t plist_id); -H5_DLL herr_t H5F__unmount(H5G_loc_t *loc, const char *name); H5_DLL herr_t H5F__close_mounts(H5F_t *f); H5_DLL herr_t H5F__mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs); @@ -567,6 +565,12 @@ H5_DLL herr_t H5F__sfile_add(H5F_shared_t *shared); H5_DLL H5F_shared_t *H5F__sfile_search(H5FD_t *lf); H5_DLL herr_t H5F__sfile_remove(H5F_shared_t *shared); +/* Parallel I/O (i.e. MPI) related routines */ +#ifdef H5_HAVE_PARALLEL +H5_DLL herr_t H5F__get_mpi_atomicity(const H5F_t *file, hbool_t *flag); +H5_DLL herr_t H5F__set_mpi_atomicity(H5F_t *file, hbool_t flag); +#endif /* H5_HAVE_PARALLEL */ + /* External file cache routines */ H5_DLL H5F_efc_t *H5F__efc_create(unsigned max_nfiles); H5_DLL H5F_t * H5F__efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 901ab7c..cef77dc 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -301,23 +301,36 @@ uint64_decode(uint8_t **pp) (p) += 8; \ } +/* clang-format off */ /* Address-related macros */ -#define H5F_addr_overflow(X, Z) \ - (HADDR_UNDEF == (X) || HADDR_UNDEF == (X) + (haddr_t)(Z) || (X) + (haddr_t)(Z) < (X)) -#define H5F_addr_defined(X) ((X) != HADDR_UNDEF) +#define H5F_addr_overflow(X,Z) (HADDR_UNDEF==(X) || \ + HADDR_UNDEF==(X)+(haddr_t)(Z) || \ + (X)+(haddr_t)(Z)<(X)) +#define H5F_addr_defined(X) ((X)!=HADDR_UNDEF) /* The H5F_addr_eq() macro guarantees that Y is not HADDR_UNDEF by making * certain that X is not HADDR_UNDEF and then checking that X equals Y */ -#define H5F_addr_eq(X, Y) ((X) != HADDR_UNDEF && (X) == (Y)) -#define H5F_addr_ne(X, Y) (!H5F_addr_eq((X), (Y))) -#define H5F_addr_lt(X, Y) ((X) != HADDR_UNDEF && (Y) != HADDR_UNDEF && (X) < (Y)) -#define H5F_addr_le(X, Y) ((X) != HADDR_UNDEF && (Y) != HADDR_UNDEF && (X) <= (Y)) -#define H5F_addr_gt(X, Y) ((X) != HADDR_UNDEF && (Y) != HADDR_UNDEF && (X) > (Y)) -#define H5F_addr_ge(X, Y) ((X) != HADDR_UNDEF && (Y) != HADDR_UNDEF && (X) >= (Y)) -#define H5F_addr_cmp(X, Y) (H5F_addr_eq((X), (Y)) ? 0 : (H5F_addr_lt((X), (Y)) ? -1 : 1)) -#define H5F_addr_pow2(N) ((haddr_t)1 << (N)) -#define H5F_addr_overlap(O1, L1, O2, L2) \ - (((O1) < (O2) && ((O1) + (L1)) > (O2)) || ((O1) >= (O2) && (O1) < ((O2) + (L2)))) +#define H5F_addr_eq(X,Y) ((X)!=HADDR_UNDEF && \ + (X)==(Y)) +#define H5F_addr_ne(X,Y) (!H5F_addr_eq((X),(Y))) +#define H5F_addr_lt(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ + (X)<(Y)) +#define H5F_addr_le(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ + (X)<=(Y)) +#define H5F_addr_gt(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ + (X)>(Y)) +#define H5F_addr_ge(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ + (X)>=(Y)) +#define H5F_addr_cmp(X,Y) (H5F_addr_eq((X), (Y)) ? 0 : \ + (H5F_addr_lt((X), (Y)) ? -1 : 1)) +#define H5F_addr_pow2(N) ((haddr_t)1<<(N)) +#define H5F_addr_overlap(O1,L1,O2,L2) (((O1) < (O2) && ((O1) + (L1)) > (O2)) || \ + ((O1) >= (O2) && (O1) < ((O2) + (L2)))) +/* clang-format on */ /* If the module using this macro is allowed access to the private variables, access them directly */ #ifdef H5F_MODULE @@ -540,18 +553,18 @@ uint64_decode(uint8_t **pp) #define H5F_DEFAULT_CSET H5T_CSET_ASCII /* ========= File Creation properties ============ */ -#define H5F_CRT_USER_BLOCK_NAME "block_size" /* Size of the file user block in bytes */ -#define H5F_CRT_SYM_LEAF_NAME "symbol_leaf" /* 1/2 rank for symbol table leaf nodes */ -#define H5F_CRT_SYM_LEAF_DEF 4 -#define H5F_CRT_BTREE_RANK_NAME "btree_rank" /* 1/2 rank for btree internal nodes */ -#define H5F_CRT_ADDR_BYTE_NUM_NAME "addr_byte_num" /* Byte number in an address */ -#define H5F_CRT_OBJ_BYTE_NUM_NAME "obj_byte_num" /* Byte number for object size */ -#define H5F_CRT_SUPER_VERS_NAME "super_version" /* Version number of the superblock */ -#define H5F_CRT_SHMSG_NINDEXES_NAME "num_shmsg_indexes" /* Number of shared object header message indexes */ +#define H5F_CRT_USER_BLOCK_NAME "block_size" /* Size of the file user block in bytes */ +#define H5F_CRT_SYM_LEAF_NAME "symbol_leaf" /* 1/2 rank for symbol table leaf nodes */ +#define H5F_CRT_SYM_LEAF_DEF 4 +#define H5F_CRT_BTREE_RANK_NAME "btree_rank" /* 1/2 rank for btree internal nodes */ +#define H5F_CRT_ADDR_BYTE_NUM_NAME "addr_byte_num" /* Byte number in an address */ +#define H5F_CRT_OBJ_BYTE_NUM_NAME "obj_byte_num" /* Byte number for object size */ +#define H5F_CRT_SUPER_VERS_NAME "super_version" /* Version number of the superblock */ +/* Number of shared object header message indexes */ +#define H5F_CRT_SHMSG_NINDEXES_NAME "num_shmsg_indexes" #define H5F_CRT_SHMSG_INDEX_TYPES_NAME "shmsg_message_types" /* Types of message in each index */ -#define H5F_CRT_SHMSG_INDEX_MINSIZE_NAME \ - "shmsg_message_minsize" /* Minimum size of messages in each index \ - */ +/* Minimum size of messages in each index */ +#define H5F_CRT_SHMSG_INDEX_MINSIZE_NAME "shmsg_message_minsize" #define H5F_CRT_SHMSG_LIST_MAX_NAME "shmsg_list_max" /* Shared message list maximum size */ #define H5F_CRT_SHMSG_BTREE_MIN_NAME "shmsg_btree_min" /* Shared message B-tree minimum size */ #define H5F_CRT_FILE_SPACE_STRATEGY_NAME "file_space_strategy" /* File space handling strategy */ @@ -598,10 +611,10 @@ uint64_decode(uint8_t **pp) #define H5F_ACS_CLEAR_STATUS_FLAGS_NAME \ "clear_status_flags" /* Whether to clear superblock status_flags (private property only used by h5clear) \ */ -#define H5F_ACS_NULL_FSM_ADDR_NAME "null_fsm_addr" /* Nullify addresses of free-space managers */ - /* Private property used only by h5clear */ -#define H5F_ACS_SKIP_EOF_CHECK_NAME "skip_eof_check" /* Skip EOF check */ - /* Private property used only by h5clear */ +#define H5F_ACS_NULL_FSM_ADDR_NAME "null_fsm_addr" /* Nullify addresses of free-space managers */ +/* Private property used only by h5clear */ +#define H5F_ACS_SKIP_EOF_CHECK_NAME "skip_eof_check" /* Skip EOF check */ +/* Private property used only by h5clear */ #define H5F_ACS_USE_MDC_LOGGING_NAME "use_mdc_logging" /* Whether to use metadata cache logging */ #define H5F_ACS_MDC_LOG_LOCATION_NAME "mdc_log_location" /* Name of metadata cache log location */ #define H5F_ACS_START_MDC_LOG_ON_ACCESS_NAME \ @@ -669,13 +682,13 @@ uint64_decode(uint8_t **pp) #define HDF5_BTREE_SNODE_IK_DEF 16 #define HDF5_BTREE_CHUNK_IK_DEF \ 32 /* Note! this value is assumed \ - to be 32 for version 0 \ - of the superblock and \ - if it is changed, the code \ - must compensate. -QAK \ - */ + to be 32 for version 0 \ + of the superblock and \ + if it is changed, the code \ + must compensate. -QAK \ + */ #define HDF5_BTREE_IK_MAX_ENTRIES 65536 /* 2^16 - 2 bytes for storing entries (children) */ - /* See format specification on version 1 B-trees */ +/* See format specification on version 1 B-trees */ /* Default file space handling strategy */ #define H5F_FILE_SPACE_STRATEGY_DEF H5F_FSPACE_STRATEGY_FSM_AGGR @@ -778,6 +791,7 @@ uint64_decode(uint8_t **pp) /* Forward declarations (for prototypes & type definitions) */ struct H5B_class_t; struct H5UC_t; +struct H5G_loc_t; struct H5O_loc_t; struct H5HG_heap_t; struct H5VL_class_t; @@ -853,7 +867,6 @@ H5_DLL herr_t H5F_init(void); H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id); H5_DLL herr_t H5F_try_close(H5F_t *f, hbool_t *was_closed /*out*/); H5_DLL hid_t H5F_get_file_id(H5VL_object_t *vol_obj, H5I_type_t obj_type, hbool_t app_ref); -H5_DLL herr_t H5F_delete(const char *filename, hid_t fapl_id); /* Functions that retrieve values from the file struct */ H5_DLL H5F_libver_t H5F_get_low_bound(const H5F_t *f); @@ -931,7 +944,12 @@ H5_DLL haddr_t H5F_shared_get_eoa(const H5F_shared_t *f_sh, H5FD_mem_t type); H5_DLL haddr_t H5F_get_eoa(const H5F_t *f, H5FD_mem_t type); H5_DLL herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void **file_handle); -/* Functions that check file mounting information */ +/* VFD SWMR functions */ +H5_DLL hbool_t H5F_use_vfd_swmr(const H5F_t *f); + +/* File mounting routines */ +H5_DLL herr_t H5F_mount(const struct H5G_loc_t *loc, const char *name, H5F_t *child, hid_t plist_id); +H5_DLL herr_t H5F_unmount(const struct H5G_loc_t *loc, const char *name); H5_DLL hbool_t H5F_is_mount(const H5F_t *file); H5_DLL hbool_t H5F_has_mount(const H5F_t *file); H5_DLL herr_t H5F_traverse_mount(struct H5O_loc_t *oloc /*in,out*/); @@ -984,8 +1002,6 @@ H5_DLL MPI_Comm H5F_mpi_get_comm(const H5F_t *f); H5_DLL int H5F_shared_mpi_get_size(const H5F_shared_t *f_sh); H5_DLL int H5F_mpi_get_size(const H5F_t *f); H5_DLL herr_t H5F_mpi_retrieve_comm(hid_t loc_id, hid_t acspl_id, MPI_Comm *mpi_comm); -H5_DLL herr_t H5F_get_mpi_atomicity(H5F_t *file, hbool_t *flag); -H5_DLL herr_t H5F_set_mpi_atomicity(H5F_t *file, hbool_t flag); #endif /* H5_HAVE_PARALLEL */ /* External file cache routines */ @@ -1005,6 +1021,4 @@ H5_DLL herr_t H5F_cwfs_remove_heap(H5F_shared_t *shared, struct H5HG_heap_t *hea /* Debugging functions */ H5_DLL herr_t H5F_debug(H5F_t *f, FILE *stream, int indent, int fwidth); -H5_DLL hbool_t H5F_use_vfd_swmr(const H5F_t *f); - #endif /* H5Fprivate_H */ diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 48bfaaa..d241816 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -1114,7 +1114,7 @@ H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr); * \since 1.8.0 * */ -H5_DLL herr_t H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr); +H5_DLL herr_t H5Fset_mdc_config(hid_t file_id, const H5AC_cache_config_t *config_ptr); /** * \ingroup MDC * @@ -1888,6 +1888,7 @@ H5_DLL herr_t H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag); H5_DLL herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag); #endif /* H5_HAVE_PARALLEL */ +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -1907,6 +1908,7 @@ H5_DLL herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag); #define H5Fflush_async_wrap H5_NO_EXPAND(H5Fflush_async) #define H5Fclose_async_wrap H5_NO_EXPAND(H5Fclose_async) #endif /* H5F_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5G.c b/src/H5G.c index 45ba023..deaf792 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -502,8 +502,9 @@ done: hid_t H5Gget_create_plist(hid_t group_id) { - H5VL_object_t *vol_obj = NULL; - hid_t ret_value = H5I_INVALID_HID; + H5VL_object_t * vol_obj; /* Object for loc_id */ + H5VL_group_get_args_t vol_cb_args; /* Arguments to VOL callback */ + hid_t ret_value = H5I_INVALID_HID; FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", group_id); @@ -512,11 +513,17 @@ H5Gget_create_plist(hid_t group_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(group_id, H5I_GROUP))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a group ID") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_GET_GCPL; + vol_cb_args.args.get_gcpl.gcpl_id = H5I_INVALID_HID; + /* Get the group creation property list for the group */ - if (H5VL_group_get(vol_obj, H5VL_GROUP_GET_GCPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &ret_value) < - 0) + if (H5VL_group_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5I_INVALID_HID, "can't get group's creation property list") + /* Set the return value */ + ret_value = vol_cb_args.args.get_gcpl.gcpl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Gget_create_plist() */ @@ -538,9 +545,9 @@ H5G__get_info_api_common(hid_t loc_id, H5G_info_t *group_info /*out*/, void **to H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - H5I_type_t id_type; /* Type of ID */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_group_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5I_type_t id_type; /* Type of ID */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -551,13 +558,14 @@ H5G__get_info_api_common(hid_t loc_id, H5G_info_t *group_info /*out*/, void **to if (!group_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL") - /* Set up object access arguments */ - if (H5VL_setup_self_args(loc_id, vol_obj_ptr, &loc_params) < 0) + /* Set up VOL callback & object access arguments */ + vol_cb_args.op_type = H5VL_GROUP_GET_INFO; + if (H5VL_setup_self_args(loc_id, vol_obj_ptr, &vol_cb_args.args.get_info.loc_params) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments") + vol_cb_args.args.get_info.ginfo = group_info; /* Retrieve group information */ - if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, - group_info) < 0) + if (H5VL_group_get(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info") done: @@ -647,8 +655,8 @@ H5G__get_info_by_name_api_common(hid_t loc_id, const char *name, H5G_info_t *gro H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_group_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -656,13 +664,15 @@ H5G__get_info_by_name_api_common(hid_t loc_id, const char *name, H5G_info_t *gro if (!group_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL") - /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + /* Set up VOL callback & object access arguments */ + vol_cb_args.op_type = H5VL_GROUP_GET_INFO; + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, vol_obj_ptr, + &vol_cb_args.args.get_info.loc_params) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments") + vol_cb_args.args.get_info.ginfo = group_info; /* Retrieve group information */ - if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, - group_info) < 0) + if (H5VL_group_get(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info") done: @@ -754,8 +764,8 @@ H5G__get_info_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_group_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -763,14 +773,15 @@ H5G__get_info_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t if (!group_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_info parameter cannot be NULL") - /* Set up object access arguments */ - if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, - &loc_params) < 0) + /* Set up VOL callback & object access arguments */ + vol_cb_args.op_type = H5VL_GROUP_GET_INFO; + if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, FALSE, lapl_id, vol_obj_ptr, + &vol_cb_args.args.get_info.loc_params) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments") + vol_cb_args.args.get_info.ginfo = group_info; /* Retrieve group information */ - if (H5VL_group_get(*vol_obj_ptr, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, - group_info) < 0) + if (H5VL_group_get(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info") done: @@ -957,8 +968,9 @@ done: herr_t H5Gflush(hid_t group_id) { - H5VL_object_t *vol_obj; /* Group for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_group_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", group_id); @@ -971,9 +983,12 @@ H5Gflush(hid_t group_id) if (H5CX_set_loc(group_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_FLUSH; + vol_cb_args.args.flush.grp_id = group_id; + /* Flush group's metadata to file */ - if (H5VL_group_specific(vol_obj, H5VL_GROUP_FLUSH, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, group_id) < - 0) + if (H5VL_group_specific(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTFLUSH, FAIL, "unable to flush group") done: @@ -995,8 +1010,9 @@ done: herr_t H5Grefresh(hid_t group_id) { - H5VL_object_t *vol_obj; /* Group for this operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_group_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", group_id); @@ -1009,9 +1025,12 @@ H5Grefresh(hid_t group_id) if (H5CX_set_loc(group_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_REFRESH; + vol_cb_args.args.refresh.grp_id = group_id; + /* Refresh group's metadata */ - if (H5VL_group_specific(vol_obj, H5VL_GROUP_REFRESH, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - group_id) < 0) + if (H5VL_group_specific(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to refresh group") done: diff --git a/src/H5Gcompact.c b/src/H5Gcompact.c index a621f6e..0c0b5db 100644 --- a/src/H5Gcompact.c +++ b/src/H5Gcompact.c @@ -200,20 +200,20 @@ done: * * Purpose: Returns the name of objects in the group by giving index. * - * Return: Success: Non-negative, length of name - * Failure: Negative + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Sep 6, 2005 * *------------------------------------------------------------------------- */ -ssize_t +herr_t H5G__compact_get_name_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, hsize_t idx, char *name, size_t size) + H5_iter_order_t order, hsize_t idx, char *name, size_t name_size, + size_t *name_len) { H5G_link_table_t ltable = {0, NULL}; /* Link table */ - ssize_t ret_value = -1; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -229,13 +229,13 @@ H5G__compact_get_name_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound") /* Get the length of the name */ - ret_value = (ssize_t)HDstrlen(ltable.lnks[idx].name); + *name_len = HDstrlen(ltable.lnks[idx].name); /* Copy the name into the user's buffer, if given */ if (name) { - HDstrncpy(name, ltable.lnks[idx].name, MIN((size_t)(ret_value + 1), size)); - if ((size_t)ret_value >= size) - name[size - 1] = '\0'; + HDstrncpy(name, ltable.lnks[idx].name, MIN((*name_len + 1), name_size)); + if (*name_len >= name_size) + name[name_size - 1] = '\0'; } /* end if */ done: diff --git a/src/H5Gdense.c b/src/H5Gdense.c index ec5cb71..753936b 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -169,7 +169,7 @@ typedef struct { size_t name_size; /* Size of name buffer to fill */ /* upward */ - ssize_t name_len; /* Full length of name */ + size_t name_len; /* Full length of name */ } H5G_bt2_ud_gnbi_t; /* @@ -185,7 +185,7 @@ typedef struct { size_t name_size; /* Size of name buffer to fill */ /* upward */ - ssize_t name_len; /* Full length of name */ + size_t name_len; /* Full length of name */ } H5G_fh_ud_gnbi_t; /* @@ -1046,12 +1046,12 @@ H5G__dense_get_name_by_idx_fh_cb(const void *obj, size_t obj_len, void *_udata) HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link") /* Get the length of the name */ - udata->name_len = (ssize_t)HDstrlen(lnk->name); + udata->name_len = HDstrlen(lnk->name); /* Copy the name into the user's buffer, if given */ if (udata->name) { - HDstrncpy(udata->name, lnk->name, MIN((size_t)(udata->name_len + 1), udata->name_size)); - if ((size_t)udata->name_len >= udata->name_size) + HDstrncpy(udata->name, lnk->name, MIN((udata->name_len + 1), udata->name_size)); + if (udata->name_len >= udata->name_size) udata->name[udata->name_size - 1] = '\0'; } /* end if */ @@ -1106,23 +1106,22 @@ done: * * Purpose: Returns the name of objects in the group by giving index. * - * Return: Success: Non-negative, length of name - * Failure: Negative + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Sep 19 2006 * *------------------------------------------------------------------------- */ -ssize_t +herr_t H5G__dense_get_name_by_idx(H5F_t *f, H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, char *name, size_t size) + hsize_t n, char *name, size_t name_size, size_t *name_len) { - H5HF_t * fheap = NULL; /* Fractal heap handle */ - H5G_link_table_t ltable = {0, NULL}; /* Table of links */ - H5B2_t * bt2 = NULL; /* v2 B-tree handle for index */ - haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ - ssize_t ret_value = -1; /* Return value */ + H5HF_t * fheap = NULL; /* Fractal heap handle */ + H5G_link_table_t ltable = {0, NULL}; /* Table of links */ + H5B2_t * bt2 = NULL; /* v2 B-tree handle for index */ + haddr_t bt2_addr; /* Address of v2 B-tree to use for lookup */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -1176,14 +1175,14 @@ H5G__dense_get_name_by_idx(H5F_t *f, H5O_linfo_t *linfo, H5_index_t idx_type, H5 udata.f = f; udata.fheap = fheap; udata.name = name; - udata.name_size = size; + udata.name_size = name_size; /* Retrieve the name according to the v2 B-tree's index order */ if (H5B2_index(bt2, order, n, H5G__dense_get_name_by_idx_bt2_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTLIST, FAIL, "can't locate object in v2 B-tree") /* Set return value */ - ret_value = udata.name_len; + *name_len = udata.name_len; } /* end if */ else { /* Otherwise, we need to build a table of the links and sort it */ /* Build the table of links for this group */ @@ -1195,13 +1194,13 @@ H5G__dense_get_name_by_idx(H5F_t *f, H5O_linfo_t *linfo, H5_index_t idx_type, H5 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound") /* Get the length of the name */ - ret_value = (ssize_t)HDstrlen(ltable.lnks[n].name); + *name_len = HDstrlen(ltable.lnks[n].name); /* Copy the name into the user's buffer, if given */ if (name) { - HDstrncpy(name, ltable.lnks[n].name, MIN((size_t)(ret_value + 1), size)); - if ((size_t)ret_value >= size) - name[size - 1] = '\0'; + HDstrncpy(name, ltable.lnks[n].name, MIN((*name_len + 1), name_size)); + if (*name_len >= name_size) + name[name_size - 1] = '\0'; } /* end if */ } /* end else */ diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index 45065e8..7c0404f 100644 --- a/src/H5Gdeprec.c +++ b/src/H5Gdeprec.c @@ -308,7 +308,8 @@ done: herr_t H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new_name) { - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "iLl*s*s", cur_loc_id, type, cur_name, new_name); @@ -326,20 +327,15 @@ H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new /* Create link */ if (type == H5L_TYPE_HARD) { H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params1; - H5VL_loc_params_t loc_params2; + H5VL_loc_params_t new_loc_params; H5VL_object_t tmp_vol_obj; /* Temporary object */ - loc_params1.type = H5VL_OBJECT_BY_NAME; - loc_params1.obj_type = H5I_get_type(cur_loc_id); - loc_params1.loc_data.loc_by_name.name = cur_name; - loc_params1.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + /* Set up new location struct */ + new_loc_params.type = H5VL_OBJECT_BY_NAME; + new_loc_params.loc_data.loc_by_name.name = new_name; + new_loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - loc_params2.type = H5VL_OBJECT_BY_NAME; - loc_params2.loc_data.loc_by_name.name = new_name; - loc_params2.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - - /* get the location object */ + /* Get the location object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(cur_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") @@ -347,16 +343,24 @@ H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new tmp_vol_obj.data = NULL; tmp_vol_obj.connector = vol_obj->connector; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_HARD; + vol_cb_args.args.hard.curr_obj = vol_obj->data; + vol_cb_args.args.hard.curr_loc_params.type = H5VL_OBJECT_BY_NAME; + vol_cb_args.args.hard.curr_loc_params.obj_type = H5I_get_type(cur_loc_id); + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.name = cur_name; + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + /* Create the link through the VOL */ - if (H5VL_link_create(H5VL_LINK_CREATE_HARD, &tmp_vol_obj, &loc_params2, H5P_LINK_CREATE_DEFAULT, - H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - vol_obj->data, &loc_params1) < 0) + if (H5VL_link_create(&vol_cb_args, &tmp_vol_obj, &new_loc_params, H5P_LINK_CREATE_DEFAULT, + H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end if */ else if (type == H5L_TYPE_SOFT) { H5VL_object_t * vol_obj; /* Object of loc_id */ H5VL_loc_params_t loc_params; + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.loc_data.loc_by_name.name = new_name; loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; @@ -366,10 +370,13 @@ H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(cur_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_SOFT; + vol_cb_args.args.soft.target = cur_name; + /* Create the link through the VOL */ - if (H5VL_link_create(H5VL_LINK_CREATE_SOFT, vol_obj, &loc_params, H5P_LINK_CREATE_DEFAULT, - H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - cur_name) < 0) + if (H5VL_link_create(&vol_cb_args, vol_obj, &loc_params, H5P_LINK_CREATE_DEFAULT, + H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end else-if */ else @@ -390,7 +397,8 @@ done: herr_t H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_id, const char *new_name) { - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*sLli*s", cur_loc_id, cur_name, type, new_loc_id, new_name); @@ -409,29 +417,31 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_ if (type == H5L_TYPE_HARD) { H5VL_object_t * vol_obj1; /* Object of loc_id */ H5VL_object_t * vol_obj2; /* Object of loc_id */ - H5VL_loc_params_t loc_params1; - H5VL_loc_params_t loc_params2; + H5VL_loc_params_t new_loc_params; - loc_params1.type = H5VL_OBJECT_BY_NAME; - loc_params1.obj_type = H5I_get_type(cur_loc_id); - loc_params1.loc_data.loc_by_name.name = cur_name; - loc_params1.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + /* Set up new location struct */ + new_loc_params.type = H5VL_OBJECT_BY_NAME; + new_loc_params.obj_type = H5I_get_type(new_loc_id); + new_loc_params.loc_data.loc_by_name.name = new_name; + new_loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - loc_params2.type = H5VL_OBJECT_BY_NAME; - loc_params2.obj_type = H5I_get_type(new_loc_id); - loc_params2.loc_data.loc_by_name.name = new_name; - loc_params2.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - - /* get the location object */ + /* Get the location objects */ if (NULL == (vol_obj1 = (H5VL_object_t *)H5I_object(cur_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") if (NULL == (vol_obj2 = (H5VL_object_t *)H5I_object(new_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_HARD; + vol_cb_args.args.hard.curr_obj = vol_obj1->data; + vol_cb_args.args.hard.curr_loc_params.type = H5VL_OBJECT_BY_NAME; + vol_cb_args.args.hard.curr_loc_params.obj_type = H5I_get_type(cur_loc_id); + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.name = cur_name; + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + /* Create the link through the VOL */ - if (H5VL_link_create(H5VL_LINK_CREATE_HARD, vol_obj2, &loc_params2, H5P_LINK_CREATE_DEFAULT, - H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - vol_obj1->data, &loc_params1) < 0) + if (H5VL_link_create(&vol_cb_args, vol_obj2, &new_loc_params, H5P_LINK_CREATE_DEFAULT, + H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end if */ else if (type == H5L_TYPE_SOFT) { @@ -443,6 +453,7 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_ if (new_loc_id == H5L_SAME_LOC) new_loc_id = cur_loc_id; + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.loc_data.loc_by_name.name = new_name; loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; @@ -452,10 +463,13 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(new_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_SOFT; + vol_cb_args.args.soft.target = cur_name; + /* Create the link through the VOL */ - if (H5VL_link_create(H5VL_LINK_CREATE_SOFT, vol_obj, &loc_params, H5P_LINK_CREATE_DEFAULT, - H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - cur_name) < 0) + if (H5VL_link_create(&vol_cb_args, vol_obj, &loc_params, H5P_LINK_CREATE_DEFAULT, + H5P_LINK_ACCESS_DEFAULT, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end else-if */ else @@ -572,9 +586,10 @@ done: herr_t H5Gunlink(hid_t loc_id, const char *name) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*s", loc_id, name); @@ -596,9 +611,11 @@ H5Gunlink(hid_t loc_id, const char *name) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_DELETE; + /* Delete the link */ - if (H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "couldn't delete link") done: @@ -616,9 +633,10 @@ done: herr_t H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf /*out*/) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*szx", loc_id, name, size, buf); @@ -631,6 +649,7 @@ H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf /*out*/) if (H5CX_set_loc(loc_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set collective metadata read info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.obj_type = H5I_get_type(loc_id); loc_params.loc_data.loc_by_name.name = name; @@ -640,9 +659,13 @@ H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf /*out*/) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_VAL; + vol_cb_args.args.get_val.buf = buf; + vol_cb_args.args.get_val.buf_size = size; + /* Get the link value */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_VAL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, buf, - size) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get link value") done: @@ -669,9 +692,11 @@ done: herr_t H5Gset_comment(hid_t loc_id, const char *name, const char *comment) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "i*s*s", loc_id, name, comment); @@ -693,9 +718,14 @@ H5Gset_comment(hid_t loc_id, const char *name, const char *comment) if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.set_comment.comment = comment; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_SET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* Set the comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_SET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, comment) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "unable to set comment value") done: @@ -728,10 +758,12 @@ done: int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf /*out*/) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t op_ret; /* Return value from operation */ - int ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + size_t comment_len = 0; /* Length of comment */ + int ret_value; /* Return value */ FUNC_ENTER_API(-1) H5TRACE4("Is", "i*szx", loc_id, name, bufsize, buf); @@ -755,13 +787,20 @@ H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf /*out*/ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, -1, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.get_comment.buf = buf; + obj_opt_args.get_comment.buf_size = bufsize; + obj_opt_args.get_comment.comment_len = &comment_len; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* Get the comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, buf, bufsize, &op_ret) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, -1, "unable to get comment value") /* Set return value */ - ret_value = (int)op_ret; + ret_value = (int)comment_len; done: FUNC_LEAVE_API(ret_value) @@ -794,12 +833,11 @@ done: herr_t H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, void *op_data) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5G_link_iterate_t lnk_op; /* Link operator */ - hsize_t last_obj; /* Index of last object looked at */ - hsize_t idx; /* Internal location to hold index */ - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_group_optional_args_t grp_opt_args; /* Arguments for optional operation */ + hsize_t last_obj = 0; /* Pointer to index value */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*s*IsGi*x", loc_id, name, idx_p, op, op_data); @@ -812,30 +850,28 @@ H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, void *o if (!op) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified") - /* Set number of objects looked at to zero */ - last_obj = 0; - idx = (hsize_t)(idx_p == NULL ? 0 : *idx_p); - - /* Build link operator info */ - lnk_op.op_type = H5G_LINK_OP_OLD; - lnk_op.op_func.op_old = op; - - /* Fill out location struct */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - loc_params.obj_type = H5I_get_type(loc_id); - /* Get the object pointer */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ID, H5E_BADTYPE, (-1), "invalid identifier") + /* Set up VOL callback arguments */ + grp_opt_args.iterate_old.loc_params.type = H5VL_OBJECT_BY_NAME; + grp_opt_args.iterate_old.loc_params.loc_data.loc_by_name.name = name; + grp_opt_args.iterate_old.loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + grp_opt_args.iterate_old.loc_params.obj_type = H5I_get_type(loc_id); + grp_opt_args.iterate_old.idx = (hsize_t)(idx_p == NULL ? 0 : *idx_p); + grp_opt_args.iterate_old.last_obj = &last_obj; + grp_opt_args.iterate_old.op = op; + grp_opt_args.iterate_old.op_data = op_data; + vol_cb_args.op_type = H5VL_NATIVE_GROUP_ITERATE_OLD; + vol_cb_args.args = &grp_opt_args; + /* Call private iteration function, through VOL callback */ - if ((ret_value = H5VL_group_optional(vol_obj, H5VL_NATIVE_GROUP_ITERATE_OLD, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, idx, &last_obj, &lnk_op, op_data)) < 0) + if ((ret_value = H5VL_group_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)) < + 0) HERROR(H5E_SYM, H5E_BADITER, "error iterating over group's links"); - /* Set the index we stopped at */ + /* Set value to return */ if (idx_p) *idx_p = (int)last_obj; @@ -862,11 +898,11 @@ done: herr_t H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs /*out*/) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5I_type_t id_type; /* Type of ID */ - H5VL_loc_params_t loc_params; - H5G_info_t grp_info; /* Group information */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_group_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5I_type_t id_type; /* Type of ID */ + H5G_info_t grp_info; /* Group information */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "ix", loc_id, num_objs); @@ -878,17 +914,14 @@ H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs /*out*/) if (!num_objs) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad pointer to # of objects") - /* Fill in location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = id_type; - - /* Get group location */ - if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback & object access arguments */ + vol_cb_args.op_type = H5VL_GROUP_GET_INFO; + if (H5VL_setup_self_args(loc_id, &vol_obj, &vol_cb_args.args.get_info.loc_params) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set object access arguments") + vol_cb_args.args.get_info.ginfo = &grp_info; /* Retrieve the group's information */ - if (H5VL_group_get(vol_obj, H5VL_GROUP_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, - &grp_info) < 0) + if (H5VL_group_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get group info") /* Set the number of objects [i.e. links] in the group */ @@ -918,9 +951,10 @@ done: herr_t H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, H5G_stat_t *statbuf /*out*/) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_group_optional_args_t grp_opt_args; /* Arguments for optional operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE4("e", "i*sbx", loc_id, name, follow_link, statbuf); @@ -933,20 +967,22 @@ H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, H5G_stat_t * if (H5CX_set_loc(loc_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set collective metadata read info"); - /* Retrieve object info */ - /* Fill out location struct */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - loc_params.obj_type = H5I_get_type(loc_id); - /* Get the location object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier"); + /* Set up VOL callback arguments */ + grp_opt_args.get_objinfo.loc_params.type = H5VL_OBJECT_BY_NAME; + grp_opt_args.get_objinfo.loc_params.loc_data.loc_by_name.name = name; + grp_opt_args.get_objinfo.loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + grp_opt_args.get_objinfo.loc_params.obj_type = H5I_get_type(loc_id); + grp_opt_args.get_objinfo.follow_link = follow_link; + grp_opt_args.get_objinfo.statbuf = statbuf; + vol_cb_args.op_type = H5VL_NATIVE_GROUP_GET_OBJINFO; + vol_cb_args.args = &grp_opt_args; + /* Retrieve the object's information */ - if (H5VL_group_optional(vol_obj, H5VL_NATIVE_GROUP_GET_OBJINFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &loc_params, (unsigned)follow_link, statbuf) < 0) + if (H5VL_group_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get info for object: '%s'", name); done: @@ -1138,9 +1174,11 @@ done: ssize_t H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name /*out*/, size_t size) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + size_t name_len = 0; /* Length of object name */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("Zs", "ihxz", loc_id, idx, name, size); @@ -1149,7 +1187,7 @@ H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name /*out*/, size_t size if (H5CX_set_loc(loc_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSET, (-1), "can't set collective metadata read info") - /* Fill in location struct fields */ + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = "."; loc_params.loc_data.loc_by_idx.idx_type = H5_INDEX_NAME; @@ -1162,11 +1200,19 @@ H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name /*out*/, size_t size if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_NAME; + vol_cb_args.args.get_name.name_size = size; + vol_cb_args.args.get_name.name = name; + vol_cb_args.args.get_name.name_len = &name_len; + /* Call internal function */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - name, size, &ret_value) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, (-1), "can't get object name") + /* Set the return value */ + ret_value = (ssize_t)name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Gget_objname_by_idx() */ @@ -1189,10 +1235,11 @@ done: H5G_obj_t H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_info2_t oinfo; /* Object info (contains object type) */ - H5G_obj_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5O_info2_t oinfo; /* Object info (contains object type) */ + H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_API(H5G_UNKNOWN) H5TRACE2("Go", "ih", loc_id, idx); @@ -1210,9 +1257,13 @@ H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx) if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = &oinfo; + vol_cb_args.args.get_info.fields = H5O_INFO_BASIC; + /* Retrieve the object's basic information (which includes its type) */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &oinfo, H5O_INFO_BASIC) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, H5G_UNKNOWN, "can't get object info") /* Map to group object type */ diff --git a/src/H5Gloc.c b/src/H5Gloc.c index 7d08b54..2844c66 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -53,12 +53,6 @@ typedef struct { H5G_loc_t *loc; /* Group location to set */ } H5G_loc_fnd_t; -/* User data for checking if an object exists */ -typedef struct { - /* upward */ - htri_t exists; /* Whether the object exists */ -} H5G_loc_exists_t; - /* User data for looking up an object in a group by index */ typedef struct { /* downward */ @@ -103,7 +97,7 @@ typedef struct { size_t bufsize; /* Size of object comment buffer */ /* upward */ - ssize_t comment_size; /* Actual size of object comment */ + size_t comment_size; /* Actual size of object comment */ } H5G_loc_gc_t; /********************/ @@ -616,24 +610,26 @@ H5G__loc_exists_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ATTR_ const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata /*in,out*/, H5G_own_loc_t *own_loc /*out*/) { - H5G_loc_exists_t *udata = (H5G_loc_exists_t *)_udata; /* User data passed in */ + hbool_t *exists = (hbool_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC_NOERR + FUNC_ENTER_STATIC /* Check if the name in this group resolved to a valid object */ if (obj_loc == NULL) if (lnk) - udata->exists = FALSE; + *exists = FALSE; else - udata->exists = FAIL; + HGOTO_ERROR(H5E_SYM, H5E_INTERNAL, FAIL, "no object or link info?") else - udata->exists = TRUE; + *exists = TRUE; /* Indicate that this callback didn't take ownership of the group * * location for the object */ *own_loc = H5G_OWN_NONE; - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G__loc_exists_cb() */ /*------------------------------------------------------------------------- @@ -649,28 +645,22 @@ H5G__loc_exists_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ATTR_ * *------------------------------------------------------------------------- */ -htri_t -H5G_loc_exists(const H5G_loc_t *loc, const char *name) +herr_t +H5G_loc_exists(const H5G_loc_t *loc, const char *name, hbool_t *exists) { - H5G_loc_exists_t udata; /* User data for traversal callback */ - htri_t ret_value = FAIL; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Check args. */ HDassert(loc); HDassert(name && *name); - - /* Set up user data for locating object */ - udata.exists = FALSE; + HDassert(exists); /* Traverse group hierarchy to locate object */ - if (H5G_traverse(loc, name, H5G_TARGET_EXISTS, H5G__loc_exists_cb, &udata) < 0) + if (H5G_traverse(loc, name, H5G_TARGET_EXISTS, H5G__loc_exists_cb, exists) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't check if object exists") - /* Set return value */ - ret_value = udata.exists; - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_exists() */ @@ -1024,7 +1014,7 @@ H5G__loc_get_comment_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ else { if (udata->comment && udata->bufsize) HDstrncpy(udata->comment, comment.s, udata->bufsize); - udata->comment_size = (ssize_t)HDstrlen(comment.s); + udata->comment_size = HDstrlen(comment.s); H5O_msg_reset(H5O_NAME_ID, &comment); } @@ -1043,22 +1033,19 @@ done: * Purpose: Retrieve the information for an object from a group location * and path to that object * - * Return: Success: Number of bytes in the comment excluding the - * null terminator. Zero if the object has no - * comment. - * - * Failure: Negative + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Thursday, August 30, 2007 * *------------------------------------------------------------------------- */ -ssize_t -H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, char *comment /*out*/, size_t bufsize) +herr_t +H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, char *comment /*out*/, size_t bufsize, + size_t *comment_len) { - H5G_loc_gc_t udata; /* User data for traversal callback */ - ssize_t ret_value = -1; /* Return value */ + H5G_loc_gc_t udata; /* User data for traversal callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1069,14 +1056,15 @@ H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, char *comment /*out* /* Set up user data for locating object */ udata.comment = comment; udata.bufsize = bufsize; - udata.comment_size = (-1); + udata.comment_size = 0; /* Traverse group hierarchy to locate object */ if (H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G__loc_get_comment_cb, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") - /* Set the return value */ - ret_value = udata.comment_size; + /* Set value to return */ + if (comment_len) + *comment_len = udata.comment_size; done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Gmodule.h b/src/H5Gmodule.h index fe26bd2..a0e121d 100644 --- a/src/H5Gmodule.h +++ b/src/H5Gmodule.h @@ -29,8 +29,29 @@ #define H5_MY_PKG_ERR H5E_SYM #define H5_MY_PKG_INIT YES -/** - * \defgroup H5G H5G +/** \defgroup H5G H5G + * + * Use the functions in this module to manage HDF5 groups. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5G_examples.c create + * </td> + * <td> + * \snippet{lineno} H5G_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5G_examples.c update + * </td> + * <td> + * \snippet{lineno} H5G_examples.c delete + * </td> + * </tr> + * </table> * * \details \Bold{Groups in HDF5:} A group associates names with objects and * provides a mechanism for mapping a name to an object. Since all diff --git a/src/H5Gname.c b/src/H5Gname.c index 2465f01..c139a4e 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -468,11 +468,10 @@ H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth) * *------------------------------------------------------------------------- */ -ssize_t -H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, hbool_t *cached) +herr_t +H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, size_t *name_len, hbool_t *cached) { - ssize_t len = 0; /* Length of object's name */ - ssize_t ret_value = -1; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -481,14 +480,20 @@ H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, hbool_t *cac /* If the user path is available and it's not "hidden", use it */ if (loc->path->user_path_r != NULL && loc->path->obj_hidden == 0) { + size_t len; /* Length of object's name */ + len = H5RS_len(loc->path->user_path_r); if (name) { - HDstrncpy(name, H5RS_get_str(loc->path->user_path_r), MIN((size_t)(len + 1), size)); - if ((size_t)len >= size) + HDstrncpy(name, H5RS_get_str(loc->path->user_path_r), MIN((len + 1), size)); + if (len >= size) name[size - 1] = '\0'; } /* end if */ + /* Set name length, if requested */ + if (name_len) + *name_len = len; + /* Indicate that the name is cached, if requested */ /* (Currently only used for testing - QAK, 2010/07/26) */ if (cached) @@ -496,7 +501,7 @@ H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, hbool_t *cac } /* end if */ else if (!loc->path->obj_hidden) { /* Search for name of object */ - if ((len = H5G_get_name_by_addr(loc->oloc->file, loc->oloc, name, size)) < 0) + if (H5G_get_name_by_addr(loc->oloc->file, loc->oloc, name, size, name_len) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't determine name") /* Indicate that the name is _not_ cached, if requested */ @@ -505,9 +510,6 @@ H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, hbool_t *cac *cached = FALSE; } /* end else */ - /* Set return value */ - ret_value = len; - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_get_name() */ @@ -1152,28 +1154,29 @@ done: * *------------------------------------------------------------------------- */ -ssize_t -H5G_get_name_by_addr(H5F_t *f, const H5O_loc_t *loc, char *name, size_t size) +herr_t +H5G_get_name_by_addr(H5F_t *f, const H5O_loc_t *loc, char *name, size_t size, size_t *name_len) { - H5G_gnba_iter_t udata; /* User data for iteration */ - H5G_loc_t root_loc; /* Root group's location */ - hbool_t found_obj = FALSE; /* If we found the object */ - herr_t status; /* Status from iteration */ - ssize_t ret_value = -1; /* Return value */ + H5G_gnba_iter_t udata; /* User data for iteration */ + size_t len; /* Length of path name */ + H5G_loc_t root_loc; /* Root group's location */ + hbool_t found_obj = FALSE; /* If we found the object */ + herr_t status; /* Status from iteration */ + herr_t ret_value = SUCCEED; /* Return value */ /* Portably clear udata struct (before FUNC_ENTER) */ HDmemset(&udata, 0, sizeof(udata)); - FUNC_ENTER_NOAPI((-1)) + FUNC_ENTER_NOAPI(FAIL) /* Construct a group location for root group of the file */ if (H5G_root_loc(f, &root_loc) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, (-1), "can't get root group's location") + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get root group's location") /* Check for root group being the object looked for */ if (root_loc.oloc->addr == loc->addr && root_loc.oloc->file == loc->file) { if (NULL == (udata.path = H5MM_strdup(""))) - HGOTO_ERROR(H5E_SYM, H5E_CANTALLOC, (-1), "can't duplicate path string") + HGOTO_ERROR(H5E_SYM, H5E_CANTALLOC, FAIL, "can't duplicate path string") found_obj = TRUE; } /* end if */ else { @@ -1184,7 +1187,7 @@ H5G_get_name_by_addr(H5F_t *f, const H5O_loc_t *loc, char *name, size_t size) /* Visit all the links in the file */ if ((status = H5G_visit(&root_loc, "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5G__get_name_by_addr_cb, &udata)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_BADITER, (-1), "group traversal failed while looking for object name") + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group traversal failed while looking for object name") else if (status > 0) found_obj = TRUE; } /* end else */ @@ -1192,7 +1195,7 @@ H5G_get_name_by_addr(H5F_t *f, const H5O_loc_t *loc, char *name, size_t size) /* Check for finding the object */ if (found_obj) { /* Set the length of the full path */ - ret_value = (ssize_t)(HDstrlen(udata.path) + 1); /* Length of path + 1 (for "/") */ + len = HDstrlen(udata.path) + 1; /* Length of path + 1 (for "/") */ /* If there's a buffer provided, copy into it, up to the limit of its size */ if (name) { @@ -1202,12 +1205,16 @@ H5G_get_name_by_addr(H5F_t *f, const H5O_loc_t *loc, char *name, size_t size) /* Append the rest of the path */ /* (less one character, for the initial path separator) */ HDstrncat(name, udata.path, (size - 2)); - if ((size_t)ret_value >= size) + if (len >= size) name[size - 1] = '\0'; } /* end if */ } /* end if */ else - ret_value = 0; + len = 0; + + /* Set path name length, if given */ + if (name_len) + *name_len = len; done: /* Release resources */ diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 1ca6b14..66917c2 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -767,13 +767,13 @@ done: * *------------------------------------------------------------------------- */ -ssize_t +herr_t H5G_obj_get_name_by_idx(const H5O_loc_t *oloc, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, - char *name, size_t size) + char *name, size_t name_size, size_t *name_len) { - H5O_linfo_t linfo; /* Link info message */ - htri_t linfo_exists; /* Whether the link info message exists */ - ssize_t ret_value = -1; /* Return value */ + H5O_linfo_t linfo; /* Link info message */ + htri_t linfo_exists; /* Whether the link info message exists */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_TAG(oloc->addr, FAIL) @@ -785,22 +785,21 @@ H5G_obj_get_name_by_idx(const H5O_loc_t *oloc, H5_index_t idx_type, H5_iter_orde HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check for link info message") if (linfo_exists) { /* Check for creation order tracking, if creation order index lookup requested */ - if (idx_type == H5_INDEX_CRT_ORDER) { + if (idx_type == H5_INDEX_CRT_ORDER) /* Check if creation order is tracked */ if (!linfo.track_corder) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "creation order not tracked for links in group") - } /* end if */ /* Check for dense link storage */ if (H5F_addr_defined(linfo.fheap_addr)) { /* Get the object's name from the dense link storage */ - if ((ret_value = H5G__dense_get_name_by_idx(oloc->file, &linfo, idx_type, order, n, name, size)) < - 0) + if (H5G__dense_get_name_by_idx(oloc->file, &linfo, idx_type, order, n, name, name_size, + name_len) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") } /* end if */ else { /* Get the object's name from the link messages */ - if ((ret_value = H5G__compact_get_name_by_idx(oloc, &linfo, idx_type, order, n, name, size)) < 0) + if (H5G__compact_get_name_by_idx(oloc, &linfo, idx_type, order, n, name, name_size, name_len) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") } /* end else */ } /* end if */ @@ -810,7 +809,7 @@ H5G_obj_get_name_by_idx(const H5O_loc_t *oloc, H5_index_t idx_type, H5_iter_orde HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "no creation order index to query") /* Get the object's name from the symbol table */ - if ((ret_value = H5G__stab_get_name_by_idx(oloc, order, n, name, size)) < 0) + if (H5G__stab_get_name_by_idx(oloc, order, n, name, name_size, name_len) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name") } /* end else */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index a5efd48..d108b03 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -358,14 +358,14 @@ H5_DLL herr_t H5G__stab_iterate(const H5O_loc_t *oloc, H5_iter_order_t order, hs H5G_lib_iterate_t op, void *op_data); H5_DLL herr_t H5G__stab_count(const struct H5O_loc_t *oloc, hsize_t *num_objs); H5_DLL herr_t H5G__stab_bh_size(H5F_t *f, const H5O_stab_t *stab, H5_ih_info_t *bh_info); -H5_DLL ssize_t H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char *name, - size_t size); -H5_DLL herr_t H5G__stab_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); -H5_DLL herr_t H5G__stab_remove_by_idx(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, - H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk); -H5_DLL herr_t H5G__stab_lookup_by_idx(const H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, - H5O_link_t *lnk); +H5_DLL herr_t H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char *name, + size_t name_size, size_t *name_len); +H5_DLL herr_t H5G__stab_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); +H5_DLL herr_t H5G__stab_remove_by_idx(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, + H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, H5O_link_t *lnk); +H5_DLL herr_t H5G__stab_lookup_by_idx(const H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, + H5O_link_t *lnk); #ifndef H5_STRICT_FORMAT_CHECKS H5_DLL herr_t H5G__stab_valid(H5O_loc_t *grp_oloc, H5O_stab_t *alt_stab); #endif /* H5_STRICT_FORMAT_CHECKS */ @@ -405,41 +405,42 @@ H5_DLL herr_t H5G__link_release_table(H5G_link_table_t *ltable); H5_DLL herr_t H5G__link_name_replace(H5F_t *file, H5RS_str_t *grp_full_path_r, const H5O_link_t *lnk); /* Functions that understand "compact" link storage */ -H5_DLL herr_t H5G__compact_insert(const H5O_loc_t *grp_oloc, H5O_link_t *obj_lnk); -H5_DLL ssize_t H5G__compact_get_name_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, - H5_index_t idx_type, H5_iter_order_t order, hsize_t idx, - char *name, size_t size); -H5_DLL herr_t H5G__compact_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); -H5_DLL herr_t H5G__compact_remove_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, - H5RS_str_t *grp_full_path_r, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5G__compact_iterate(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, - H5G_lib_iterate_t op, void *op_data); -H5_DLL herr_t H5G__compact_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, - H5O_link_t *lnk); +H5_DLL herr_t H5G__compact_insert(const H5O_loc_t *grp_oloc, H5O_link_t *obj_lnk); +H5_DLL herr_t H5G__compact_get_name_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, + H5_index_t idx_type, H5_iter_order_t order, hsize_t idx, + char *name, size_t name_size, size_t *name_len); +H5_DLL herr_t H5G__compact_remove(const H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); +H5_DLL herr_t H5G__compact_remove_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, + H5RS_str_t *grp_full_path_r, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5G__compact_iterate(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, + H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, + H5G_lib_iterate_t op, void *op_data); +H5_DLL herr_t H5G__compact_lookup(const H5O_loc_t *grp_oloc, const char *name, hbool_t *found, + H5O_link_t *lnk); H5_DLL herr_t H5G__compact_lookup_by_idx(const H5O_loc_t *oloc, const H5O_linfo_t *linfo, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_link_t *lnk); /* Functions that understand "dense" link storage */ -H5_DLL herr_t H5G__dense_build_table(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, H5G_link_table_t *ltable); -H5_DLL herr_t H5G__dense_create(H5F_t *f, H5O_linfo_t *linfo, const H5O_pline_t *pline); -H5_DLL herr_t H5G__dense_insert(H5F_t *f, const H5O_linfo_t *linfo, const H5O_link_t *lnk); -H5_DLL herr_t H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, hbool_t *found, - H5O_link_t *lnk); -H5_DLL herr_t H5G__dense_lookup_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5O_link_t *lnk); -H5_DLL herr_t H5G__dense_iterate(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, - void *op_data); -H5_DLL ssize_t H5G__dense_get_name_by_idx(H5F_t *f, H5O_linfo_t *linfo, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, char *name, size_t size); -H5_DLL herr_t H5G__dense_remove(H5F_t *f, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, - const char *name); -H5_DLL herr_t H5G__dense_remove_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, - H5_index_t idx_type, H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5G__dense_delete(H5F_t *f, H5O_linfo_t *linfo, hbool_t adj_link); +H5_DLL herr_t H5G__dense_build_table(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, + H5_iter_order_t order, H5G_link_table_t *ltable); +H5_DLL herr_t H5G__dense_create(H5F_t *f, H5O_linfo_t *linfo, const H5O_pline_t *pline); +H5_DLL herr_t H5G__dense_insert(H5F_t *f, const H5O_linfo_t *linfo, const H5O_link_t *lnk); +H5_DLL herr_t H5G__dense_lookup(H5F_t *f, const H5O_linfo_t *linfo, const char *name, hbool_t *found, + H5O_link_t *lnk); +H5_DLL herr_t H5G__dense_lookup_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5O_link_t *lnk); +H5_DLL herr_t H5G__dense_iterate(H5F_t *f, const H5O_linfo_t *linfo, H5_index_t idx_type, + H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, + void *op_data); +H5_DLL herr_t H5G__dense_get_name_by_idx(H5F_t *f, H5O_linfo_t *linfo, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, char *name, size_t name_size, + size_t *name_len); +H5_DLL herr_t H5G__dense_remove(H5F_t *f, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, + const char *name); +H5_DLL herr_t H5G__dense_remove_by_idx(H5F_t *f, const H5O_linfo_t *linfo, H5RS_str_t *grp_full_path_r, + H5_index_t idx_type, H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5G__dense_delete(H5F_t *f, H5O_linfo_t *linfo, hbool_t adj_link); /* Functions that understand group objects */ H5_DLL herr_t H5G__obj_create(H5F_t *f, H5G_obj_create_t *gcrt_info, H5O_loc_t *oloc /*out*/); diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 409d790..4cf4623 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -144,7 +144,7 @@ struct H5O_link_t; * The "location" of an object in a group hierarchy. This points to an object * location and a group hierarchy path for the object. */ -typedef struct { +typedef struct H5G_loc_t { struct H5O_loc_t *oloc; /* Object header location */ H5G_name_t * path; /* Group hierarchy path */ } H5G_loc_t; @@ -227,16 +227,17 @@ H5_DLL herr_t H5G_link_to_info(const struct H5O_loc_t *link_loc, const struct H5 /* * Functions that understand group objects */ -H5_DLL herr_t H5G_obj_insert(const struct H5O_loc_t *grp_oloc, const char *name, struct H5O_link_t *obj_lnk, - hbool_t adj_link, H5O_type_t obj_type, const void *crt_info); -H5_DLL ssize_t H5G_obj_get_name_by_idx(const struct H5O_loc_t *oloc, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, char *name, size_t size); -H5_DLL herr_t H5G_obj_remove(const struct H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); -H5_DLL herr_t H5G_obj_remove_by_idx(const struct H5O_loc_t *grp_oloc, H5RS_str_t *grp_full_path_r, - H5_index_t idx_type, H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5G_obj_lookup_by_idx(const struct H5O_loc_t *grp_oloc, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, struct H5O_link_t *lnk); -H5_DLL hid_t H5G_get_create_plist(const H5G_t *grp); +H5_DLL herr_t H5G_obj_insert(const struct H5O_loc_t *grp_oloc, const char *name, struct H5O_link_t *obj_lnk, + hbool_t adj_link, H5O_type_t obj_type, const void *crt_info); +H5_DLL herr_t H5G_obj_get_name_by_idx(const struct H5O_loc_t *oloc, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, char *name, size_t name_size, + size_t *name_len); +H5_DLL herr_t H5G_obj_remove(const struct H5O_loc_t *oloc, H5RS_str_t *grp_full_path_r, const char *name); +H5_DLL herr_t H5G_obj_remove_by_idx(const struct H5O_loc_t *grp_oloc, H5RS_str_t *grp_full_path_r, + H5_index_t idx_type, H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5G_obj_lookup_by_idx(const struct H5O_loc_t *grp_oloc, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, struct H5O_link_t *lnk); +H5_DLL hid_t H5G_get_create_plist(const H5G_t *grp); /* * These functions operate on symbol table nodes. @@ -253,35 +254,37 @@ H5_DLL herr_t H5G_ent_decode(const H5F_t *f, const uint8_t **pp, H5G_entry_t *en /* * These functions operate on group hierarchy names. */ -H5_DLL herr_t H5G_name_set(const H5G_name_t *loc, H5G_name_t *obj, const char *name); -H5_DLL herr_t H5G_name_replace(const struct H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file, - H5RS_str_t *src_full_path_r, H5F_t *dst_file, H5RS_str_t *dst_full_path_r); -H5_DLL herr_t H5G_name_reset(H5G_name_t *name); -H5_DLL herr_t H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth); -H5_DLL herr_t H5G_name_free(H5G_name_t *name); -H5_DLL ssize_t H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, hbool_t *cached); -H5_DLL ssize_t H5G_get_name_by_addr(H5F_t *f, const struct H5O_loc_t *loc, char *name, size_t size); +H5_DLL herr_t H5G_name_set(const H5G_name_t *loc, H5G_name_t *obj, const char *name); +H5_DLL herr_t H5G_name_replace(const struct H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file, + H5RS_str_t *src_full_path_r, H5F_t *dst_file, H5RS_str_t *dst_full_path_r); +H5_DLL herr_t H5G_name_reset(H5G_name_t *name); +H5_DLL herr_t H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth); +H5_DLL herr_t H5G_name_free(H5G_name_t *name); +H5_DLL herr_t H5G_get_name(const H5G_loc_t *loc, char *name /*out*/, size_t size, size_t *name_len, + hbool_t *cached); +H5_DLL herr_t H5G_get_name_by_addr(H5F_t *f, const struct H5O_loc_t *loc, char *name, size_t size, + size_t *name_len); H5_DLL H5RS_str_t *H5G_build_fullpath_refstr_str(H5RS_str_t *path_r, const char *name); /* * These functions operate on group "locations" */ -H5_DLL herr_t H5G_loc_real(void *obj, H5I_type_t type, H5G_loc_t *loc); -H5_DLL herr_t H5G_loc(hid_t loc_id, H5G_loc_t *loc); -H5_DLL herr_t H5G_loc_copy(H5G_loc_t *dst, const H5G_loc_t *src, H5_copy_depth_t depth); -H5_DLL herr_t H5G_loc_find(const H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc /*out*/); -H5_DLL herr_t H5G_loc_find_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5G_loc_t *obj_loc /*out*/); -H5_DLL htri_t H5G_loc_exists(const H5G_loc_t *loc, const char *name); -H5_DLL herr_t H5G_loc_info(const H5G_loc_t *loc, const char *name, H5O_info2_t *oinfo /*out*/, - unsigned fields); -H5_DLL herr_t H5G_loc_native_info(const H5G_loc_t *loc, const char *name, H5O_native_info_t *oinfo /*out*/, - unsigned fields); -H5_DLL herr_t H5G_loc_set_comment(const H5G_loc_t *loc, const char *name, const char *comment); -H5_DLL ssize_t H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, char *comment /*out*/, - size_t bufsize); -H5_DLL herr_t H5G_loc_reset(H5G_loc_t *loc); -H5_DLL herr_t H5G_loc_free(H5G_loc_t *loc); +H5_DLL herr_t H5G_loc_real(void *obj, H5I_type_t type, H5G_loc_t *loc); +H5_DLL herr_t H5G_loc(hid_t loc_id, H5G_loc_t *loc); +H5_DLL herr_t H5G_loc_copy(H5G_loc_t *dst, const H5G_loc_t *src, H5_copy_depth_t depth); +H5_DLL herr_t H5G_loc_find(const H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc /*out*/); +H5_DLL herr_t H5G_loc_find_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5G_loc_t *obj_loc /*out*/); +H5_DLL herr_t H5G_loc_exists(const H5G_loc_t *loc, const char *name, hbool_t *exists); +H5_DLL herr_t H5G_loc_info(const H5G_loc_t *loc, const char *name, H5O_info2_t *oinfo /*out*/, + unsigned fields); +H5_DLL herr_t H5G_loc_native_info(const H5G_loc_t *loc, const char *name, H5O_native_info_t *oinfo /*out*/, + unsigned fields); +H5_DLL herr_t H5G_loc_set_comment(const H5G_loc_t *loc, const char *name, const char *comment); +H5_DLL herr_t H5G_loc_get_comment(const H5G_loc_t *loc, const char *name, char *comment /*out*/, + size_t bufsize, size_t *comment_len); +H5_DLL herr_t H5G_loc_reset(H5G_loc_t *loc); +H5_DLL herr_t H5G_loc_free(H5G_loc_t *loc); /* * These functions operate on the root group diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index b009d41..d9c29f6 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -467,6 +467,7 @@ H5_DLL herr_t H5Gclose(hid_t group_id); H5_DLL herr_t H5Gclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id, hid_t es_id); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -488,6 +489,7 @@ H5_DLL herr_t H5Gclose_async(const char *app_file, const char *app_func, unsigne #define H5Gget_info_by_idx_async_wrap H5_NO_EXPAND(H5Gget_info_by_idx_async) #define H5Gclose_async_wrap H5_NO_EXPAND(H5Gclose_async) #endif /* H5G_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5Gstab.c b/src/H5Gstab.c index bf4b417..ca74aa5 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -705,22 +705,22 @@ done: * * Purpose: Returns the name of objects in the group by giving index. * - * Return: Success: Non-negative, length of name - * Failure: Negative + * Return: Non-negative on success/Negative on failure * * Programmer: Raymond Lu * Nov 20, 2002 * *------------------------------------------------------------------------- */ -ssize_t -H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char *name, size_t size) +herr_t +H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char *name, + size_t name_size, size_t *name_len) { - H5HL_t * heap = NULL; /* Pointer to local heap */ - H5O_stab_t stab; /* Info about local heap & B-tree */ - H5G_bt_it_gnbi_t udata; /* Iteration information */ - hbool_t udata_valid = FALSE; /* Whether iteration information is valid */ - ssize_t ret_value = -1; /* Return value */ + H5HL_t * heap = NULL; /* Pointer to local heap */ + H5O_stab_t stab; /* Info about local heap & B-tree */ + H5G_bt_it_gnbi_t udata; /* Iteration information */ + hbool_t udata_valid = FALSE; /* Whether iteration information is valid */ + herr_t ret_value = SUCCEED; /* Return value */ /* Portably clear udata struct (before FUNC_ENTER) */ HDmemset(&udata, 0, sizeof(udata)); @@ -767,13 +767,13 @@ H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound") /* Get the length of the name */ - ret_value = (ssize_t)HDstrlen(udata.name); + *name_len = HDstrlen(udata.name); /* Copy the name into the user's buffer, if given */ if (name) { - HDstrncpy(name, udata.name, MIN((size_t)(ret_value + 1), size)); - if ((size_t)ret_value >= size) - name[size - 1] = '\0'; + HDstrncpy(name, udata.name, MIN((*name_len + 1), name_size)); + if (*name_len >= name_size) + name[name_size - 1] = '\0'; } /* end if */ done: diff --git a/src/H5Gtest.c b/src/H5Gtest.c index 9f0dca2..7ae41ed 100644 --- a/src/H5Gtest.c +++ b/src/H5Gtest.c @@ -616,14 +616,14 @@ H5G__user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsign /* Retrieve a copy of the user path and put it into the buffer */ if (obj_path->user_path_r) { - ssize_t len = H5RS_len(obj_path->user_path_r); + size_t len = H5RS_len(obj_path->user_path_r); /* Set the user path, if given */ if (user_path) - HDstrncpy(user_path, H5RS_get_str(obj_path->user_path_r), (size_t)(len + 1)); + HDstrncpy(user_path, H5RS_get_str(obj_path->user_path_r), (len + 1)); /* Set the length of the path */ - *user_path_len = (size_t)len; + *user_path_len = len; /* Set the user path hidden flag */ *obj_hidden = obj_path->obj_hidden; diff --git a/src/H5I.c b/src/H5I.c index 1973354..954a86b 100644 --- a/src/H5I.c +++ b/src/H5I.c @@ -925,9 +925,11 @@ done: ssize_t H5Iget_name(hid_t id, char *name /*out*/, size_t size) { - H5VL_object_t * vol_obj = NULL; /* Object stored in ID */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object stored in ID */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + size_t obj_name_len = 0; /* Length of object's name */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "ixz", id, name, size); @@ -940,11 +942,19 @@ H5Iget_name(hid_t id, char *name /*out*/, size_t size) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_NAME; + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = name; + vol_cb_args.args.get_name.name_len = &obj_name_len; + /* Retrieve object's name */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value, name, size) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTGET, (-1), "can't retrieve object name") + /* Set return value */ + ret_value = (ssize_t)obj_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Iget_name() */ diff --git a/src/H5Idbg.c b/src/H5Idbg.c index 7b5eb5a..8bf8ecb 100644 --- a/src/H5Idbg.c +++ b/src/H5Idbg.c @@ -110,9 +110,9 @@ H5I__id_dump_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) case H5I_DATATYPE: { const H5T_t *dt = (const H5T_t *)info->object; - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") object = (void *)H5T_get_actual_type((H5T_t *)dt); /* Casting away const OK - QAK */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") path = H5T_nameof((const H5T_t *)object); break; diff --git a/src/H5Iint.c b/src/H5Iint.c index 164fafc..86a2810 100644 --- a/src/H5Iint.c +++ b/src/H5Iint.c @@ -391,7 +391,7 @@ H5I__mark_node(void *_info, void H5_ATTR_UNUSED *key, void *_udata) */ if (udata->force || (info->count - (!udata->app_ref * info->app_count)) <= 1) { /* Check if this is an un-realized future object */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") if (info->is_future) { /* Discard the future object */ if ((info->discard_cb)((void *)info->object) < 0) { @@ -437,7 +437,7 @@ H5I__mark_node(void *_info, void H5_ATTR_UNUSED *key, void *_udata) mark = TRUE; } } - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Remove ID if requested */ if (mark) { @@ -705,9 +705,9 @@ H5I_subst(hid_t id, const void *new_object) HGOTO_ERROR(H5E_ID, H5E_NOTFOUND, NULL, "can't get ID ref count") /* Get the old object pointer to return */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") ret_value = (void *)info->object; /* (Casting away const OK -QAK) */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Set the new object pointer for the ID */ info->object = new_object; @@ -739,9 +739,9 @@ H5I_object(hid_t id) /* General lookup of the ID */ if (NULL != (info = H5I__find_id(id))) { /* Get the object pointer to return */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") ret_value = (void *)info->object; /* (Casting away const OK -QAK) */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") } FUNC_LEAVE_NOAPI(ret_value) @@ -775,9 +775,9 @@ H5I_object_verify(hid_t id, H5I_type_t type) /* Verify that the type of the ID is correct & lookup the ID */ if (type == H5I_TYPE(id) && NULL != (info = H5I__find_id(id))) { /* Get the object pointer to return */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") ret_value = (void *)info->object; /* (Casting away const OK -QAK) */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") } FUNC_LEAVE_NOAPI(ret_value) @@ -938,9 +938,9 @@ H5I__remove_common(H5I_type_info_t *type_info, hid_t id) if (type_info->last_id_info == info) type_info->last_id_info = NULL; - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") ret_value = (void *)info->object; /* (Casting away const OK -QAK) */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") if (!H5I_marking_g) info = H5FL_FREE(H5I_id_info_t, info); @@ -1040,7 +1040,7 @@ H5I__dec_ref(hid_t id, void **request) /* Get the ID's type */ type_info = H5I_type_info_array_g[H5I_TYPE(id)]; - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") /* (Casting away const OK -QAK) */ if (!type_info->cls->free_func || (type_info->cls->free_func)((void *)info->object, request) >= 0) { /* Remove the node from the type */ @@ -1050,7 +1050,7 @@ H5I__dec_ref(hid_t id, void **request) } /* end if */ else ret_value = -1; - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") } /* end if */ else { --(info->count); @@ -1529,9 +1529,9 @@ H5I__iterate_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) /* The stored object pointer might be an H5VL_object_t, in which * case we'll need to get the wrapped object struct (H5F_t *, etc.). */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") object = H5I__unwrap((void *)info->object, type); /* Casting away const OK */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Invoke callback function */ cb_ret_val = (*udata->user_func)((void *)object, info->id, udata->user_udata); @@ -1654,7 +1654,7 @@ H5I__find_id(hid_t id) } /* Check if this is a future ID */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") if (id_info && id_info->is_future) { hid_t actual_id = H5I_INVALID_HID; /* ID for actual object */ void *future_object; /* Pointer to the future object */ @@ -1686,7 +1686,7 @@ H5I__find_id(hid_t id) id_info->realize_cb = NULL; id_info->discard_cb = NULL; } - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Set return value */ ret_value = id_info; @@ -1721,9 +1721,9 @@ H5I__find_id_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata) HDassert(udata); /* Get a pointer to the VOL connector's data */ - H5_GCC_DIAG_OFF("cast-qual") + H5_GCC_CLANG_DIAG_OFF("cast-qual") object = H5I__unwrap((void *)info->object, type); /* Casting away const OK */ - H5_GCC_DIAG_ON("cast-qual") + H5_GCC_CLANG_DIAG_ON("cast-qual") /* Check for a match */ if (object == udata->object) { diff --git a/src/H5Imodule.h b/src/H5Imodule.h index 8db31c8..08f8bb0 100644 --- a/src/H5Imodule.h +++ b/src/H5Imodule.h @@ -30,8 +30,85 @@ #define H5_MY_PKG_INIT NO /**\defgroup H5I H5I - * \brief Identifier Interface - * \todo Describe concisely what the functions in this module are about. + * + * Use the functions in this module to manage identifiers defined by the HDF5 + * library. See \ref H5IUD for user-defined identifiers and identifier + * types. + * + * HDF5 identifiers are usually created as a side-effect of creating HDF5 + * entities such as groups, datasets, attributes, or property lists. + * + * Identifiers defined by the HDF5 library can be used to retrieve information + * such as path names and reference counts, and their validity can be checked. + * + * Identifiers can be updated by manipulating their reference counts. + * + * Unused identifiers should be reclaimed by closing the associated item, e.g., + * HDF5 object, or decrementing the reference count to 0. + * + * \note Identifiers (of type \ref hid_t) are run-time auxiliaries and + * not persisted in the file. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5I_examples.c create + * </td> + * <td> + * \snippet{lineno} H5I_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5I_examples.c update + * </td> + * <td> + * \snippet{lineno} H5I_examples.c delete + * </td> + * </tr> + * </table> + * + * \defgroup H5IUD User-defined ID Types + * \ingroup H5I + * + * The \ref H5I module contains functions to define new identifier types. + * For convenience, handles of type \ref hid_t can then be associated with the + * new identifier types and user objects. + * + * New identifier types can be created by registering a new identifier type + * with the HDF5 library. Once a new identifier type has bee registered, + * it can be used to generate identifiers for user objects. + * + * User-defined identifier types can be searched and iterated. + * + * Like library-defined identifiers, user-defined identifiers \Emph{and} + * identifier types are reference counted, and the reference counts can be + * manipulated accordingly. + * + * User-defined identifiers no longer in use should be deleted or reclaimed, + * and identifier types should be destroyed if they are no longer required. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5I_examples.c create_ud + * </td> + * <td> + * \snippet{lineno} H5I_examples.c read_ud + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5I_examples.c update_ud + * </td> + * <td> + * \snippet{lineno} H5I_examples.c delete_ud + * </td> + * </tr> + * </table> + * */ #endif /* H5Imodule_H */ diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index a5f830b..8d4dbf8 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -106,7 +106,7 @@ extern "C" { /* Public API functions */ /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Registers an object under a type and returns an ID for it * @@ -128,7 +128,7 @@ extern "C" { */ H5_DLL hid_t H5Iregister(H5I_type_t type, const void *object); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Returns the object referenced by an ID * @@ -151,7 +151,7 @@ H5_DLL hid_t H5Iregister(H5I_type_t type, const void *object); */ H5_DLL void *H5Iobject_verify(hid_t id, H5I_type_t type); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Removes an ID from its type * @@ -190,12 +190,7 @@ H5_DLL void *H5Iremove_verify(hid_t id, H5I_type_t type); * \return Returns the object type if successful; otherwise #H5I_BADID. * * \details H5Iget_type() retrieves the type of the object identified by - * \p id. - * - * Valid types returned by the function are: - * \id_types - * - * If no valid type can be determined or the identifier submitted is + * \p id. If no valid type can be determined or the identifier submitted is * invalid, the function returns #H5I_BADID. * * This function is of particular use in determining the type of @@ -391,7 +386,7 @@ H5_DLL int H5Idec_ref(hid_t id); */ H5_DLL int H5Iget_ref(hid_t id); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Creates and returns a new ID type * @@ -423,7 +418,7 @@ H5_DLL int H5Iget_ref(hid_t id); */ H5_DLL H5I_type_t H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Deletes all identifiers of the given type * @@ -447,7 +442,7 @@ H5_DLL H5I_type_t H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free */ H5_DLL herr_t H5Iclear_type(H5I_type_t type, hbool_t force); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Removes an identifier type and all identifiers within that type * @@ -470,7 +465,7 @@ H5_DLL herr_t H5Iclear_type(H5I_type_t type, hbool_t force); */ H5_DLL herr_t H5Idestroy_type(H5I_type_t type); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Increments the reference count on an ID type * @@ -489,7 +484,7 @@ H5_DLL herr_t H5Idestroy_type(H5I_type_t type); */ H5_DLL int H5Iinc_type_ref(H5I_type_t type); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Decrements the reference count on an identifier type * @@ -509,7 +504,7 @@ H5_DLL int H5Iinc_type_ref(H5I_type_t type); */ H5_DLL int H5Idec_type_ref(H5I_type_t type); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Retrieves the reference count on an ID type * @@ -528,7 +523,7 @@ H5_DLL int H5Idec_type_ref(H5I_type_t type); */ H5_DLL int H5Iget_type_ref(H5I_type_t type); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Finds the memory referred to by an ID within the given ID type such * that some criterion is satisfied @@ -569,7 +564,7 @@ H5_DLL int H5Iget_type_ref(H5I_type_t type); */ H5_DLL void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Calls a callback for each member of the identifier type specified * @@ -598,7 +593,7 @@ H5_DLL void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key); */ H5_DLL herr_t H5Iiterate(H5I_type_t type, H5I_iterate_func_t op, void *op_data); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Returns the number of identifiers in a given identifier type * @@ -618,7 +613,7 @@ H5_DLL herr_t H5Iiterate(H5I_type_t type, H5I_iterate_func_t op, void *op_data); */ H5_DLL herr_t H5Inmembers(H5I_type_t type, hsize_t *num_members); /** - * \ingroup H5I + * \ingroup H5IUD * * \brief Determines whether an identifier type is registered * diff --git a/src/H5Itest.c b/src/H5Itest.c index 71ef3f8..80738a9 100644 --- a/src/H5Itest.c +++ b/src/H5Itest.c @@ -71,6 +71,7 @@ H5I__get_name_test(hid_t id, char *name /*out*/, size_t size, hbool_t *cached) H5G_loc_t loc; /* Object location */ hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + size_t name_len = 0; /* Length of name */ ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_PACKAGE @@ -86,7 +87,7 @@ H5I__get_name_test(hid_t id, char *name /*out*/, size_t size, hbool_t *cached) /* Set wrapper info in API context */ if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_ID, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + HGOTO_ERROR(H5E_ID, H5E_CANTSET, (-1), "can't set VOL wrapper info") vol_wrapper_set = TRUE; /* Get object location */ @@ -94,13 +95,16 @@ H5I__get_name_test(hid_t id, char *name /*out*/, size_t size, hbool_t *cached) HGOTO_ERROR(H5E_ID, H5E_CANTGET, (-1), "can't retrieve object location") /* Call internal group routine to retrieve object's name */ - if ((ret_value = H5G_get_name(&loc, name, size, cached)) < 0) + if (H5G_get_name(&loc, name, size, &name_len, cached) < 0) HGOTO_ERROR(H5E_ID, H5E_CANTGET, (-1), "can't retrieve object name") + /* Set return value */ + ret_value = (ssize_t)name_len; + done: /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_ID, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + HDONE_ERROR(H5E_ID, H5E_CANTRESET, (-1), "can't reset VOL wrapper info") if (api_ctx_pushed && H5CX_pop(FALSE) < 0) HDONE_ERROR(H5E_SYM, H5E_CANTRESET, (-1), "can't reset API context") diff --git a/src/H5L.c b/src/H5L.c index a30c4da..065cc5c 100644 --- a/src/H5L.c +++ b/src/H5L.c @@ -148,14 +148,28 @@ H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *ds HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Make sure that the VOL connectors are the same */ - if (vol_obj1 && vol_obj2) - if (vol_obj1->connector->cls->value != vol_obj2->connector->cls->value) + if (vol_obj1 && vol_obj2) { + int same_connector = 0; + + /* Check if both objects are associated with the same VOL connector */ + if (H5VL_cmp_connector_cls(&same_connector, vol_obj1->connector->cls, vol_obj2->connector->cls) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOMPARE, FAIL, "can't compare connector classes") + if (same_connector) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL connectors and can't be linked") + } /* end if */ /* Construct a temporary source VOL object */ - tmp_vol_obj.data = (vol_obj1 ? vol_obj1->data : NULL); - tmp_vol_obj.connector = (vol_obj1 ? vol_obj1->connector : vol_obj2->connector); + if (vol_obj1) { + tmp_vol_obj.connector = vol_obj1->connector; + tmp_vol_obj.data = vol_obj1->data; + } /* end if */ + else { + HDassert(vol_obj2); + + tmp_vol_obj.connector = vol_obj2->connector; + tmp_vol_obj.data = NULL; + } /* end else */ /* Move the link */ if (H5VL_link_move(&tmp_vol_obj, &loc_params1, vol_obj2, &loc_params2, lcpl_id, lapl_id, @@ -238,14 +252,28 @@ H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *ds HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Make sure that the VOL connectors are the same */ - if (vol_obj1 && vol_obj2) - if (vol_obj1->connector->cls->value != vol_obj2->connector->cls->value) + if (vol_obj1 && vol_obj2) { + int same_connector = 0; + + /* Check if both objects are associated with the same VOL connector */ + if (H5VL_cmp_connector_cls(&same_connector, vol_obj1->connector->cls, vol_obj2->connector->cls) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOMPARE, FAIL, "can't compare connector classes") + if (same_connector) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL connectors and can't be linked") + } /* end if */ /* Construct a temporary source VOL object */ - tmp_vol_obj.data = (vol_obj1 ? vol_obj1->data : NULL); - tmp_vol_obj.connector = (vol_obj1 ? vol_obj1->connector : vol_obj2->connector); + if (vol_obj1) { + tmp_vol_obj.connector = vol_obj1->connector; + tmp_vol_obj.data = vol_obj1->data; + } /* end if */ + else { + HDassert(vol_obj2); + + tmp_vol_obj.connector = vol_obj2->connector; + tmp_vol_obj.data = NULL; + } /* end else */ /* Copy the link */ if (H5VL_link_copy(&tmp_vol_obj, &loc_params1, vol_obj2, &loc_params2, lcpl_id, lapl_id, @@ -272,8 +300,9 @@ H5L__create_soft_api_common(const char *link_target, hid_t link_loc_id, const ch H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -286,6 +315,7 @@ H5L__create_soft_api_common(const char *link_target, hid_t link_loc_id, const ch HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_target parameter cannot be an empty string") if (lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") + /* link_name is verified in H5VL_setup_name_args() */ /* Get the link creation property list */ if (H5P_DEFAULT == lcpl_id) @@ -298,15 +328,17 @@ H5L__create_soft_api_common(const char *link_target, hid_t link_loc_id, const ch if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, link_loc_id, TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") - /* link_name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(link_loc_id, link_name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < - 0) + if (H5VL_setup_name_args(link_loc_id, link_name, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_SOFT; + vol_cb_args.args.soft.target = link_target; + /* Create the link */ - if (H5VL_link_create(H5VL_LINK_CREATE_SOFT, *vol_obj_ptr, &loc_params, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, token_ptr, link_target) < 0) + if (H5VL_link_create(&vol_cb_args, *vol_obj_ptr, &loc_params, lcpl_id, lapl_id, H5P_DATASET_XFER_DEFAULT, + token_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create soft link") done: @@ -401,31 +433,31 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5L__create_hard_api_common(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, const char *new_name, +H5L__create_hard_api_common(hid_t cur_loc_id, const char *cur_name, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr) { - H5VL_object_t * vol_obj1 = NULL; /* Object of cur_loc_id */ - H5VL_object_t * vol_obj2 = NULL; /* Object of new_loc_id */ + H5VL_object_t * curr_vol_obj = NULL; /* Object of cur_loc_id */ + H5VL_object_t * link_vol_obj = NULL; /* Object of link_loc_id */ H5VL_object_t tmp_vol_obj; /* Temporary object */ H5VL_object_t * tmp_vol_obj_ptr = &tmp_vol_obj; /* Ptr to temporary object */ H5VL_object_t **tmp_vol_obj_ptr_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj_ptr); /* Ptr to ptr to temporary object */ - H5VL_loc_params_t loc_params1; /* Location parameters for cur_loc_id object access */ - H5VL_loc_params_t loc_params2; /* Location parameters for new_loc_id object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t link_loc_params; /* Location parameters for link_loc_id object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC /* Check arguments */ - if (cur_loc_id == H5L_SAME_LOC && new_loc_id == H5L_SAME_LOC) + if (cur_loc_id == H5L_SAME_LOC && link_loc_id == H5L_SAME_LOC) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not be both H5L_SAME_LOC") if (!cur_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cur_name parameter cannot be NULL") if (!*cur_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cur_name parameter cannot be an empty string") - if (!new_name) + if (!link_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new_name parameter cannot be NULL") - if (!*new_name) + if (!*link_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new_name parameter cannot be an empty string") if (lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") @@ -441,40 +473,59 @@ H5L__create_hard_api_common(hid_t cur_loc_id, const char *cur_name, hid_t new_lo if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, cur_loc_id, TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") - /* Set up current & new location structs */ - loc_params1.type = H5VL_OBJECT_BY_NAME; - loc_params1.obj_type = H5I_get_type(cur_loc_id); - loc_params1.loc_data.loc_by_name.name = cur_name; - loc_params1.loc_data.loc_by_name.lapl_id = lapl_id; - - loc_params2.type = H5VL_OBJECT_BY_NAME; - loc_params2.obj_type = H5I_get_type(new_loc_id); - loc_params2.loc_data.loc_by_name.name = new_name; - loc_params2.loc_data.loc_by_name.lapl_id = lapl_id; + /* Set up new location struct */ + link_loc_params.type = H5VL_OBJECT_BY_NAME; + link_loc_params.obj_type = H5I_get_type(link_loc_id); + link_loc_params.loc_data.loc_by_name.name = link_name; + link_loc_params.loc_data.loc_by_name.lapl_id = lapl_id; if (H5L_SAME_LOC != cur_loc_id) /* Get the current location object */ - if (NULL == (vol_obj1 = (H5VL_object_t *)H5VL_vol_object(cur_loc_id))) + if (NULL == (curr_vol_obj = (H5VL_object_t *)H5VL_vol_object(cur_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - if (H5L_SAME_LOC != new_loc_id) + if (H5L_SAME_LOC != link_loc_id) /* Get the new location object */ - if (NULL == (vol_obj2 = (H5VL_object_t *)H5VL_vol_object(new_loc_id))) + if (NULL == (link_vol_obj = (H5VL_object_t *)H5VL_vol_object(link_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Make sure that the VOL connectors are the same */ - if (vol_obj1 && vol_obj2) - if (vol_obj1->connector->cls->value != vol_obj2->connector->cls->value) + if (curr_vol_obj && link_vol_obj) { + int same_connector = 0; + + /* Check if both objects are associated with the same VOL connector */ + if (H5VL_cmp_connector_cls(&same_connector, curr_vol_obj->connector->cls, + link_vol_obj->connector->cls) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOMPARE, FAIL, "can't compare connector classes") + if (same_connector) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL connectors and can't be linked") + } /* end if */ /* Construct a temporary VOL object */ - (*tmp_vol_obj_ptr_ptr)->data = (vol_obj2 ? (vol_obj2->data) : NULL); - (*tmp_vol_obj_ptr_ptr)->connector = (vol_obj1 != NULL ? vol_obj1->connector : vol_obj2->connector); + if (curr_vol_obj) + (*tmp_vol_obj_ptr_ptr)->connector = curr_vol_obj->connector; + else { + HDassert(link_vol_obj); + + (*tmp_vol_obj_ptr_ptr)->connector = link_vol_obj->connector; + } /* end else */ + if (link_vol_obj) + (*tmp_vol_obj_ptr_ptr)->data = link_vol_obj->data; + else + (*tmp_vol_obj_ptr_ptr)->data = NULL; + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_HARD; + vol_cb_args.args.hard.curr_obj = (curr_vol_obj ? curr_vol_obj->data : NULL); + vol_cb_args.args.hard.curr_loc_params.type = H5VL_OBJECT_BY_NAME; + vol_cb_args.args.hard.curr_loc_params.obj_type = + (H5L_SAME_LOC != cur_loc_id ? H5I_get_type(cur_loc_id) : H5I_BADID); + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.name = cur_name; + vol_cb_args.args.hard.curr_loc_params.loc_data.loc_by_name.lapl_id = lapl_id; /* Create the link */ - if (H5VL_link_create(H5VL_LINK_CREATE_HARD, *tmp_vol_obj_ptr_ptr, &loc_params2, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, token_ptr, (vol_obj1 ? vol_obj1->data : NULL), - &loc_params1) < 0) + if (H5VL_link_create(&vol_cb_args, *tmp_vol_obj_ptr_ptr, &link_loc_params, lcpl_id, lapl_id, + H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create hard link") done: @@ -534,12 +585,11 @@ H5Lcreate_hard_async(const char *app_file, const char *app_func, unsigned app_li const char *cur_name, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id, hid_t es_id) { - H5VL_object_t vol_obj; /* Object for loc_id */ - H5VL_object_t * vol_obj_ptr = &vol_obj; /* Pointer to object for loc_id */ - H5VL_object_t **vol_obj_ptr_ptr = &vol_obj_ptr; /* Pointer to object pointer */ - void * token = NULL; /* Request token for async operation */ - void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t vol_obj; /* Object for loc_id */ + H5VL_object_t *vol_obj_ptr = &vol_obj; /* Pointer to object for loc_id */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE10("e", "*s*sIui*si*siii", app_file, app_func, app_line, cur_loc_id, cur_name, new_loc_id, @@ -551,7 +601,7 @@ H5Lcreate_hard_async(const char *app_file, const char *app_func, unsigned app_li /* Creates a hard link asynchronously */ if (H5L__create_hard_api_common(cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, lapl_id, token_ptr, - vol_obj_ptr_ptr) < 0) + &vol_obj_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to asynchronously create hard link") /* If a token was created, add the token to the event set */ @@ -590,16 +640,16 @@ herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - char * norm_obj_name = NULL; /* Pointer to normalized current name */ - void * ext_link_buf = NULL; /* Buffer to contain external link */ - size_t buf_size; /* Size of buffer to hold external link */ - size_t file_name_len; /* Length of file name string */ - size_t norm_obj_name_len; /* Length of normalized object name string */ - uint8_t * p; /* Pointer into external link buffer */ - H5L_type_t link_type = H5L_TYPE_EXTERNAL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + char * norm_obj_name = NULL; /* Pointer to normalized current name */ + void * ext_link_buf = NULL; /* Buffer to contain external link */ + size_t buf_size; /* Size of buffer to hold external link */ + size_t file_name_len; /* Length of file name string */ + size_t norm_obj_name_len; /* Length of normalized object name string */ + uint8_t * p; /* Pointer into external link buffer */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "*s*si*sii", file_name, obj_name, link_loc_id, link_name, lcpl_id, lapl_id); @@ -650,10 +700,15 @@ H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_i if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(link_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_UD; + vol_cb_args.args.ud.type = H5L_TYPE_EXTERNAL; + vol_cb_args.args.ud.buf = ext_link_buf; + vol_cb_args.args.ud.buf_size = buf_size; + /* Create an external link */ - if (H5VL_link_create(H5VL_LINK_CREATE_UD, vol_obj, &loc_params, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)link_type, ext_link_buf, - buf_size) < 0) + if (H5VL_link_create(&vol_cb_args, vol_obj, &loc_params, lcpl_id, lapl_id, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create external link") done: @@ -691,9 +746,10 @@ herr_t H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_type_t link_type, const void *udata, size_t udata_size, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sLl*xzii", link_loc_id, link_name, link_type, udata, udata_size, lcpl_id, lapl_id); @@ -726,9 +782,15 @@ H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_type_t link_type, con if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(link_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") - /* Create external link */ - if (H5VL_link_create(H5VL_LINK_CREATE_UD, vol_obj, &loc_params, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, (int)link_type, udata, udata_size) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_UD; + vol_cb_args.args.ud.type = link_type; + vol_cb_args.args.ud.buf = udata; + vol_cb_args.args.ud.buf_size = udata_size; + + /* Create user-defined link */ + if (H5VL_link_create(&vol_cb_args, vol_obj, &loc_params, lcpl_id, lapl_id, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") done: @@ -751,8 +813,9 @@ H5L__delete_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **tok H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -760,12 +823,14 @@ H5L__delete_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **tok /* name is verified in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, name, TRUE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") - /* Unlink */ - if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, token_ptr) < - 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_DELETE; + + /* Delete link */ + if (H5VL_link_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") done: @@ -864,8 +929,9 @@ H5L__delete_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t i H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -878,13 +944,15 @@ H5L__delete_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t i HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") /* Set up object access arguments */ - if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, TRUE, lapl_id, vol_obj_ptr, - &loc_params) < 0) + if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, TRUE, lapl_id, vol_obj_ptr, &loc_params) < + 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_DELETE; + /* Delete the link */ - if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_DELETE, H5P_DATASET_XFER_DEFAULT, token_ptr) < - 0) + if (H5VL_link_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") done: @@ -993,9 +1061,10 @@ done: herr_t H5Lget_val(hid_t loc_id, const char *name, void *buf /*out*/, size_t size, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*sxzi", loc_id, name, buf, size, lapl_id); @@ -1008,18 +1077,23 @@ H5Lget_val(hid_t loc_id, const char *name, void *buf /*out*/, size_t size, hid_t if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.obj_type = H5I_get_type(loc_id); loc_params.loc_data.loc_by_name.name = name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - /* Get the location object */ + /* Get the VOL object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_VAL; + vol_cb_args.args.get_val.buf = buf; + vol_cb_args.args.get_val.buf_size = size; + /* Get the link value */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_VAL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, buf, - size) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link value for '%s'", name) done: @@ -1048,9 +1122,10 @@ herr_t H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, void *buf /*out*/, size_t size, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIohxzi", loc_id, group_name, idx_type, order, n, buf, size, lapl_id); @@ -1067,6 +1142,7 @@ H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_ if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -1075,13 +1151,17 @@ H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_ loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); - /* get the location object */ + /* Get the VOL object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_VAL; + vol_cb_args.args.get_val.buf = buf; + vol_cb_args.args.get_val.buf_size = size; + /* Get the link value */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_VAL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, buf, - size) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link value") done: @@ -1104,8 +1184,9 @@ H5L__exists_api_common(hid_t loc_id, const char *name, hbool_t *exists, hid_t la H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1115,12 +1196,15 @@ H5L__exists_api_common(hid_t loc_id, const char *name, hbool_t *exists, hid_t la HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer for link existence") /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_EXISTS; + vol_cb_args.args.exists.exists = exists; + /* Check for the existence of the link */ - if (H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_EXISTS, H5P_DATASET_XFER_DEFAULT, token_ptr, - exists) < 0) + if (H5VL_link_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") done: @@ -1216,9 +1300,10 @@ done: herr_t H5Lget_info2(hid_t loc_id, const char *name, H5L_info2_t *linfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*sxi", loc_id, name, linfo, lapl_id); @@ -1231,18 +1316,22 @@ H5Lget_info2(hid_t loc_id, const char *name, H5L_info2_t *linfo /*out*/, hid_t l if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.obj_type = H5I_get_type(loc_id); loc_params.loc_data.loc_by_name.name = name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - /* get the location object */ + /* Get the location object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_INFO; + vol_cb_args.args.get_info.linfo = linfo; + /* Get the link information */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - linfo) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") done: @@ -1267,9 +1356,10 @@ herr_t H5Lget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIohxi", loc_id, group_name, idx_type, order, n, linfo, lapl_id); @@ -1286,6 +1376,7 @@ H5Lget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -1294,13 +1385,16 @@ H5Lget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); - /* get the location object */ + /* Get the location object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_INFO; + vol_cb_args.args.get_info.linfo = linfo; + /* Get the link information */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - linfo) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") done: @@ -1463,9 +1557,11 @@ ssize_t H5Lget_name_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + size_t link_name_len = 0; /* Length of the link name string */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE8("Zs", "i*sIiIohxzi", loc_id, group_name, idx_type, order, n, name, size, lapl_id); @@ -1482,7 +1578,7 @@ H5Lget_name_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5 if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, (-1), "can't set access property list info") - /* Fill in location struct fields */ + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -1491,15 +1587,23 @@ H5Lget_name_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5 loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); - /* Get the location object */ + /* Get the VOL object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_NAME; + vol_cb_args.args.get_name.name_size = size; + vol_cb_args.args.get_name.name = name; + vol_cb_args.args.get_name.name_len = &link_name_len; + /* Get the link information */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - name, size, &ret_value) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, (-1), "unable to get link name") + /* Set the return value */ + ret_value = (ssize_t)link_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Lget_name_by_idx() */ @@ -1519,10 +1623,11 @@ H5L__iterate_api_common(hid_t group_id, H5_index_t idx_type, H5_iter_order_t ord { H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = - (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - H5I_type_t id_type; /* Type of ID */ - herr_t ret_value = H5_ITER_CONT; /* Return value */ + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5I_type_t id_type; /* Type of ID */ + herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_STATIC @@ -1541,10 +1646,18 @@ H5L__iterate_api_common(hid_t group_id, H5_index_t idx_type, H5_iter_order_t ord if (H5VL_setup_self_args(group_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = FALSE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = idx_p; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(*vol_obj_ptr, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - token_ptr, (unsigned)FALSE, (int)idx_type, (int)order, idx_p, op, - op_data)) < 0) + if ((ret_value = H5VL_link_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + token_ptr)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") done: @@ -1663,9 +1776,10 @@ herr_t H5Literate_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate2_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIo*hLI*xi", loc_id, group_name, idx_type, order, idx_p, op, op_data, lapl_id); @@ -1696,9 +1810,18 @@ H5Literate_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H loc_params.loc_data.loc_by_name.name = group_name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = FALSE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = idx_p; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, FALSE, idx_type, order, idx_p, op, op_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") done: @@ -1736,10 +1859,11 @@ done: herr_t H5Lvisit2(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate2_t op, void *op_data) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5I_type_t id_type; /* Type of ID */ - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5I_type_t id_type; /* Type of ID */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "iIiIoLI*x", group_id, idx_type, order, op, op_data); @@ -1763,9 +1887,18 @@ H5Lvisit2(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterat if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(group_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = TRUE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = NULL; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, TRUE, idx_type, order, NULL, op, op_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") done: @@ -1804,9 +1937,10 @@ herr_t H5Lvisit_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate2_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIoLI*xi", loc_id, group_name, idx_type, order, op, op_data, lapl_id); @@ -1837,9 +1971,18 @@ H5Lvisit_by_name2(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_ loc_params.loc_data.loc_by_name.name = group_name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = TRUE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = NULL; + vol_cb_args.args.iterate.op = op; + vol_cb_args.args.iterate.op_data = op_data; + /* Visit the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, TRUE, idx_type, order, NULL, op, op_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") done: diff --git a/src/H5Ldeprec.c b/src/H5Ldeprec.c index df4c384..01e77f9 100644 --- a/src/H5Ldeprec.c +++ b/src/H5Ldeprec.c @@ -141,12 +141,13 @@ herr_t H5Literate1(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate1_t op, void *op_data) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5I_type_t id_type; /* Type of ID */ - H5L_shim_data_t shim_data; - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5I_type_t id_type; /* Type of ID */ + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iIiIo*hLi*x", group_id, idx_type, order, idx_p, op, op_data); @@ -181,10 +182,18 @@ H5Literate1(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t shim_data.real_op = op; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = FALSE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = idx_p; + vol_cb_args.args.iterate.op = H5L__iterate2_shim; + vol_cb_args.args.iterate.op_data = &shim_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (unsigned)FALSE, (int)idx_type, (int)order, idx_p, - H5L__iterate2_shim, (void *)&shim_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") done: @@ -219,11 +228,12 @@ herr_t H5Literate_by_name1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate1_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5L_shim_data_t shim_data; - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIo*hLi*xi", loc_id, group_name, idx_type, order, idx_p, op, op_data, lapl_id); @@ -265,10 +275,18 @@ H5Literate_by_name1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H shim_data.real_op = op; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = FALSE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = idx_p; + vol_cb_args.args.iterate.op = H5L__iterate2_shim; + vol_cb_args.args.iterate.op_data = &shim_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, FALSE, idx_type, order, idx_p, H5L__iterate2_shim, - (void *)&shim_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed") done: @@ -293,11 +311,12 @@ done: herr_t H5Lget_info1(hid_t loc_id, const char *name, H5L_info1_t *linfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - H5L_info2_t linfo2; /* New-style link info */ - hbool_t is_native_vol_obj; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5L_info2_t linfo2; /* New-style link info */ + hbool_t is_native_vol_obj; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*sxi", loc_id, name, linfo, lapl_id); @@ -310,12 +329,13 @@ H5Lget_info1(hid_t loc_id, const char *name, H5L_info1_t *linfo /*out*/, hid_t l if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_NAME; loc_params.obj_type = H5I_get_type(loc_id); loc_params.loc_data.loc_by_name.name = name; loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - /* get the location object */ + /* Get the location object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") @@ -326,9 +346,12 @@ H5Lget_info1(hid_t loc_id, const char *name, H5L_info1_t *linfo /*out*/, hid_t l HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "H5Lget_info1 is only meant to be used with the native VOL connector") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_INFO; + vol_cb_args.args.get_info.linfo = &linfo2; + /* Get the link information */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &linfo2) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") /* Copy the new-style members into the old-style struct */ @@ -376,11 +399,12 @@ herr_t H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5L_info1_t *linfo /*out*/, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - H5L_info2_t linfo2; /* New-style link info */ - hbool_t is_native_vol_obj; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_link_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5L_info2_t linfo2; /* New-style link info */ + hbool_t is_native_vol_obj; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIohxi", loc_id, group_name, idx_type, order, n, linfo, lapl_id); @@ -397,6 +421,7 @@ H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up location struct */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -405,7 +430,7 @@ H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H loc_params.loc_data.loc_by_idx.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); - /* get the location object */ + /* Get the location object */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") @@ -416,9 +441,12 @@ H5Lget_info_by_idx1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "H5Lget_info_by_idx1 is only meant to be used with the native VOL connector") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_GET_INFO; + vol_cb_args.args.get_info.linfo = &linfo2; + /* Get the link information */ - if (H5VL_link_get(vol_obj, &loc_params, H5VL_LINK_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &linfo2) < 0) + if (H5VL_link_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info") /* Copy the new-style members into the old-style struct */ @@ -479,12 +507,13 @@ done: herr_t H5Lvisit1(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate1_t op, void *op_data) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5I_type_t id_type; /* Type of ID */ - H5L_shim_data_t shim_data; - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5I_type_t id_type; /* Type of ID */ + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "iIiIoLi*x", group_id, idx_type, order, op, op_data); @@ -519,10 +548,18 @@ H5Lvisit1(hid_t group_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterat shim_data.real_op = op; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = TRUE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = NULL; + vol_cb_args.args.iterate.op = H5L__iterate2_shim; + vol_cb_args.args.iterate.op_data = &shim_data; + /* Iterate over the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, TRUE, idx_type, order, NULL, H5L__iterate2_shim, - (void *)&shim_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") done: @@ -563,11 +600,12 @@ herr_t H5Lvisit_by_name1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate1_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5L_shim_data_t shim_data; - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_link_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + H5L_shim_data_t shim_data; + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIoLi*xi", loc_id, group_name, idx_type, order, op, op_data, lapl_id); @@ -609,10 +647,18 @@ H5Lvisit_by_name1(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_ shim_data.real_op = op; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_ITER; + vol_cb_args.args.iterate.recursive = TRUE; + vol_cb_args.args.iterate.idx_type = idx_type; + vol_cb_args.args.iterate.order = order; + vol_cb_args.args.iterate.idx_p = NULL; + vol_cb_args.args.iterate.op = H5L__iterate2_shim; + vol_cb_args.args.iterate.op_data = &shim_data; + /* Visit the links */ - if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, H5VL_LINK_ITER, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, TRUE, idx_type, order, NULL, H5L__iterate2_shim, - (void *)&shim_data)) < 0) + if ((ret_value = H5VL_link_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") done: diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index eccd2c6..2f7c7eb 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -173,30 +173,30 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group, cons /* Make callback if it exists */ if (cb_info.func) { - const char *parent_file_name; /* Parent file name */ - ssize_t group_name_len; /* Length of parent group name */ + const char *parent_file_name; /* Parent file name */ + size_t group_name_len = 0; /* Length of parent group name */ /* Get parent file name */ parent_file_name = H5F_OPEN_NAME(loc.oloc->file); /* Query length of parent group name */ - if ((group_name_len = H5G_get_name(&loc, NULL, (size_t)0, NULL)) < 0) + if (H5G_get_name(&loc, NULL, (size_t)0, &group_name_len, NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, H5I_INVALID_HID, "unable to retrieve length of group name") /* Account for null terminator */ group_name_len++; /* Check if we need to allocate larger buffer */ - if ((size_t)group_name_len > sizeof(local_group_name)) { - if (NULL == (parent_group_name = (char *)H5MM_malloc((size_t)group_name_len))) + if (group_name_len > sizeof(local_group_name)) { + if (NULL == (parent_group_name = (char *)H5MM_malloc(group_name_len))) HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, H5I_INVALID_HID, - "can't allocate buffer to hold group name, group_name_len = %zd", group_name_len) + "can't allocate buffer to hold group name, group_name_len = %zu", group_name_len) } /* end if */ else parent_group_name = local_group_name; /* Get parent group name */ - if (H5G_get_name(&loc, parent_group_name, (size_t)group_name_len, NULL) < 0) + if (H5G_get_name(&loc, parent_group_name, group_name_len, NULL, NULL) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, H5I_INVALID_HID, "unable to retrieve group name") /* Make callback */ diff --git a/src/H5Lint.c b/src/H5Lint.c index a8e9ba2..346c37d 100644 --- a/src/H5Lint.c +++ b/src/H5Lint.c @@ -47,6 +47,50 @@ typedef struct { H5L_info2_t *linfo; /* Buffer to return to user */ } H5L_trav_gi_t; +/* User data for path traversal routine for getting link value by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ + size_t size; /* Size of user buffer */ + + /* Out */ + void *buf; /* User buffer */ +} H5L_trav_gvbi_t; + +/* User data for path traversal routine for getting link info by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ + + /* Out */ + H5L_info2_t *linfo; /* Buffer to return to user */ +} H5L_trav_gibi_t; + +/* User data for path traversal routine for removing link by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ +} H5L_trav_rmbi_t; + +/* User data for path traversal routine for getting name by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ + size_t size; /* Size of name buffer */ + + /* Out */ + char * name; /* Buffer to return name to user */ + size_t name_len; /* Length of full name */ +} H5L_trav_gnbi_t; + /* User data for path traversal callback to creating a link */ typedef struct { H5F_t * file; /* Pointer to the file */ @@ -2012,8 +2056,8 @@ H5L__get_name_by_idx_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc /*in*/, const char H5_ HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "group doesn't exist") /* Query link */ - if ((udata->name_len = H5G_obj_get_name_by_idx(obj_loc->oloc, udata->idx_type, udata->order, udata->n, - udata->name, udata->size)) < 0) + if (H5G_obj_get_name_by_idx(obj_loc->oloc, udata->idx_type, udata->order, udata->n, udata->name, + udata->size, &udata->name_len) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "link not found") done: @@ -2034,18 +2078,19 @@ done: * *------------------------------------------------------------------------- */ -ssize_t +herr_t H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, char *name /*out*/, size_t size) + hsize_t n, char *name /*out*/, size_t size, size_t *link_name_len) { - H5L_trav_gnbi_t udata; /* User data for callback */ - ssize_t ret_value = FAIL; /* Return value */ + H5L_trav_gnbi_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Check arguments */ HDassert(loc); HDassert(group_name && *group_name); + HDassert(link_name_len); /* Set up user data for callback */ udata.idx_type = idx_type; @@ -2053,7 +2098,7 @@ H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t id udata.n = n; udata.name = name; udata.size = size; - udata.name_len = -1; + udata.name_len = 0; /* Traverse the group hierarchy to locate the link to get name of */ if (H5G_traverse(loc, group_name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__get_name_by_idx_cb, &udata) < @@ -2061,7 +2106,7 @@ H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t id HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get name") /* Set the return value */ - ret_value = udata.name_len; + *link_name_len = udata.name_len; done: FUNC_LEAVE_NOAPI(ret_value) @@ -2104,9 +2149,9 @@ H5L__link_copy_file(H5F_t *dst_file, const H5O_link_t *_src_lnk, const H5O_loc_t /* Expand soft or external link, if requested */ if ((H5L_TYPE_SOFT == src_lnk->type && cpy_info->expand_soft_link) || (H5L_TYPE_EXTERNAL == src_lnk->type && cpy_info->expand_ext_link)) { - H5G_loc_t lnk_grp_loc; /* Group location holding link */ - H5G_name_t lnk_grp_path; /* Path for link */ - htri_t tar_exists; /* Whether the target object exists */ + H5G_loc_t lnk_grp_loc; /* Group location holding link */ + H5G_name_t lnk_grp_path; /* Path for link */ + hbool_t tar_exists = FALSE; /* Whether the target object exists */ /* Set up group location for link */ H5G_name_reset(&lnk_grp_path); @@ -2114,7 +2159,7 @@ H5L__link_copy_file(H5F_t *dst_file, const H5O_link_t *_src_lnk, const H5O_loc_t lnk_grp_loc.oloc = (H5O_loc_t *)src_oloc; /* Casting away const OK -QAK */ /* Check if the target object exists */ - if ((tar_exists = H5G_loc_exists(&lnk_grp_loc, src_lnk->name)) < 0) + if (H5G_loc_exists(&lnk_grp_loc, src_lnk->name, &tar_exists) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to check if target object exists") if (tar_exists) { diff --git a/src/H5Lmodule.h b/src/H5Lmodule.h index 16f1f34..cffd25c 100644 --- a/src/H5Lmodule.h +++ b/src/H5Lmodule.h @@ -30,8 +30,29 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5L H5L - * \brief Link Interface - * \todo Describe concisely what the functions in this module are about. + * + * Use the functions in this module to manage HDF5 links and link types. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5L_examples.c create + * </td> + * <td> + * \snippet{lineno} H5L_examples.c iter_cb + * \snippet{lineno} H5L_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5L_examples.c update + * </td> + * <td> + * \snippet{lineno} H5L_examples.c delete + * </td> + * </tr> + * </table> * * \defgroup TRAV Link Traversal * \ingroup H5L diff --git a/src/H5Lpkg.h b/src/H5Lpkg.h index 7057e30..36a4d12 100644 --- a/src/H5Lpkg.h +++ b/src/H5Lpkg.h @@ -53,26 +53,27 @@ /* Package Private Prototypes */ /******************************/ -H5_DLL herr_t H5L__create_hard(H5G_loc_t *cur_loc, const char *cur_name, const H5G_loc_t *link_loc, - const char *link_name, hid_t lcpl_id); -H5_DLL herr_t H5L__create_soft(const char *target_path, const H5G_loc_t *cur_loc, const char *cur_name, - hid_t lcpl_id); -H5_DLL herr_t H5L__create_ud(const H5G_loc_t *link_loc, const char *link_name, const void *ud_data, - size_t ud_data_size, H5L_type_t type, hid_t lcpl_id); -H5_DLL herr_t H5L__exists(const H5G_loc_t *loc, const char *name, hbool_t *exists); -H5_DLL herr_t H5L__get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo /*out*/); -H5_DLL ssize_t H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size); -H5_DLL herr_t H5L__get_val(const H5G_loc_t *loc, const char *name, void *buf /*out*/, size_t size); -H5_DLL herr_t H5L__get_val_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, void *buf /*out*/, size_t size); -H5_DLL herr_t H5L__move(const H5G_loc_t *src_loc, const char *src_name, const H5G_loc_t *dst_loc, - const char *dst_name, hbool_t copy_flag, hid_t lcpl_id); -H5_DLL herr_t H5L__delete(const H5G_loc_t *loc, const char *name); -H5_DLL herr_t H5L__delete_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n); -H5_DLL herr_t H5L__link_copy_file(H5F_t *dst_file, const H5O_link_t *_src_lnk, const H5O_loc_t *src_oloc, - H5O_link_t *dst_lnk, H5O_copy_t *cpy_info); +H5_DLL herr_t H5L__create_hard(H5G_loc_t *cur_loc, const char *cur_name, const H5G_loc_t *link_loc, + const char *link_name, hid_t lcpl_id); +H5_DLL herr_t H5L__create_soft(const char *target_path, const H5G_loc_t *cur_loc, const char *cur_name, + hid_t lcpl_id); +H5_DLL herr_t H5L__create_ud(const H5G_loc_t *link_loc, const char *link_name, const void *ud_data, + size_t ud_data_size, H5L_type_t type, hid_t lcpl_id); +H5_DLL herr_t H5L__exists(const H5G_loc_t *loc, const char *name, hbool_t *exists); +H5_DLL herr_t H5L__get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5L_info2_t *linfo /*out*/); +H5_DLL herr_t H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, + size_t *name_len); +H5_DLL herr_t H5L__get_val(const H5G_loc_t *loc, const char *name, void *buf /*out*/, size_t size); +H5_DLL herr_t H5L__get_val_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, void *buf /*out*/, size_t size); +H5_DLL herr_t H5L__move(const H5G_loc_t *src_loc, const char *src_name, const H5G_loc_t *dst_loc, + const char *dst_name, hbool_t copy_flag, hid_t lcpl_id); +H5_DLL herr_t H5L__delete(const H5G_loc_t *loc, const char *name); +H5_DLL herr_t H5L__delete_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n); +H5_DLL herr_t H5L__link_copy_file(H5F_t *dst_file, const H5O_link_t *_src_lnk, const H5O_loc_t *src_oloc, + H5O_link_t *dst_lnk, H5O_copy_t *cpy_info); #endif /* H5Lpkg_H */ diff --git a/src/H5Lprivate.h b/src/H5Lprivate.h index 53b8726..98e3051 100644 --- a/src/H5Lprivate.h +++ b/src/H5Lprivate.h @@ -52,50 +52,6 @@ /* Library Private Typedefs */ /****************************/ -/* User data for path traversal routine for getting link value by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ - size_t size; /* Size of user buffer */ - - /* Out */ - void *buf; /* User buffer */ -} H5L_trav_gvbi_t; - -/* User data for path traversal routine for getting link info by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ - - /* Out */ - H5L_info2_t *linfo; /* Buffer to return to user */ -} H5L_trav_gibi_t; - -/* User data for path traversal routine for getting name by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ - size_t size; /* Size of name buffer */ - - /* Out */ - char * name; /* Buffer to return name to user */ - ssize_t name_len; /* Length of full name */ -} H5L_trav_gnbi_t; - -/* User data for path traversal routine for removing link by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ -} H5L_trav_rmbi_t; - /* Structure for external link traversal callback property */ typedef struct H5L_elink_cb_t { H5L_elink_traverse_t func; diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h index f665526..72b0182 100644 --- a/src/H5Lpublic.h +++ b/src/H5Lpublic.h @@ -1380,6 +1380,7 @@ H5_DLL herr_t H5Lunpack_elink_val(const void *ext_linkval /*in*/, size_t link_si H5_DLL herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -1401,6 +1402,7 @@ H5_DLL herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hi #define H5Lexists_async_wrap H5_NO_EXPAND(H5Lexists_async) #define H5Literate_async_wrap H5_NO_EXPAND(H5Literate_async) #endif /* H5L_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5M.c b/src/H5M.c index f3cc2ea..b890a5c 100644 --- a/src/H5M.c +++ b/src/H5M.c @@ -211,15 +211,20 @@ H5M_term_package(void) static herr_t H5M__close_cb(H5VL_object_t *map_vol_obj, void **request) { - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC /* Sanity check */ HDassert(map_vol_obj); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_MAP_CLOSE; + vol_cb_args.args = NULL; + /* Close the map */ - if (H5VL_optional(map_vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, request) < 0) + if (H5VL_optional(map_vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, request) < 0) HGOTO_ERROR(H5E_MAP, H5E_CLOSEERROR, FAIL, "unable to close map"); /* Free the VOL object */ @@ -251,8 +256,9 @@ H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_STATIC @@ -274,14 +280,24 @@ H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t else if (TRUE != H5P_isa_class(mcpl_id, H5P_MAP_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "mcpl_id is not a map create property list ID") - /* Set up object access arguments */ - if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, TRUE, &mapl_id, vol_obj_ptr, &loc_params) < 0) + /* Set up VOL callback arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, TRUE, &mapl_id, vol_obj_ptr, &map_args.create.loc_params) < + 0) HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") + map_args.create.name = name; + map_args.create.lcpl_id = lcpl_id; + map_args.create.key_type_id = key_type_id; + map_args.create.val_type_id = val_type_id; + map_args.create.mcpl_id = mcpl_id; + map_args.create.mapl_id = mapl_id; + map_args.create.map = NULL; + vol_cb_args.op_type = H5VL_MAP_CREATE; + vol_cb_args.args = &map_args; /* Create the map */ - if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, name, - lcpl_id, key_type_id, val_type_id, mcpl_id, mapl_id, &map) < 0) + if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map") + map = map_args.create.map; /* Get an ID for the map */ if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0) @@ -289,9 +305,14 @@ H5M__create_api_common(hid_t loc_id, const char *name, hid_t key_type_id, hid_t done: /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (map && H5VL_optional(*vol_obj_ptr, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5I_INVALID_HID == ret_value) { + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_MAP_CLOSE; + vol_cb_args.args = NULL; + + if (map && H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map") + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5M__create_api_common() */ @@ -407,10 +428,11 @@ done: hid_t H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id, hid_t mapl_id) { - void * map = NULL; /* map object from VOL connector */ - H5VL_object_t * vol_obj = NULL; /* object of loc_id */ - H5VL_loc_params_t loc_params; - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + void * map = NULL; /* map object from VOL connector */ + H5VL_object_t * vol_obj = NULL; /* object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE5("i", "iiiii", loc_id, key_type_id, val_type_id, mcpl_id, mapl_id); @@ -430,13 +452,24 @@ H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") /* Set location parameters */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(loc_id); + + /* Set up VOL callback arguments */ + map_args.create.loc_params.type = H5VL_OBJECT_BY_SELF; + map_args.create.loc_params.obj_type = H5I_get_type(loc_id); + map_args.create.name = NULL; + map_args.create.lcpl_id = H5P_LINK_CREATE_DEFAULT; + map_args.create.key_type_id = key_type_id; + map_args.create.val_type_id = val_type_id; + map_args.create.mcpl_id = mcpl_id; + map_args.create.mapl_id = mapl_id; + map_args.create.map = NULL; + vol_cb_args.op_type = H5VL_MAP_CREATE; + vol_cb_args.args = &map_args; /* Create the map */ - if (H5VL_optional(vol_obj, H5VL_MAP_CREATE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &loc_params, NULL, - H5P_LINK_CREATE_DEFAULT, key_type_id, val_type_id, mcpl_id, mapl_id, &map) < 0) + if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, H5I_INVALID_HID, "unable to create map") + map = map_args.create.map; /* Get an ID for the map */ if ((ret_value = H5VL_register(H5I_MAP, map, vol_obj->connector, TRUE)) < 0) @@ -444,9 +477,14 @@ H5Mcreate_anon(hid_t loc_id, hid_t key_type_id, hid_t val_type_id, hid_t mcpl_id done: /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5I_INVALID_HID == ret_value) { + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_MAP_CLOSE; + vol_cb_args.args = NULL; + + if (map && H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map") + } /* end if */ FUNC_LEAVE_API(ret_value) } /* end H5Mcreate_anon() */ @@ -470,8 +508,9 @@ H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_STATIC @@ -481,14 +520,20 @@ H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token if (!*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "name parameter cannot be an empty string") - /* Set up object access arguments */ - if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, FALSE, &mapl_id, vol_obj_ptr, &loc_params) < 0) + /* Set up VOL callback arguments */ + if (H5VL_setup_acc_args(loc_id, H5P_CLS_MACC, FALSE, &mapl_id, vol_obj_ptr, &map_args.open.loc_params) < + 0) HGOTO_ERROR(H5E_MAP, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") + map_args.open.name = name; + map_args.open.mapl_id = mapl_id; + map_args.open.map = NULL; + vol_cb_args.op_type = H5VL_MAP_OPEN; + vol_cb_args.args = &map_args; /* Open the map */ - if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_OPEN, H5P_DATASET_XFER_DEFAULT, token_ptr, &loc_params, name, - mapl_id, &map) < 0) + if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open map") + map = map_args.create.map; /* Register an ID for the map */ if ((ret_value = H5VL_register(H5I_MAP, map, (*vol_obj_ptr)->connector, TRUE)) < 0) @@ -496,9 +541,14 @@ H5M__open_api_common(hid_t loc_id, const char *name, hid_t mapl_id, void **token done: /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (map && H5VL_optional(*vol_obj_ptr, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + if (H5I_INVALID_HID == ret_value) { + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_MAP_CLOSE; + vol_cb_args.args = NULL; + + if (map && H5VL_optional(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map") + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5M__open_api_common() */ @@ -521,9 +571,7 @@ done: hid_t H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id) { - void * map = NULL; /* map object from VOL connector */ - H5VL_object_t *vol_obj = NULL; /* object of loc_id */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE3("i", "i*si", loc_id, name, mapl_id); @@ -533,11 +581,6 @@ H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id) HGOTO_ERROR(H5E_MAP, H5E_CANTCREATE, H5I_INVALID_HID, "unable to open map synchronously") done: - /* Cleanup on failure */ - if (H5I_INVALID_HID == ret_value) - if (map && H5VL_optional(vol_obj, H5VL_MAP_CLOSE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, H5I_INVALID_HID, "unable to release map") - FUNC_LEAVE_API(ret_value) } /* end H5Mopen() */ @@ -697,8 +740,10 @@ done: hid_t H5Mget_key_type(hid_t map_id) { - H5VL_object_t *vol_obj; /* Map structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Map structure */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", map_id); @@ -707,10 +752,18 @@ H5Mget_key_type(hid_t map_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier") - /* get the datatype */ - if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_KEY_TYPE, - &ret_value) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype") + /* Set up VOL callback arguments */ + map_args.get.get_type = H5VL_MAP_GET_KEY_TYPE; + map_args.get.args.get_key_type.type_id = H5I_INVALID_HID; + vol_cb_args.op_type = H5VL_MAP_GET; + vol_cb_args.args = &map_args; + + /* Get the key datatype */ + if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get key datatype") + + /* Set return value */ + ret_value = map_args.get.args.get_key_type.type_id; done: FUNC_LEAVE_API(ret_value) @@ -732,8 +785,10 @@ done: hid_t H5Mget_val_type(hid_t map_id) { - H5VL_object_t *vol_obj; /* Map structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Map structure */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", map_id); @@ -742,10 +797,18 @@ H5Mget_val_type(hid_t map_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier") - /* get the datatype */ - if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_VAL_TYPE, - &ret_value) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype") + /* Set up VOL callback arguments */ + map_args.get.get_type = H5VL_MAP_GET_VAL_TYPE; + map_args.get.args.get_val_type.type_id = H5I_INVALID_HID; + vol_cb_args.op_type = H5VL_MAP_GET; + vol_cb_args.args = &map_args; + + /* Get the value datatype */ + if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get value datatype") + + /* Set return value */ + ret_value = map_args.get.args.get_val_type.type_id; done: FUNC_LEAVE_API(ret_value) @@ -767,8 +830,10 @@ done: hid_t H5Mget_create_plist(hid_t map_id) { - H5VL_object_t *vol_obj; /* Map structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Map structure */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", map_id); @@ -777,11 +842,19 @@ H5Mget_create_plist(hid_t map_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier") + /* Set up VOL callback arguments */ + map_args.get.get_type = H5VL_MAP_GET_MCPL; + map_args.get.args.get_mcpl.mcpl_id = H5I_INVALID_HID; + vol_cb_args.op_type = H5VL_MAP_GET; + vol_cb_args.args = &map_args; + /* Get the map creation property list */ - if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_MCPL, - &ret_value) < 0) + if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map creation properties") + /* Set return value */ + ret_value = map_args.get.args.get_mcpl.mcpl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Mget_create_plist() */ @@ -805,8 +878,10 @@ done: hid_t H5Mget_access_plist(hid_t map_id) { - H5VL_object_t *vol_obj; /* Map structure */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_object_t * vol_obj; /* Map structure */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE1("i", "i", map_id); @@ -815,11 +890,19 @@ H5Mget_access_plist(hid_t map_id) if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid map identifier") + /* Set up VOL callback arguments */ + map_args.get.get_type = H5VL_MAP_GET_MAPL; + map_args.get.args.get_mapl.mapl_id = H5I_INVALID_HID; + vol_cb_args.op_type = H5VL_MAP_GET; + vol_cb_args.args = &map_args; + /* Get the map access property list */ - if (H5VL_optional(vol_obj, H5VL_MAP_GET, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5VL_MAP_GET_MAPL, - &ret_value) < 0) + if (H5VL_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map access properties") + /* Set return value */ + ret_value = map_args.get.args.get_mapl.mapl_id; + done: FUNC_LEAVE_API(ret_value) } /* end H5Mget_access_plist() */ @@ -839,8 +922,10 @@ done: herr_t H5Mget_count(hid_t map_id, hsize_t *count /*out*/, hid_t dxpl_id) { - H5VL_object_t *vol_obj; /* Map structure */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Map structure */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE3("e", "ixi", map_id, count, dxpl_id); @@ -858,9 +943,19 @@ H5Mget_count(hid_t map_id, hsize_t *count /*out*/, hid_t dxpl_id) /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); + /* Set up VOL callback arguments */ + map_args.get.get_type = H5VL_MAP_GET_COUNT; + map_args.get.args.get_count.count = 0; + vol_cb_args.op_type = H5VL_MAP_GET; + vol_cb_args.args = &map_args; + /* Get the number of key-value pairs stored in the map */ - if (H5VL_optional(vol_obj, H5VL_MAP_GET, dxpl_id, H5_REQUEST_NULL, H5VL_MAP_GET_COUNT, count) < 0) - HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get map access properties") + if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_MAP, H5E_CANTGET, H5I_INVALID_HID, "unable to get KV pair count for map") + + /* Set value to return */ + if (count) + *count = map_args.get.args.get_count.count; done: FUNC_LEAVE_API(ret_value) @@ -882,7 +977,9 @@ H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -905,9 +1002,16 @@ H5M__put_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); + /* Set up VOL callback arguments */ + map_args.put.key_mem_type_id = key_mem_type_id; + map_args.put.key = key; + map_args.put.value_mem_type_id = val_mem_type_id; + map_args.put.value = value; + vol_cb_args.op_type = H5VL_MAP_PUT; + vol_cb_args.args = &map_args; + /* Set the key/value pair */ - if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_PUT, dxpl_id, token_ptr, key_mem_type_id, key, val_mem_type_id, - value) < 0) + if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, dxpl_id, token_ptr) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to put key/value pair") done: @@ -1008,7 +1112,9 @@ H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1031,9 +1137,16 @@ H5M__get_api_common(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); + /* Set up VOL callback arguments */ + map_args.get_val.key_mem_type_id = key_mem_type_id; + map_args.get_val.key = key; + map_args.get_val.value_mem_type_id = val_mem_type_id; + map_args.get_val.value = value; + vol_cb_args.op_type = H5VL_MAP_GET_VAL; + vol_cb_args.args = &map_args; + /* Get the value for the key */ - if (H5VL_optional(*vol_obj_ptr, H5VL_MAP_GET_VAL, dxpl_id, token_ptr, key_mem_type_id, key, - val_mem_type_id, value) < 0) + if (H5VL_optional(*vol_obj_ptr, &vol_cb_args, dxpl_id, token_ptr) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "unable to get value from map") done: @@ -1137,8 +1250,10 @@ done: herr_t H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists, hid_t dxpl_id) { - H5VL_object_t *vol_obj = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "ii*x*bi", map_id, key_mem_type_id, key, exists, dxpl_id); @@ -1160,11 +1275,21 @@ H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists, /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); + /* Set up VOL callback arguments */ + map_args.exists.key_mem_type_id = key_mem_type_id; + map_args.exists.key = key; + map_args.exists.exists = FALSE; + vol_cb_args.op_type = H5VL_MAP_EXISTS; + vol_cb_args.args = &map_args; + /* Check if key exists */ - if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_EXISTS, dxpl_id, H5_REQUEST_NULL, key_mem_type_id, key, - exists)) < 0) + if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTGET, ret_value, "unable to check if key exists") + /* Set value to return */ + if (exists) + *exists = map_args.exists.exists; + done: FUNC_LEAVE_API(ret_value) } /* end H5Mexists() */ @@ -1203,9 +1328,10 @@ done: herr_t H5Miterate(hid_t map_id, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, void *op_data, hid_t dxpl_id) { - H5VL_object_t * vol_obj = NULL; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "i*hiMI*xi", map_id, idx, key_mem_type_id, op, op_data, dxpl_id); @@ -1229,14 +1355,23 @@ H5Miterate(hid_t map_id, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); - /* Set location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(map_id); + /* Set up VOL callback arguments */ + map_args.specific.specific_type = H5VL_MAP_ITER; + map_args.specific.args.iterate.loc_params.type = H5VL_OBJECT_BY_SELF; + map_args.specific.args.iterate.loc_params.obj_type = H5I_get_type(map_id); + map_args.specific.args.iterate.idx = (idx ? *idx : 0); + map_args.specific.args.iterate.op = op; + map_args.specific.args.iterate.op_data = op_data; + vol_cb_args.op_type = H5VL_MAP_SPECIFIC; + vol_cb_args.args = &map_args; /* Iterate over keys */ - if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params, - H5VL_MAP_ITER, idx, key_mem_type_id, op, op_data)) < 0) - HGOTO_ERROR(H5E_MAP, H5E_BADITER, ret_value, "unable to iterate over keys") + if ((ret_value = H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL)) < 0) + HERROR(H5E_MAP, H5E_BADITER, "unable to iterate over keys"); + + /* Set value to return */ + if (idx) + *idx = map_args.specific.args.iterate.idx; done: FUNC_LEAVE_API(ret_value) @@ -1277,9 +1412,10 @@ herr_t H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *idx, hid_t key_mem_type_id, H5M_iterate_t op, void *op_data, hid_t dxpl_id, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*s*hiMI*xii", loc_id, map_name, idx, key_mem_type_id, op, op_data, dxpl_id, lapl_id); @@ -1307,16 +1443,25 @@ H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *idx, hid_t key_m /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); - /* Set location struct fields */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.obj_type = H5I_get_type(loc_id); - loc_params.loc_data.loc_by_name.name = map_name; - loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + /* Set up VOL callback arguments */ + map_args.specific.specific_type = H5VL_MAP_ITER; + map_args.specific.args.iterate.loc_params.type = H5VL_OBJECT_BY_NAME; + map_args.specific.args.iterate.loc_params.obj_type = H5I_get_type(loc_id); + map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.name = map_name; + map_args.specific.args.iterate.loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + map_args.specific.args.iterate.idx = (idx ? *idx : 0); + map_args.specific.args.iterate.op = op; + map_args.specific.args.iterate.op_data = op_data; + vol_cb_args.op_type = H5VL_MAP_SPECIFIC; + vol_cb_args.args = &map_args; /* Iterate over keys */ - if ((ret_value = H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params, - H5VL_MAP_ITER, idx, key_mem_type_id, op, op_data)) < 0) - HGOTO_ERROR(H5E_MAP, H5E_BADITER, ret_value, "unable to ierate over keys") + if ((ret_value = H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL)) < 0) + HERROR(H5E_MAP, H5E_BADITER, "unable to ierate over keys"); + + /* Set value to return */ + if (idx) + *idx = map_args.specific.args.iterate.idx; done: FUNC_LEAVE_API(ret_value) @@ -1340,9 +1485,10 @@ done: herr_t H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id) { - H5VL_object_t * vol_obj = NULL; - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_map_args_t map_args; /* Arguments for map operations */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "ii*xi", map_id, key_mem_type_id, key, dxpl_id); @@ -1364,13 +1510,17 @@ H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id) /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); - /* Set location struct fields */ - loc_params.type = H5VL_OBJECT_BY_SELF; - loc_params.obj_type = H5I_get_type(map_id); + /* Set up VOL callback arguments */ + map_args.specific.specific_type = H5VL_MAP_DELETE; + map_args.specific.args.del.loc_params.type = H5VL_OBJECT_BY_SELF; + map_args.specific.args.del.loc_params.obj_type = H5I_get_type(map_id); + map_args.specific.args.del.key_mem_type_id = key_mem_type_id; + map_args.specific.args.del.key = key; + vol_cb_args.op_type = H5VL_MAP_SPECIFIC; + vol_cb_args.args = &map_args; /* Delete the key/value pair */ - if (H5VL_optional(vol_obj, H5VL_MAP_SPECIFIC, dxpl_id, H5_REQUEST_NULL, &loc_params, H5VL_MAP_DELETE, - key_mem_type_id, key) < 0) + if (H5VL_optional(vol_obj, &vol_cb_args, dxpl_id, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "unable to delete key/value pair") done: diff --git a/src/H5MF.c b/src/H5MF.c index fd38495..ca780c3 100644 --- a/src/H5MF.c +++ b/src/H5MF.c @@ -2463,15 +2463,15 @@ done: * Purpose: To retrieve free-space section information for * paged or non-paged aggregation * - * Return: Success: Number of free sections - * Failure: -1 + * Return: SUCCEED/FAIL * * Programmer: Vailin Choi; Dec 2012 * *------------------------------------------------------------------------- */ -ssize_t -H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t *sect_info) +herr_t +H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t *sect_info, + size_t *sect_count) { H5AC_ring_t orig_ring = H5AC_RING_INV; /* Original ring value */ H5AC_ring_t curr_ring = H5AC_RING_INV; /* Current ring value */ @@ -2480,9 +2480,9 @@ H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t H5MF_sect_iter_ud_t sect_udata; /* User data for callback */ H5F_mem_page_t start_type, end_type; /* Memory types to iterate over */ H5F_mem_page_t ty; /* Memory type for iteration */ - ssize_t ret_value = -1; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, (-1)) + FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL) /* check args */ HDassert(f); @@ -2544,7 +2544,7 @@ H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t if (!f->shared->fs_man[ty] && H5F_addr_defined(f->shared->fs_addr[ty])) { if (H5MF__open_fstype(f, ty) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, (-1), "can't open the free space manager") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't open the free space manager") HDassert(f->shared->fs_man[ty]); fs_started = TRUE; } /* end if */ @@ -2552,7 +2552,7 @@ H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t /* Check if there's free space sections of this type */ if (f->shared->fs_man[ty]) if (H5MF__get_free_sects(f, f->shared->fs_man[ty], §_udata, &nums) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, (-1), + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't get section info for the free space manager") /* Increment total # of sections */ @@ -2561,13 +2561,13 @@ H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t /* Close the free space manager of this type, if we started it here */ if (fs_started) if (H5MF__close_fstype(f, ty) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCLOSEOBJ, (-1), "can't close file free space") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCLOSEOBJ, FAIL, "can't close file free space") if ((H5F_PAGED_AGGR(f)) && (type != H5FD_MEM_DEFAULT)) ty = (H5F_mem_page_t)(ty + H5FD_MEM_NTYPES - 2); } /* end for */ - /* Set return value */ - ret_value = (ssize_t)total_sects; + /* Set value to return */ + *sect_count = total_sects; done: /* Reset the ring in the API context */ diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index 81bf36d..e55b00f 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -56,7 +56,8 @@ H5_DLL haddr_t H5MF_aggr_vfd_alloc(H5F_t *f, H5FD_mem_t type, hsize_t size); H5_DLL herr_t H5MF_xfree(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size); H5_DLL herr_t H5MF_try_extend(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested); H5_DLL htri_t H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size); -H5_DLL ssize_t H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t *sect_info); +H5_DLL herr_t H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t *sect_info, + size_t *sect_count); /* File 'temporary' space allocation routines */ H5_DLL haddr_t H5MF_alloc_tmp(H5F_t *f, hsize_t size); diff --git a/src/H5Mmodule.h b/src/H5Mmodule.h index 3dae3e2..848f63f 100644 --- a/src/H5Mmodule.h +++ b/src/H5Mmodule.h @@ -26,9 +26,9 @@ #define H5_MY_PKG_ERR H5E_MAP #define H5_MY_PKG_INIT YES -/** - * \defgroup H5M H5M - * \brief Map Interface +/**\defgroup H5M H5M + * + * \todo Describe the map life cycle. * * \details \Bold{The interface can only be used with the HDF5 VOL connectors that * implement map objects.} The native HDF5 library does not support this diff --git a/src/H5Mprivate.h b/src/H5Mprivate.h index 1a2524e..e62434a 100644 --- a/src/H5Mprivate.h +++ b/src/H5Mprivate.h @@ -21,10 +21,9 @@ #include "H5Mpublic.h" /* Private headers needed by this file */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5Oprivate.h" /* Object headers */ -#include "H5Sprivate.h" /* Dataspaces */ -#include "H5Zprivate.h" /* Data filters */ +#include "H5Oprivate.h" /* Object headers */ +#include "H5Sprivate.h" /* Dataspaces */ +#include "H5Zprivate.h" /* Data filters */ /**************************/ /* Library Private Macros */ diff --git a/src/H5Mpublic.h b/src/H5Mpublic.h index 3f6bf01..3f94edb 100644 --- a/src/H5Mpublic.h +++ b/src/H5Mpublic.h @@ -25,6 +25,7 @@ /* Public headers needed by this file */ #include "H5public.h" #include "H5Ipublic.h" +#include "H5VLconnector.h" /*****************/ /* Public Macros */ @@ -68,6 +69,115 @@ typedef enum H5VL_map_specific_t { typedef herr_t (*H5M_iterate_t)(hid_t map_id, const void *key, void *op_data); //! <!-- [H5M_iterate_t_snip] --> +/* Parameters for map operations */ +typedef union H5VL_map_args_t { + /* H5VL_MAP_CREATE */ + struct { + H5VL_loc_params_t loc_params; /* Location parameters for object */ + const char * name; /* Name of new map object */ + hid_t lcpl_id; /* Link creation property list for map */ + hid_t key_type_id; /* Datatype for map keys */ + hid_t val_type_id; /* Datatype for map values */ + hid_t mcpl_id; /* Map creation property list */ + hid_t mapl_id; /* Map access property list */ + void * map; /* Pointer to newly created map object (OUT) */ + } create; + + /* H5VL_MAP_OPEN */ + struct { + H5VL_loc_params_t loc_params; /* Location parameters for object */ + const char * name; /* Name of new map object */ + hid_t mapl_id; /* Map access property list */ + void * map; /* Pointer to newly created map object (OUT) */ + } open; + + /* H5VL_MAP_GET_VAL */ + struct { + hid_t key_mem_type_id; /* Memory datatype for key */ + const void *key; /* Pointer to key */ + hid_t value_mem_type_id; /* Memory datatype for value */ + void * value; /* Buffer for value (OUT) */ + } get_val; + + /* H5VL_MAP_EXISTS */ + struct { + hid_t key_mem_type_id; /* Memory datatype for key */ + const void *key; /* Pointer to key */ + hbool_t exists; /* Flag indicating whether key exists in map (OUT) */ + } exists; + + /* H5VL_MAP_PUT */ + struct { + hid_t key_mem_type_id; /* Memory datatype for key */ + const void *key; /* Pointer to key */ + hid_t value_mem_type_id; /* Memory datatype for value */ + const void *value; /* Pointer to value */ + } put; + + /* H5VL_MAP_GET */ + struct { + H5VL_map_get_t get_type; /* 'get' operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_MAP_GET_MAPL */ + struct { + hid_t mapl_id; /* Map access property list ID (OUT) */ + } get_mapl; + + /* H5VL_MAP_GET_MCPL */ + struct { + hid_t mcpl_id; /* Map creation property list ID (OUT) */ + } get_mcpl; + + /* H5VL_MAP_GET_KEY_TYPE */ + struct { + hid_t type_id; /* Datatype ID for map's keys (OUT) */ + } get_key_type; + + /* H5VL_MAP_GET_VAL_TYPE */ + struct { + hid_t type_id; /* Datatype ID for map's values (OUT) */ + } get_val_type; + + /* H5VL_MAP_GET_COUNT */ + struct { + hsize_t count; /* # of KV pairs in map (OUT) */ + } get_count; + } args; + } get; + + /* H5VL_MAP_SPECIFIC */ + struct { + H5VL_map_specific_t specific_type; /* 'specific' operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_MAP_ITER */ + struct { + H5VL_loc_params_t loc_params; /* Location parameters for object */ + hsize_t idx; /* Start/end iteration index (IN/OUT) */ + hid_t key_mem_type_id; /* Memory datatype for key */ + H5M_iterate_t op; /* Iteration callback routine */ + void * op_data; /* Pointer to callback context */ + } iterate; + + /* H5VL_MAP_DELETE */ + struct { + H5VL_loc_params_t loc_params; /* Location parameters for object */ + hid_t key_mem_type_id; /* Memory datatype for key */ + const void * key; /* Pointer to key */ + } del; + } args; + } specific; + + /* H5VL_MAP_OPTIONAL */ + /* Unused */ + + /* H5VL_MAP_CLOSE */ + /* No args */ +} H5VL_map_args_t; + /********************/ /* Public Variables */ /********************/ @@ -478,6 +588,7 @@ H5_DLL herr_t H5Miterate_by_name(hid_t loc_id, const char *map_name, hsize_t *id */ H5_DLL herr_t H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t dxpl_id); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -496,6 +607,7 @@ H5_DLL herr_t H5Mdelete(hid_t map_id, hid_t key_mem_type_id, const void *key, hi #define H5Mput_async_wrap H5_NO_EXPAND(H5Mput_async) #define H5Mget_async_wrap H5_NO_EXPAND(H5Mget_async) #endif /* H5M_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5O.c b/src/H5O.c index 732473f..db3ff31 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -70,7 +70,7 @@ static herr_t H5O__copy_api_common(hid_t src_loc_id, const char *src_name, hid_t H5VL_object_t **_vol_obj_ptr); static herr_t H5O__flush_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_ptr); static herr_t H5O__refresh_api_common(hid_t oid, void **token_ptr, H5VL_object_t **_vol_obj_ptr); -static htri_t H5O__close_check_common(hid_t object_id); +static htri_t H5O__close_check_type(hid_t object_id); /*********************/ /* Package Variables */ @@ -112,7 +112,7 @@ H5O__open_api_common(hid_t loc_id, const char *name, hid_t lapl_id, void **token /* name is checked in this H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") /* Open the object */ @@ -239,7 +239,7 @@ H5O__open_by_idx_api_common(hid_t loc_id, const char *group_name, H5_index_t idx /* Check args */ /* group_name, idx_type, order are checked in H5VL_setup_idx-args() */ /* Set up object access arguments */ - if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, + if (H5VL_setup_idx_args(loc_id, group_name, idx_type, order, n, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTSET, H5I_INVALID_HID, "can't set object access arguments") @@ -617,8 +617,9 @@ H5O__flush_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_p H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -626,9 +627,13 @@ H5O__flush_api_common(hid_t obj_id, void **token_ptr, H5VL_object_t **_vol_obj_p if (H5VL_setup_loc_args(obj_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_FLUSH; + vol_cb_args.args.flush.obj_id = obj_id; + /* Flush the object */ - if (H5VL_object_specific(*vol_obj_ptr, &loc_params, H5VL_OBJECT_FLUSH, H5P_DATASET_XFER_DEFAULT, - token_ptr, obj_id) < 0) + if (H5VL_object_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object") done: @@ -718,8 +723,9 @@ H5O__refresh_api_common(hid_t oid, void **token_ptr, H5VL_object_t **_vol_obj_pt H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -727,9 +733,13 @@ H5O__refresh_api_common(hid_t oid, void **token_ptr, H5VL_object_t **_vol_obj_pt if (H5VL_setup_loc_args(oid, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_REFRESH; + vol_cb_args.args.refresh.obj_id = oid; + /* Refresh the object */ - if (H5VL_object_specific(*vol_obj_ptr, &loc_params, H5VL_OBJECT_REFRESH, H5P_DATASET_XFER_DEFAULT, - token_ptr, oid) < 0) + if (H5VL_object_specific(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") done: @@ -828,12 +838,12 @@ done: herr_t H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id) { - H5VL_object_t * vol_obj1 = NULL; /* object of obj_id */ - H5VL_object_t * vol_obj2 = NULL; /* object of new_loc_id */ - H5VL_object_t tmp_vol_obj; /* Temporary object */ - H5VL_loc_params_t loc_params1; - H5VL_loc_params_t loc_params2; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj1 = NULL; /* object of obj_id */ + H5VL_object_t * vol_obj2 = NULL; /* object of new_loc_id */ + H5VL_object_t tmp_vol_obj; /* Temporary object */ + H5VL_link_create_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t new_loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "ii*sii", obj_id, new_loc_id, new_name, lcpl_id, lapl_id); @@ -863,36 +873,45 @@ H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, obj_id, TRUE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") - loc_params1.type = H5VL_OBJECT_BY_SELF; - loc_params1.obj_type = H5I_get_type(obj_id); - - loc_params2.type = H5VL_OBJECT_BY_NAME; - loc_params2.obj_type = H5I_get_type(new_loc_id); - loc_params2.loc_data.loc_by_name.name = new_name; - loc_params2.loc_data.loc_by_name.lapl_id = lapl_id; + /* Set up new location struct */ + new_loc_params.type = H5VL_OBJECT_BY_NAME; + new_loc_params.obj_type = H5I_get_type(new_loc_id); + new_loc_params.loc_data.loc_by_name.name = new_name; + new_loc_params.loc_data.loc_by_name.lapl_id = lapl_id; - if (H5L_SAME_LOC != obj_id) - /* get the location object */ - if (NULL == (vol_obj1 = H5VL_vol_object(obj_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Get the first location object */ + if (NULL == (vol_obj1 = H5VL_vol_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") if (H5L_SAME_LOC != new_loc_id) /* get the location object */ if (NULL == (vol_obj2 = H5VL_vol_object(new_loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") /* Make sure that the VOL connectors are the same */ - if (vol_obj1 && vol_obj2) - if (vol_obj1->connector->cls->value != vol_obj2->connector->cls->value) + if (vol_obj1 && vol_obj2) { + int same_connector = 0; + + /* Check if both objects are associated with the same VOL connector */ + if (H5VL_cmp_connector_cls(&same_connector, vol_obj1->connector->cls, vol_obj2->connector->cls) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOMPARE, FAIL, "can't compare connector classes") + if (same_connector) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL connectors and can't be linked") + } /* end if */ /* Construct a temporary VOL object */ tmp_vol_obj.data = vol_obj2->data; - tmp_vol_obj.connector = (vol_obj1 != NULL ? vol_obj1->connector : vol_obj2->connector); + tmp_vol_obj.connector = vol_obj1->connector; + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_LINK_CREATE_HARD; + vol_cb_args.args.hard.curr_obj = vol_obj1->data; + vol_cb_args.args.hard.curr_loc_params.type = H5VL_OBJECT_BY_SELF; + vol_cb_args.args.hard.curr_loc_params.obj_type = H5I_get_type(obj_id); /* Create a link to the object */ - if (H5VL_link_create(H5VL_LINK_CREATE_HARD, &tmp_vol_obj, &loc_params2, lcpl_id, lapl_id, - H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, vol_obj1->data, &loc_params1) < 0) + if (H5VL_link_create(&vol_cb_args, &tmp_vol_obj, &new_loc_params, lcpl_id, lapl_id, + H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "unable to create link") done: @@ -922,9 +941,10 @@ done: herr_t H5Oincr_refcount(hid_t object_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", object_id); @@ -940,9 +960,13 @@ H5Oincr_refcount(hid_t object_id) if (H5CX_set_loc(object_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_CHANGE_REF_COUNT; + vol_cb_args.args.change_rc.delta = 1; + /* Change the object's reference count */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_CHANGE_REF_COUNT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, 1) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "modifying object link count failed") done: @@ -972,9 +996,10 @@ done: herr_t H5Odecr_refcount(hid_t object_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", object_id); @@ -990,9 +1015,13 @@ H5Odecr_refcount(hid_t object_id) if (H5CX_set_loc(object_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_CHANGE_REF_COUNT; + vol_cb_args.args.change_rc.delta = -1; + /* Change the object's reference count */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_CHANGE_REF_COUNT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, -1) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "modifying object link count failed") done: @@ -1015,9 +1044,11 @@ done: htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - htri_t ret_value = FAIL; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + hbool_t obj_exists = FALSE; /* Whether object exists */ + htri_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("t", "i*si", loc_id, name, lapl_id); @@ -1042,11 +1073,18 @@ H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id) loc_params.loc_data.loc_by_name.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_EXISTS; + vol_cb_args.args.exists.exists = &obj_exists; + /* Check if the object exists */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_EXISTS, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &ret_value) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine if '%s' exists", name) + /* Set return value */ + ret_value = (htri_t)obj_exists; + done: FUNC_LEAVE_API(ret_value) } /* end H5Oexists_by_name() */ @@ -1066,9 +1104,10 @@ done: herr_t H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo /*out*/, unsigned fields) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ixIu", loc_id, oinfo, fields); @@ -1087,9 +1126,13 @@ H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo /*out*/, unsigned fields) if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = oinfo; + vol_cb_args.args.get_info.fields = fields; + /* Retrieve the object's information */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - oinfo, fields) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") done: @@ -1113,8 +1156,9 @@ H5O__get_info_by_name_api_common(hid_t loc_id, const char *name, H5O_info2_t *oi H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters for object access */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1126,12 +1170,16 @@ H5O__get_info_by_name_api_common(hid_t loc_id, const char *name, H5O_info2_t *oi /* "name" is checked in H5VL_setup_name_args() */ /* Set up object access arguments */ - if (H5VL_setup_name_args(loc_id, name, H5P_CLS_LACC, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, vol_obj_ptr, &loc_params) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set object access arguments") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = oinfo; + vol_cb_args.args.get_info.fields = fields; + /* Retrieve the object's information */ - if (H5VL_object_get(*vol_obj_ptr, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, token_ptr, - oinfo, fields) < 0) + if (H5VL_object_get(*vol_obj_ptr, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") done: @@ -1228,9 +1276,10 @@ herr_t H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info2_t *oinfo /*out*/, unsigned fields, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIohxIui", loc_id, group_name, idx_type, order, n, oinfo, fields, lapl_id); @@ -1251,6 +1300,7 @@ H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type, H if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set location struct fields */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -1263,9 +1313,13 @@ H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index_t idx_type, H if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = oinfo; + vol_cb_args.args.get_info.fields = fields; + /* Retrieve the object's information */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - oinfo, fields) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") done: @@ -1287,9 +1341,11 @@ done: herr_t H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo /*out*/, unsigned fields) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ixIu", loc_id, oinfo, fields); @@ -1308,9 +1364,15 @@ H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo /*out*/, unsigned fiel if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.get_native_info.fields = fields; + obj_opt_args.get_native_info.ninfo = oinfo; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_NATIVE_INFO; + vol_cb_args.args = &obj_opt_args; + /* Retrieve the object's information */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native file format info for object") done: @@ -1333,9 +1395,11 @@ herr_t H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oinfo /*out*/, unsigned fields, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*sxIui", loc_id, name, oinfo, fields, lapl_id); @@ -1364,9 +1428,15 @@ H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_native_info_t *oi if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.get_native_info.fields = fields; + obj_opt_args.get_native_info.ninfo = oinfo; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_NATIVE_INFO; + vol_cb_args.args = &obj_opt_args; + /* Retrieve the object's information */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native file format info for object: '%s'", name) done: @@ -1391,9 +1461,11 @@ herr_t H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_native_info_t *oinfo /*out*/, unsigned fields, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIohxIui", loc_id, group_name, idx_type, order, n, oinfo, fields, lapl_id); @@ -1414,6 +1486,7 @@ H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_t if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set access property list info") + /* Set location struct fields */ loc_params.type = H5VL_OBJECT_BY_IDX; loc_params.loc_data.loc_by_idx.name = group_name; loc_params.loc_data.loc_by_idx.idx_type = idx_type; @@ -1426,9 +1499,15 @@ H5Oget_native_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_t if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.get_native_info.fields = fields; + obj_opt_args.get_native_info.ninfo = oinfo; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_NATIVE_INFO; + vol_cb_args.args = &obj_opt_args; + /* Retrieve the object's information */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, oinfo, fields) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native file format info for object") done: @@ -1455,9 +1534,11 @@ done: herr_t H5Oset_comment(hid_t obj_id, const char *comment) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*s", obj_id, comment); @@ -1474,9 +1555,14 @@ H5Oset_comment(hid_t obj_id, const char *comment) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(obj_id); + /* Set up VOL callback arguments */ + obj_opt_args.set_comment.comment = comment; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_SET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* (Re)set the object's comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_SET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, comment) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set comment for object") done: @@ -1503,9 +1589,11 @@ done: herr_t H5Oset_comment_by_name(hid_t loc_id, const char *name, const char *comment, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*s*si", loc_id, name, comment, lapl_id); @@ -1528,9 +1616,14 @@ H5Oset_comment_by_name(hid_t loc_id, const char *name, const char *comment, hid_ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.set_comment.comment = comment; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_SET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* (Re)set the object's comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_SET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, comment) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set comment for object: '%s'", name) done: @@ -1556,9 +1649,12 @@ done: ssize_t H5Oget_comment(hid_t obj_id, char *comment /*out*/, size_t bufsize) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + size_t comment_len = 0; /* Length of comment string */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE3("Zs", "ixz", obj_id, comment, bufsize); @@ -1571,11 +1667,21 @@ H5Oget_comment(hid_t obj_id, char *comment /*out*/, size_t bufsize) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(obj_id); + /* Set up VOL callback arguments */ + obj_opt_args.get_comment.buf = comment; + obj_opt_args.get_comment.buf_size = bufsize; + obj_opt_args.get_comment.comment_len = &comment_len; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* Retrieve the object's comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, comment, bufsize, &ret_value) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, (-1), "can't get comment for object") + /* Set return value */ + ret_value = (ssize_t)comment_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Oget_comment() */ @@ -1599,9 +1705,12 @@ done: ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment /*out*/, size_t bufsize, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; + size_t comment_len = 0; /* Length of comment string */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE5("Zs", "i*sxzi", loc_id, name, comment, bufsize, lapl_id); @@ -1624,11 +1733,21 @@ H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment /*out*/, si if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") + /* Set up VOL callback arguments */ + obj_opt_args.get_comment.buf = comment; + obj_opt_args.get_comment.buf_size = bufsize; + obj_opt_args.get_comment.comment_len = &comment_len; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_COMMENT; + vol_cb_args.args = &obj_opt_args; + /* Retrieve the object's comment */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_COMMENT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, comment, bufsize, &ret_value) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, (-1), "can't get comment for object: '%s'", name) + /* Set return value */ + ret_value = (ssize_t)comment_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Oget_comment_by_name() */ @@ -1672,9 +1791,10 @@ herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iIiIoOI*xIu", obj_id, idx_type, order, op, op_data, fields); @@ -1697,10 +1817,17 @@ H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate2 loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(obj_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = op; + vol_cb_args.args.visit.op_data = op_data; + vol_cb_args.args.visit.fields = fields; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, op, op_data, fields)) < - 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object iteration failed") done: @@ -1746,9 +1873,10 @@ herr_t H5Ovisit_by_name3(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate2_t op, void *op_data, unsigned fields, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIoOI*xIui", loc_id, obj_name, idx_type, order, op, op_data, fields, lapl_id); @@ -1781,10 +1909,17 @@ H5Ovisit_by_name3(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_it loc_params.loc_data.loc_by_name.lapl_id = lapl_id; loc_params.obj_type = H5I_get_type(loc_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = op; + vol_cb_args.args.visit.op_data = op_data; + vol_cb_args.args.visit.fields = fields; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, op, op_data, fields)) < - 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object iteration failed") done: @@ -1792,23 +1927,23 @@ done: } /* end H5Ovisit_by_name3() */ /*------------------------------------------------------------------------- - * Function: H5O__close_check_common + * Function: H5O__close_check_type * * Purpose: This is the common function to validate an object - * when closing it. + * before closing it. * * Return: TRUE/FALSE/FAIL * *------------------------------------------------------------------------- */ static htri_t -H5O__close_check_common(hid_t object_id) +H5O__close_check_type(hid_t object_id) { htri_t ret_value = TRUE; /* Return value */ FUNC_ENTER_STATIC - /* Get the type of the object and close it in the correct way */ + /* Check for closeable object */ switch (H5I_get_type(object_id)) { case H5I_GROUP: case H5I_DATATYPE: @@ -1834,14 +1969,13 @@ H5O__close_check_common(hid_t object_id) case H5I_EVENTSET: case H5I_NTYPES: default: - HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FALSE, - "not a valid file object ID (dataset, group, or datatype)") + HGOTO_DONE(FALSE); break; } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5O__close_check_common() */ +} /* H5O__close_check_type() */ /*------------------------------------------------------------------------- * Function: H5Oclose @@ -1869,7 +2003,7 @@ H5Oclose(hid_t object_id) H5TRACE1("e", "i", object_id); /* Validate the object type before closing */ - if (H5O__close_check_common(object_id) <= 0) + if (H5O__close_check_type(object_id) <= 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "not a valid object") if (H5I_dec_app_ref(object_id) < 0) @@ -1901,7 +2035,7 @@ H5Oclose_async(const char *app_file, const char *app_func, unsigned app_line, hi H5TRACE5("e", "*s*sIuii", app_file, app_func, app_line, object_id, es_id); /* Validate the object type before closing */ - if (H5O__close_check_common(object_id) <= 0) + if (H5O__close_check_type(object_id) <= 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "not a valid object") /* Prepare for possible asynchronous operation */ @@ -1941,7 +2075,7 @@ done: } /* end H5Oclose_async() */ /*------------------------------------------------------------------------- - * Function: H5O_disable_mdc_flushes + * Function: H5O__disable_mdc_flushes * * Purpose: Private version of the metadata cache cork function. * @@ -1950,18 +2084,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_disable_mdc_flushes(H5O_loc_t *oloc) +H5O__disable_mdc_flushes(H5O_loc_t *oloc) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL); + FUNC_ENTER_PACKAGE if (H5AC_cork(oloc->file, oloc->addr, H5AC__SET_CORK, NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCORK, FAIL, "unable to cork object"); done: FUNC_LEAVE_NOAPI(ret_value); -} /* H5O_disable_mdc_flushes() */ +} /* H5O__disable_mdc_flushes() */ /*------------------------------------------------------------------------- * Function: H5Odisable_mdc_flushes @@ -1980,9 +2114,10 @@ done: herr_t H5Odisable_mdc_flushes(hid_t object_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE1("e", "i", object_id); @@ -1999,9 +2134,13 @@ H5Odisable_mdc_flushes(hid_t object_id) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(object_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_DISABLE_MDC_FLUSHES; + vol_cb_args.args = NULL; + /* Cork the object */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_DISABLE_MDC_FLUSHES, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCORK, FAIL, "unable to cork object"); done: @@ -2009,7 +2148,7 @@ done: } /* H5Odisable_mdc_flushes() */ /*------------------------------------------------------------------------- - * Function: H5O_enable_mdc_flushes + * Function: H5O__enable_mdc_flushes * * Purpose: Private version of the metadata cache uncork function. * @@ -2018,18 +2157,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_enable_mdc_flushes(H5O_loc_t *oloc) +H5O__enable_mdc_flushes(H5O_loc_t *oloc) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL); + FUNC_ENTER_PACKAGE if (H5AC_cork(oloc->file, oloc->addr, H5AC__UNCORK, NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTUNCORK, FAIL, "unable to uncork object"); done: FUNC_LEAVE_NOAPI(ret_value); -} /* H5O_enable_mdc_flushes() */ +} /* H5O__enable_mdc_flushes() */ /*------------------------------------------------------------------------- * Function: H5Oenable_mdc_flushes @@ -2048,9 +2187,10 @@ done: herr_t H5Oenable_mdc_flushes(hid_t object_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE1("e", "i", object_id); @@ -2067,9 +2207,13 @@ H5Oenable_mdc_flushes(hid_t object_id) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(object_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_ENABLE_MDC_FLUSHES; + vol_cb_args.args = NULL; + /* Uncork the object */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_ENABLE_MDC_FLUSHES, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTUNCORK, FAIL, "unable to uncork object"); done: @@ -2077,7 +2221,7 @@ done: } /* H5Oenable_mdc_flushes() */ /*------------------------------------------------------------------------- - * Function: H5O_are_mdc_flushes_disabled + * Function: H5O__are_mdc_flushes_disabled * * Purpose: Private version of cork status getter. * @@ -2086,11 +2230,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_are_mdc_flushes_disabled(H5O_loc_t *oloc, hbool_t *are_disabled) +H5O__are_mdc_flushes_disabled(const H5O_loc_t *oloc, hbool_t *are_disabled) { herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(FAIL); + FUNC_ENTER_PACKAGE HDassert(are_disabled); @@ -2099,7 +2243,7 @@ H5O_are_mdc_flushes_disabled(H5O_loc_t *oloc, hbool_t *are_disabled) done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5O_are_mdc_flushes_disabled() */ +} /* H5O__are_mdc_flushes_disabled() */ /*------------------------------------------------------------------------- * Function: H5Oare_mdc_flushes_disabled @@ -2121,9 +2265,11 @@ done: herr_t H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; /* Location parameters */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL); H5TRACE2("e", "i*b", object_id, are_disabled); @@ -2144,9 +2290,14 @@ H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled) loc_params.type = H5VL_OBJECT_BY_SELF; loc_params.obj_type = H5I_get_type(object_id); + /* Set up VOL callback arguments */ + obj_opt_args.are_mdc_flushes_disabled.flag = are_disabled; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED; + vol_cb_args.args = &obj_opt_args; + /* Get the cork status */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, are_disabled) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < + 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve object's cork status"); done: diff --git a/src/H5Ocache.c b/src/H5Ocache.c index a968f84..8eed092 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -78,8 +78,8 @@ static herr_t H5O__cache_chk_free_icr(void *thing); static herr_t H5O__prefix_deserialize(const uint8_t *image, H5O_cache_ud_t *udata); /* Chunk routines */ -static herr_t H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len, const uint8_t *image, - H5O_common_cache_ud_t *udata, hbool_t *dirty); +static herr_t H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t chunk_size, const uint8_t *image, + size_t len, H5O_common_cache_ud_t *udata, hbool_t *dirty); static herr_t H5O__chunk_serialize(const H5F_t *f, H5O_t *oh, unsigned chunkno); /* Misc. routines */ @@ -289,7 +289,7 @@ H5O__cache_verify_chksum(const void *_image, size_t len, void *_udata) *------------------------------------------------------------------------- */ static void * -H5O__cache_deserialize(const void *image, size_t H5_ATTR_NDEBUG_UNUSED len, void *_udata, hbool_t *dirty) +H5O__cache_deserialize(const void *image, size_t len, void *_udata, hbool_t *dirty) { H5O_t * oh = NULL; /* Object header read in */ H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata; /* User data for callback */ @@ -335,7 +335,7 @@ H5O__cache_deserialize(const void *image, size_t H5_ATTR_NDEBUG_UNUSED len, void oh->proxy = NULL; /* Parse the first chunk */ - if (H5O__chunk_deserialize(oh, udata->common.addr, udata->chunk0_size, (const uint8_t *)image, + if (H5O__chunk_deserialize(oh, udata->common.addr, udata->chunk0_size, (const uint8_t *)image, len, &(udata->common), dirty) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't deserialize first object header chunk") @@ -738,7 +738,7 @@ H5O__cache_chk_verify_chksum(const void *_image, size_t len, void *_udata) *------------------------------------------------------------------------- */ static void * -H5O__cache_chk_deserialize(const void *image, size_t H5_ATTR_NDEBUG_UNUSED len, void *_udata, hbool_t *dirty) +H5O__cache_chk_deserialize(const void *image, size_t len, void *_udata, hbool_t *dirty) { H5O_chunk_proxy_t * chk_proxy = NULL; /* Chunk proxy object */ H5O_chk_cache_ud_t *udata = (H5O_chk_cache_ud_t *)_udata; /* User data for callback */ @@ -765,7 +765,7 @@ H5O__cache_chk_deserialize(const void *image, size_t H5_ATTR_NDEBUG_UNUSED len, HDassert(udata->common.cont_msg_info); /* Parse the chunk */ - if (H5O__chunk_deserialize(udata->oh, udata->common.addr, udata->size, (const uint8_t *)image, + if (H5O__chunk_deserialize(udata->oh, udata->common.addr, udata->size, (const uint8_t *)image, len, &(udata->common), dirty) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't deserialize object header chunk") @@ -1277,7 +1277,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len, const uint8_t *image, +H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t chunk_size, const uint8_t *image, size_t len, H5O_common_cache_ud_t *udata, hbool_t *dirty) { const uint8_t *chunk_image; /* Pointer into buffer to decode */ @@ -1297,6 +1297,7 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len, const uint8_t *image HDassert(oh); HDassert(H5F_addr_defined(addr)); HDassert(image); + HDassert(len); HDassert(udata->f); HDassert(udata->cont_msg_info); @@ -1317,14 +1318,16 @@ H5O__chunk_deserialize(H5O_t *oh, haddr_t addr, size_t len, const uint8_t *image oh->chunk[chunkno].addr = addr; if (chunkno == 0) /* First chunk's 'image' includes room for the object header prefix */ - oh->chunk[0].size = len + (size_t)H5O_SIZEOF_HDR(oh); + oh->chunk[0].size = chunk_size + (size_t)H5O_SIZEOF_HDR(oh); else - oh->chunk[chunkno].size = len; + oh->chunk[chunkno].size = chunk_size; if (NULL == (oh->chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image, oh->chunk[chunkno].size))) HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, FAIL, "memory allocation failed") oh->chunk[chunkno].chunk_proxy = NULL; /* Copy disk image into chunk's image */ + if (len < oh->chunk[chunkno].size) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "attempted to copy too many disk image bytes into buffer") H5MM_memcpy(oh->chunk[chunkno].image, image, oh->chunk[chunkno].size); /* Point into chunk image to decode */ diff --git a/src/H5Odeprec.c b/src/H5Odeprec.c index 5e13f9f..7def20a 100644 --- a/src/H5Odeprec.c +++ b/src/H5Odeprec.c @@ -122,8 +122,6 @@ H5O__iterate1_adapter(hid_t obj_id, const char *name, const H5O_info2_t *oinfo2, H5O_info1_t oinfo; /* Deprecated object info struct */ unsigned dm_fields; /* Fields for data model query */ unsigned nat_fields; /* Fields for native query */ - H5VL_object_t * vol_obj; /* Object of obj_id */ - H5VL_loc_params_t loc_params; /* Location parameters for VOL callback */ herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_STATIC @@ -160,24 +158,34 @@ H5O__iterate1_adapter(hid_t obj_id, const char *name, const H5O_info2_t *oinfo2, oinfo.num_attrs = oinfo2->num_attrs; } - /* Fill out location struct */ - loc_params.type = H5VL_OBJECT_BY_NAME; - loc_params.loc_data.loc_by_name.name = name; - loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; - loc_params.obj_type = H5I_get_type(obj_id); - - /* Get the location object */ - if (NULL == (vol_obj = H5VL_vol_object(obj_id))) - HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, H5_ITER_ERROR, "invalid location identifier") - /* Check for retrieving native information */ nat_fields = shim_data->fields & (H5O_INFO_HDR | H5O_INFO_META_SIZE); if (nat_fields) { - H5O_native_info_t nat_info; /* Native object info */ + H5VL_object_t * vol_obj; /* Object of obj_id */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5VL_loc_params_t loc_params; /* Location parameters for VOL callback */ + H5O_native_info_t nat_info; /* Native object info */ + + /* Fill out location struct */ + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; + loc_params.obj_type = H5I_get_type(obj_id); + + /* Get the location object */ + if (NULL == (vol_obj = H5VL_vol_object(obj_id))) + HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, H5_ITER_ERROR, "invalid location identifier") + + /* Set up VOL callback arguments */ + obj_opt_args.get_native_info.fields = nat_fields; + obj_opt_args.get_native_info.ninfo = &nat_info; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_NATIVE_INFO; + vol_cb_args.args = &obj_opt_args; /* Retrieve the object's native information */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &loc_params, &nat_info, nat_fields) < 0) + if (H5VL_object_optional(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native info for object") /* Set the native fields */ @@ -228,11 +236,16 @@ H5O__get_info_old(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, H5O_inf /* Check for retrieving data model information */ dm_fields = fields & (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS); if (dm_fields) { - H5O_info2_t dm_info; /* Data model object info */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5O_info2_t dm_info; /* Data model object info */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_INFO; + vol_cb_args.args.get_info.oinfo = &dm_info; + vol_cb_args.args.get_info.fields = dm_fields; /* Retrieve the object's data model information */ - if (H5VL_object_get(vol_obj, loc_params, H5VL_OBJECT_GET_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &dm_info, dm_fields) < 0) + if (H5VL_object_get(vol_obj, loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get data model info for object") /* Set the data model fields */ @@ -265,11 +278,19 @@ H5O__get_info_old(H5VL_object_t *vol_obj, H5VL_loc_params_t *loc_params, H5O_inf /* Check for retrieving native information */ nat_fields = fields & (H5O_INFO_HDR | H5O_INFO_META_SIZE); if (nat_fields) { - H5O_native_info_t nat_info; /* Native object info */ + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_native_object_optional_args_t obj_opt_args; /* Arguments for optional operation */ + H5O_native_info_t nat_info; /* Native object info */ + + /* Set up VOL callback arguments */ + obj_opt_args.get_native_info.fields = nat_fields; + obj_opt_args.get_native_info.ninfo = &nat_info; + vol_cb_args.op_type = H5VL_NATIVE_OBJECT_GET_NATIVE_INFO; + vol_cb_args.args = &obj_opt_args; /* Retrieve the object's native information */ - if (H5VL_object_optional(vol_obj, H5VL_NATIVE_OBJECT_GET_NATIVE_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, loc_params, &nat_info, nat_fields) < 0) + if (H5VL_object_optional(vol_obj, loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get native info for object") /* Set the native fields */ @@ -751,10 +772,11 @@ done: herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "iIiIoOi*x", obj_id, idx_type, order, op, op_data); @@ -780,10 +802,17 @@ H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1 shim_data.fields = H5O_INFO_ALL; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = H5O__iterate1_adapter; + vol_cb_args.args.visit.op_data = &shim_data; + vol_cb_args.args.visit.fields = H5O_INFO_ALL; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, - (void *)&shim_data, H5O_INFO_ALL)) < 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") done: @@ -826,10 +855,11 @@ herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data, hid_t lapl_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("e", "i*sIiIoOi*xi", loc_id, obj_name, idx_type, order, op, op_data, lapl_id); @@ -865,10 +895,17 @@ H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_it shim_data.fields = H5O_INFO_ALL; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = H5O__iterate1_adapter; + vol_cb_args.args.visit.op_data = &shim_data; + vol_cb_args.args.visit.fields = H5O_INFO_ALL; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, - (void *)&shim_data, H5O_INFO_ALL)) < 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") done: @@ -914,11 +951,12 @@ herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data, unsigned fields) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iIiIoOi*xIu", obj_id, idx_type, order, op, op_data, fields); @@ -954,10 +992,17 @@ H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1 shim_data.fields = fields; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = H5O__iterate1_adapter; + vol_cb_args.args.visit.op_data = &shim_data; + vol_cb_args.args.visit.fields = fields; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, - (void *)&shim_data, fields)) < 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object iteration failed") done: @@ -1003,11 +1048,12 @@ herr_t H5Ovisit_by_name2(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate1_t op, void *op_data, unsigned fields, hid_t lapl_id) { - H5VL_object_t * vol_obj; /* Object of loc_id */ - H5VL_loc_params_t loc_params; - H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ - hbool_t is_native_vol_obj; - herr_t ret_value; /* Return value */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_object_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5O_visit1_adapter_t shim_data; /* Adapter for passing app callback & user data */ + hbool_t is_native_vol_obj; + herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("e", "i*sIiIoOi*xIui", loc_id, obj_name, idx_type, order, op, op_data, fields, lapl_id); @@ -1053,10 +1099,17 @@ H5Ovisit_by_name2(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_it shim_data.fields = fields; shim_data.real_op_data = op_data; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_VISIT; + vol_cb_args.args.visit.idx_type = idx_type; + vol_cb_args.args.visit.order = order; + vol_cb_args.args.visit.op = H5O__iterate1_adapter; + vol_cb_args.args.visit.op_data = &shim_data; + vol_cb_args.args.visit.fields = fields; + /* Visit the objects */ - if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_VISIT, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, (int)idx_type, (int)order, H5O__iterate1_adapter, - (void *)&shim_data, fields)) < 0) + if ((ret_value = H5VL_object_specific(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object iteration failed") done: diff --git a/src/H5Oflush.c b/src/H5Oflush.c index 2e3c1fd..f2eacd6 100644 --- a/src/H5Oflush.c +++ b/src/H5Oflush.c @@ -49,7 +49,7 @@ /* Local Prototypes */ /********************/ static herr_t H5O__oh_tag(const H5O_loc_t *oloc, haddr_t *tag); -static herr_t H5O__refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc); +static herr_t H5O__refresh_metadata_close(H5O_loc_t *oloc, H5G_loc_t *obj_loc, hid_t oid); /*************/ /* Functions */ @@ -194,7 +194,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) +H5O_refresh_metadata(H5O_loc_t *oloc, hid_t oid) { hbool_t objs_incr = FALSE; /* Whether the object count in the file was incremented */ herr_t ret_value = SUCCEED; /* Return value */ @@ -202,7 +202,7 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) FUNC_ENTER_NOAPI(FAIL) /* If the file is opened with write access, no need to perform refresh actions. */ - if (!(H5F_INTENT(oloc.file) & H5F_ACC_RDWR)) { + if (!(H5F_INTENT(oloc->file) & H5F_ACC_RDWR)) { H5G_loc_t obj_loc; H5O_loc_t obj_oloc; H5G_name_t obj_path; @@ -219,7 +219,7 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) /* "Fake" another open object in the file, so that it doesn't get closed * if this object is the only thing holding the file open. */ - H5F_incr_nopen_objs(oloc.file); + H5F_incr_nopen_objs(oloc->file); objs_incr = TRUE; /* Get the VOL object from the ID and cache a pointer to the connector. @@ -252,7 +252,7 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) connector->nrefs++; /* Close object & evict its metadata */ - if ((H5O__refresh_metadata_close(oid, oloc, &obj_loc)) < 0) + if (H5O__refresh_metadata_close(oloc, &obj_loc, oid) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") /* Re-open the object, re-fetching its metadata */ @@ -280,7 +280,7 @@ H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc) done: if (objs_incr) - H5F_decr_nopen_objs(oloc.file); + H5F_decr_nopen_objs(oloc->file); FUNC_LEAVE_NOAPI(ret_value); } /* end H5O_refresh_metadata() */ @@ -305,8 +305,9 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O__refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc) +H5O__refresh_metadata_close(H5O_loc_t *oloc, H5G_loc_t *obj_loc, hid_t oid) { + H5F_t * file; /* Local copy of the object's file pointer */ haddr_t tag = 0; /* Tag for object */ hbool_t corked = FALSE; /* Whether object's metadata is corked */ herr_t ret_value = SUCCEED; /* Return value */ @@ -327,28 +328,32 @@ H5O__refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to prepare refresh for dataset") /* Retrieve tag for object */ - if (H5O__oh_tag(&oloc, &tag) < 0) + if (H5O__oh_tag(oloc, &tag) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to get object header address") /* Get cork status of the object with tag */ - if (H5AC_cork(oloc.file, tag, H5AC__GET_CORKED, &corked) < 0) + if (H5AC_cork(oloc->file, tag, H5AC__GET_CORKED, &corked) < 0) HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, FAIL, "unable to retrieve an object's cork status") + /* Hold a copy of the object's file pointer, since closing the object will + * invalidate the file pointer in the oloc. + */ + file = oloc->file; /* Close the object */ if (H5I_dec_ref(oid) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to close object") /* Flush metadata based on tag value of the object */ - if (H5F_flush_tagged_metadata(oloc.file, tag) < 0) + if (H5F_flush_tagged_metadata(file, tag) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") /* Evict the object's tagged metadata */ - if (H5F_evict_tagged_metadata(oloc.file, tag) < 0) + if (H5F_evict_tagged_metadata(file, tag) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to evict metadata") /* Re-cork object with tag */ if (corked) - if (H5AC_cork(oloc.file, tag, H5AC__SET_CORK, &corked) < 0) + if (H5AC_cork(file, tag, H5AC__SET_CORK, &corked) < 0) HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, FAIL, "unable to cork the object") done: diff --git a/src/H5Ofsinfo.c b/src/H5Ofsinfo.c index 44c4985..b60f589 100644 --- a/src/H5Ofsinfo.c +++ b/src/H5Ofsinfo.c @@ -91,11 +91,12 @@ H5FL_DEFINE_STATIC(H5O_fsinfo_t); */ static void * H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, - unsigned H5_ATTR_UNUSED *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p) + unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) { - H5O_fsinfo_t * fsinfo = NULL; /* File space info message */ - H5F_mem_page_t ptype; /* Memory type for iteration */ - unsigned vers; /* message version */ + H5O_fsinfo_t * fsinfo = NULL; /* File space info message */ + H5F_mem_page_t ptype; /* Memory type for iteration */ + unsigned vers; /* message version */ + const uint8_t *p_end = p + p_size; void * ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC @@ -136,8 +137,12 @@ H5O__fsinfo_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNU fsinfo->threshold = threshold; if (HADDR_UNDEF == (fsinfo->eoa_pre_fsm_fsalloc = H5F_get_eoa(f, H5FD_MEM_DEFAULT))) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to get file size") - for (type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; type++) + for (type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; type++) { + if (p + H5_SIZEOF_HADDR_T > p_end) + HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, + "ran off end of input buffer while decoding") H5F_addr_decode(f, &p, &(fsinfo->fs_addr[type - 1])); + } break; case H5F_FILE_SPACE_ALL: diff --git a/src/H5Omodule.h b/src/H5Omodule.h index 134aa92..8afba29 100644 --- a/src/H5Omodule.h +++ b/src/H5Omodule.h @@ -30,9 +30,46 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5O H5O - * \brief Object Interface * - * \todo Describe concisely what the functions in this module are about. + * Use the functions in this module to manage HDF5 objects. + * + * HDF5 objects (groups, datasets, datatype objects) are usually created + * using functions in the object-specific modules (\ref H5G, \ref H5D, + * \ref H5T). However, new objects can also be created by copying existing + * objects. + * + * Many functions in this module are variations on object introspection, + * that is, the retrieval of detailed information about HDF5 objects in a file. + * Objects in an HDF5 file can be "visited" in an iterative fashion. + * + * HDF5 objects are usually updated using functions in the object-specific + * modules. However, there are certain generic object properties, such as + * reference counts, that can be manipulated using functions in this module. + * + * HDF5 objects are deleted as a side effect of rendering them unreachable + * from the root group. The net effect is the diminution of the object's + * reference count to zero, which can (but should not usually) be effected + * by a function in this module. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5O_examples.c create + * </td> + * <td> + * \snippet{lineno} H5O_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5O_examples.c update + * </td> + * <td> + * \snippet{lineno} H5O_examples.c delete + * </td> + * </tr> + * </table> * */ #endif /* H5Omodule_H */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 6e203bb..331fcf6 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -581,6 +581,11 @@ H5_DLL herr_t H5O__chunk_resize(H5O_t *oh, H5O_chunk_proxy_t *chk_pr H5_DLL herr_t H5O__chunk_delete(H5F_t *f, H5O_t *oh, unsigned idx); H5_DLL herr_t H5O__chunk_dest(H5O_chunk_proxy_t *chunk_proxy); +/* Cache corking functions */ +H5_DLL herr_t H5O__disable_mdc_flushes(H5O_loc_t *oloc); +H5_DLL herr_t H5O__enable_mdc_flushes(H5O_loc_t *oloc); +H5_DLL herr_t H5O__are_mdc_flushes_disabled(const H5O_loc_t *oloc, hbool_t *are_disabled); + /* Collect storage info for btree and heap */ H5_DLL herr_t H5O__attr_bh_info(H5F_t *f, H5O_t *oh, H5_ih_info_t *bh_info); diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index d3b469c..72306df 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -990,13 +990,9 @@ H5_DLL herr_t H5O_msg_get_flags(const H5O_loc_t *loc, unsigned type_id, uint8_t /* Object metadata flush/refresh routines */ H5_DLL herr_t H5O_flush(H5O_loc_t *oloc, hid_t obj_id); H5_DLL herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id); -H5_DLL herr_t H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc); -H5_DLL herr_t H5O_refresh_metadata_reopen(hid_t, H5G_loc_t *, const H5O_refresh_state_t *, H5VL_t *, hbool_t); - -/* Cache corking functions */ -H5_DLL herr_t H5O_disable_mdc_flushes(H5O_loc_t *oloc); -H5_DLL herr_t H5O_enable_mdc_flushes(H5O_loc_t *oloc); -H5_DLL herr_t H5O_are_mdc_flushes_disabled(H5O_loc_t *oloc, hbool_t *are_disabled); +H5_DLL herr_t H5O_refresh_metadata(H5O_loc_t *oloc, hid_t oid); +H5_DLL herr_t H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, const H5O_refresh_state_t *state, + H5VL_t *vol_driver, hbool_t start_swmr); /* Object copying routines */ H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, diff --git a/src/H5Opublic.h b/src/H5Opublic.h index 7bc7784..d9d0500 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -35,14 +35,14 @@ /*****************/ /* Flags for object copy (H5Ocopy) */ -#define H5O_COPY_SHALLOW_HIERARCHY_FLAG (0x0001u) /* Copy only immediate members */ -#define H5O_COPY_EXPAND_SOFT_LINK_FLAG (0x0002u) /* Expand soft links into new objects */ -#define H5O_COPY_EXPAND_EXT_LINK_FLAG (0x0004u) /* Expand external links into new objects */ -#define H5O_COPY_EXPAND_REFERENCE_FLAG (0x0008u) /* Copy objects that are pointed by references */ -#define H5O_COPY_WITHOUT_ATTR_FLAG (0x0010u) /* Copy object without copying attributes */ -#define H5O_COPY_PRESERVE_NULL_FLAG (0x0020u) /* Copy NULL messages (empty space) */ -#define H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG (0x0040u) /* Merge committed datatypes in dest file */ -#define H5O_COPY_ALL (0x007Fu) /* All object copying flags (for internal checking) */ +#define H5O_COPY_SHALLOW_HIERARCHY_FLAG (0x0001u) /**< Copy only immediate members */ +#define H5O_COPY_EXPAND_SOFT_LINK_FLAG (0x0002u) /**< Expand soft links into new objects */ +#define H5O_COPY_EXPAND_EXT_LINK_FLAG (0x0004u) /**< Expand external links into new objects */ +#define H5O_COPY_EXPAND_REFERENCE_FLAG (0x0008u) /**< Copy objects that are pointed by references */ +#define H5O_COPY_WITHOUT_ATTR_FLAG (0x0010u) /**< Copy object without copying attributes */ +#define H5O_COPY_PRESERVE_NULL_FLAG (0x0020u) /**< Copy NULL messages (empty space) */ +#define H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG (0x0040u) /**< Merge committed datatypes in dest file */ +#define H5O_COPY_ALL (0x007Fu) /**< All object copying flags (for internal checking) */ /* Flags for shared message indexes. * Pass these flags in using the mesg_type_flags parameter in @@ -51,25 +51,27 @@ * but we need to assign each kind of message to a different bit so that * one index can hold multiple types.) */ -#define H5O_SHMESG_NONE_FLAG 0x0000 /* No shared messages */ -#define H5O_SHMESG_SDSPACE_FLAG ((unsigned)1 << 0x0001) /* Simple Dataspace Message. */ -#define H5O_SHMESG_DTYPE_FLAG ((unsigned)1 << 0x0003) /* Datatype Message. */ -#define H5O_SHMESG_FILL_FLAG ((unsigned)1 << 0x0005) /* Fill Value Message. */ -#define H5O_SHMESG_PLINE_FLAG ((unsigned)1 << 0x000b) /* Filter pipeline message. */ -#define H5O_SHMESG_ATTR_FLAG ((unsigned)1 << 0x000c) /* Attribute Message. */ +#define H5O_SHMESG_NONE_FLAG 0x0000 /**< No shared messages */ +#define H5O_SHMESG_SDSPACE_FLAG ((unsigned)1 << 0x0001) /**< Simple Dataspace Message. */ +#define H5O_SHMESG_DTYPE_FLAG ((unsigned)1 << 0x0003) /**< Datatype Message. */ +#define H5O_SHMESG_FILL_FLAG ((unsigned)1 << 0x0005) /**< Fill Value Message. */ +#define H5O_SHMESG_PLINE_FLAG ((unsigned)1 << 0x000b) /**< Filter pipeline message. */ +#define H5O_SHMESG_ATTR_FLAG ((unsigned)1 << 0x000c) /**< Attribute Message. */ #define H5O_SHMESG_ALL_FLAG \ (H5O_SHMESG_SDSPACE_FLAG | H5O_SHMESG_DTYPE_FLAG | H5O_SHMESG_FILL_FLAG | H5O_SHMESG_PLINE_FLAG | \ H5O_SHMESG_ATTR_FLAG) +/* clang-format off */ /* Object header status flag definitions */ -#define H5O_HDR_CHUNK0_SIZE 0x03 /* 2-bit field indicating # of bytes to store the size of chunk 0's data */ -#define H5O_HDR_ATTR_CRT_ORDER_TRACKED 0x04 /* Attribute creation order is tracked */ -#define H5O_HDR_ATTR_CRT_ORDER_INDEXED 0x08 /* Attribute creation order has index */ -#define H5O_HDR_ATTR_STORE_PHASE_CHANGE 0x10 /* Non-default attribute storage phase change values stored */ -#define H5O_HDR_STORE_TIMES 0x20 /* Store access, modification, change & birth times for object */ +#define H5O_HDR_CHUNK0_SIZE 0x03 /**< 2-bit field indicating # of bytes to store the size of chunk 0's data */ +#define H5O_HDR_ATTR_CRT_ORDER_TRACKED 0x04 /**< Attribute creation order is tracked */ +#define H5O_HDR_ATTR_CRT_ORDER_INDEXED 0x08 /**< Attribute creation order has index */ +#define H5O_HDR_ATTR_STORE_PHASE_CHANGE 0x10 /**< Non-default attribute storage phase change values stored */ +#define H5O_HDR_STORE_TIMES 0x20 /**< Store access, modification, change & birth times for object */ #define H5O_HDR_ALL_FLAGS \ (H5O_HDR_CHUNK0_SIZE | H5O_HDR_ATTR_CRT_ORDER_TRACKED | H5O_HDR_ATTR_CRT_ORDER_INDEXED | \ H5O_HDR_ATTR_STORE_PHASE_CHANGE | H5O_HDR_STORE_TIMES) +/* clang-format on */ /* Maximum shared message values. Number of indexes is 8 to allow room to add * new types of messages. @@ -81,9 +83,9 @@ * Theses flags determine which fields will be filled in in the H5O_info_t * struct. */ -#define H5O_INFO_BASIC 0x0001u /* Fill in the fileno, addr, type, and rc fields */ -#define H5O_INFO_TIME 0x0002u /* Fill in the atime, mtime, ctime, and btime fields */ -#define H5O_INFO_NUM_ATTRS 0x0004u /* Fill in the num_attrs field */ +#define H5O_INFO_BASIC 0x0001u /**< Fill in the fileno, addr, type, and rc fields */ +#define H5O_INFO_TIME 0x0002u /**< Fill in the atime, mtime, ctime, and btime fields */ +#define H5O_INFO_NUM_ATTRS 0x0004u /**< Fill in the num_attrs field */ #define H5O_INFO_ALL (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS) //! <!-- [H5O_native_info_fields_snip] --> @@ -91,8 +93,8 @@ * Flags for H5Oget_native_info(). Theses flags determine which fields will be * filled in in the \ref H5O_native_info_t struct. */ -#define H5O_NATIVE_INFO_HDR 0x0008u /* Fill in the hdr field */ -#define H5O_NATIVE_INFO_META_SIZE 0x0010u /* Fill in the meta_size field */ +#define H5O_NATIVE_INFO_HDR 0x0008u /**< Fill in the hdr field */ +#define H5O_NATIVE_INFO_META_SIZE 0x0010u /**< Fill in the meta_size field */ #define H5O_NATIVE_INFO_ALL (H5O_NATIVE_INFO_HDR | H5O_NATIVE_INFO_META_SIZE) //! <!-- [H5O_native_info_fields_snip] --> @@ -146,15 +148,15 @@ typedef struct H5O_hdr_info_t { * (For H5Oget_info(), H5Oget_info_by_name(), H5Oget_info_by_idx() version 3) */ typedef struct H5O_info2_t { - unsigned long fileno; /* File number that object is located in */ - H5O_token_t token; /* Token representing the object */ - H5O_type_t type; /* Basic object type (group, dataset, etc.) */ - unsigned rc; /* Reference count of object */ - time_t atime; /* Access time */ - time_t mtime; /* Modification time */ - time_t ctime; /* Change time */ - time_t btime; /* Birth time */ - hsize_t num_attrs; /* # of attributes attached to object */ + unsigned long fileno; /**< File number that object is located in */ + H5O_token_t token; /**< Token representing the object */ + H5O_type_t type; /**< Basic object type (group, dataset, etc.) */ + unsigned rc; /**< Reference count of object */ + time_t atime; /**< Access time */ + time_t mtime; /**< Modification time */ + time_t ctime; /**< Change time */ + time_t btime; /**< Birth time */ + hsize_t num_attrs; /**< Number of attributes attached to object */ } H5O_info2_t; //! <!-- [H5O_info2_t_snip] --> @@ -165,11 +167,10 @@ typedef struct H5O_info2_t { */ typedef struct H5O_native_info_t { H5O_hdr_info_t hdr; /**< Object header information */ - /* Extra metadata storage for obj & attributes */ struct { H5_ih_info_t obj; /**< v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets */ H5_ih_info_t attr; /**< v2 B-tree & heap for attributes */ - } meta_size; + } meta_size; /**< Extra metadata storage for obj & attributes */ } H5O_native_info_t; //! <!-- [H5O_native_info_t_snip] --> @@ -181,6 +182,17 @@ typedef uint32_t H5O_msg_crt_idx_t; //! <!-- [H5O_iterate2_t_snip] --> /** * Prototype for H5Ovisit(), H5Ovisit_by_name() operator (version 3) + * + * \param[in] obj Object that serves as the root of the iteration; + * the same value as the H5Ovisit3() \c obj_id parameter + * \param[in] name Name of object, relative to \p obj, being examined at current + * step of the iteration + * \param[out] info Information about that object + * \param[in,out] op_data User-defined pointer to data required by the application + * in processing the object; a pass-through of the \c op_data + * pointer provided with the H5Ovisit3() function call + * \return \herr_t_iter + * */ typedef herr_t (*H5O_iterate2_t)(hid_t obj, const char *name, const H5O_info2_t *info, void *op_data); //! <!-- [H5O_iterate2_t_snip] --> @@ -460,28 +472,7 @@ H5_DLL htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id); * \return \herr_t * * \details H5Oget_info3() specifies an object by its identifier, \p loc_id , and - * retrieves the metadata describing that object in \p oinfo , an H5O_info2_t \c struct. - * - * The H5O_info2_t \c struct is defined in H5Opublic.h as follows : - * \snippet this H5O_info2_t_snip - * - * Note the following about H5O_info2_t : - * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) - * only \c ctime has been implemented. - * - The \c atime value is the last time the object was read or written. - * - The \c mtime value is the last time the raw data in the object was changed. - * - The \c ctime value is the last time the metadata for the object was changed. - * - The \c btime value is the time the object was created. - * - * The H5O_token_t is defined in H5public.h as follows: - * \snippet H5public.h H5O_token_t_snip - * - * The H5O_type_t \c enum indicates the object type and - * is defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip - * - * Note that the object retrieved as indicated by \p loc_id - * refers only to the types specified by H5O_type_t. + * retrieves the metadata describing that object in \p oinfo. * * The \p fields parameter contains flags to determine which fields will be filled in * the H5O_info2_t \c struct returned in \p oinfo. @@ -530,29 +521,6 @@ H5_DLL herr_t H5Oget_info3(hid_t loc_id, H5O_info2_t *oinfo, unsigned fields); * \p loc_id and \p name, respectively, and retrieves the metadata * describing that object in \p oinfo, an H5O_info2_t struct. * - * \p oinfo, in which the object information is returned, is a \c struct of - * type H5O_info2_t, which is defined in H5Opublic.h in the HDF5 source code: - * - * \snippet this H5O_info2_t_snip - * - * Note the following about H5O_info2_t : - * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) - * only \c ctime has been implemented. - * - The \c atime value is the last time the object was read or written. - * - The \c mtime value is the last time the raw data in the object was changed. - * - The \c ctime value is the last time the metadata for the object was changed. - * - The \c btime value is the time the object was created. - * - * The H5O_token_t is defined in H5public.h as follows: - * \snippet H5public.h H5O_token_t_snip - * - * The H5O_type_t \c enum indicates the object type and - * is defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip - * - * Note that the object retrieved as indicated by \p loc_id - * refers only to the types specified by H5O_type_t. - * * The \p fields parameter contains flags to determine which fields will be filled in * the H5O_info2_t \c struct returned in \p oinfo. * These flags are defined in the H5Opublic.h file: @@ -608,34 +576,6 @@ H5_DLL herr_t H5Oget_info_by_name_async(const char *app_file, const char *app_fu * If \p loc_id fully specifies the group in which the object resides, * \p group_name can be a dot (\c .). * - * \p idx_type is of type #H5_index_t, defined in H5public.h as: - * \snippet H5public.h H5_index_t_snip - * - * \p order is of type #H5_iter_order_t defined in H5public.h as: - * \snippet H5public.h H5_iter_order_t_snip - * - * \p oinfo, in which the object information is returned, is a \c struct of - * type H5O_info2_t, which is defined in H5Opublic.h in the HDF5 source code: - * \snippet this H5O_info2_t_snip - * - * Note the following about H5O_info2_t : - * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) - * only \c ctime has been implemented. - * - The \c atime value is the last time the object was read or written. - * - The \c mtime value is the last time the raw data in the object was changed. - * - The \c ctime value is the last time the metadata for the object was changed. - * - The \c btime value is the time the object was created. - * - * H5O_token_t is defined in H5public.h as follows: - * \snippet H5public.h H5O_token_t_snip - * - * The #H5O_type_t \c enum indicates the object type and - * is defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip - * - * Note that the object retrieved as indicated by \p loc_id - * refers only to the types specified by #H5O_type_t. - * * The \p fields parameter contains flags to determine which fields will be filled in * the H5O_info2_t \c struct returned in \p oinfo. * These flags are defined in the H5Opublic.h file: @@ -668,11 +608,7 @@ H5_DLL herr_t H5Oget_info_by_idx3(hid_t loc_id, const char *group_name, H5_index * \return \herr_t * * \details H5Oget_native_info() retrieves the native file format information for an object - * specified by \p loc_id. The information is retrieved into the - * buffer specified by \p oinfo, which is defined as a \c struct of - * type H5O_native_info_t in H5Opublic.h: - * - * \snippet this H5O_native_info_t_snip + * specified by \p loc_id. * * The \p fields parameter indicates which fields to fill in * H5O_native_info_t. Possible values defined in H5Opublic.h are: @@ -703,12 +639,9 @@ H5_DLL herr_t H5Oget_native_info(hid_t loc_id, H5O_native_info_t *oinfo, unsigne * * \return \herr_t * - * \details H5Oget_native_info_by_name() retrieves the native file format information for an object - * specified by \p loc_id and the name \p name. The information is - * retrieved into the buffer specified by \p oinfo, which is defined - * as a \c struct of type H5O_native_info_t in H5Opublic.h: - * - * \snippet this H5O_native_info_t_snip + * \details H5Oget_native_info_by_name() retrieves the native file format + * information for an object specified by \p loc_id and the name \p + * name. * * The \p fields parameter which fields to fill in H5O_native_info_t. * Possible values defined in H5Opublic.h are: @@ -747,16 +680,7 @@ H5_DLL herr_t H5Oget_native_info_by_name(hid_t loc_id, const char *name, H5O_nat * specified by \p loc_id, group name, \p group_name, the index by which * objects in the group are tracked, \p idx_type, the order by which * the index is to be traversed, \p order , and an object's position - * \p n within that index. The information is retrieved into the - * buffer specified by \p oinfo, which is defined as a \c struct of - * type H5O_native_info_t in H5Opublic.h: - * \snippet this H5O_native_info_t_snip - * - * \p idx_type is of type #H5_index_t, defined in H5public.h as: - * \snippet H5public.h H5_index_t_snip - * - * \p order is of type #H5_iter_order_t defined in H5public.h as: - * \snippet H5public.h H5_iter_order_t_snip + * \p n within that index. * * The \p fields parameter indicates which fields to fill in H5O_native_info_t. * Possible values defined in H5Opublic.h are: @@ -1236,11 +1160,8 @@ H5_DLL ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comm * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes - * + * unnecessary, so the iteration may begin more quickly. + * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in * a value indicating iteration in creation order and a group is @@ -1250,62 +1171,7 @@ H5_DLL ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comm * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders - * - * The prototype of the callback function op is as follows (as - * defined in the source code file H5Opublic.h): - * - * \snippet this H5O_iterate2_t_snip - * - * The parameters of this callback function have the following values - * or meanings: - * <table> - * <tr> - * <td>\c obj</td> - * <td>Object that serves as root of the iteration; - * same value as the H5Ovisit() \p obj_id parameter</td> - * </tr> - * <tr> - * <td>\c name</td> - * <td>Name of object, relative to \c obj, being examined at - * current step of the iteration</td> - * </tr> - * <tr> - * <td>\c info</td> - * <td>H5O_info2_t \c struct containing information - * regarding that object</td> - * </tr> - * <tr> - * <td>\c op_data</td> - * <td>User-defined pointer to data required by the application in - * processing the object; a pass-through of the \c op_data pointer - * provided with the H5Ovisit() function call</td> - * </tr> - * </table> - * - * The H5O_info2_t \c struct is defined in H5Opublic.h as follows: - * \snippet this H5O_info2_t_snip - * - * H5O_token_t is defined in H5public.h as follows: - * \snippet H5public.h H5O_token_t_snip - * - * The #H5O_type_t enum indicates the object type and is - * defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip - * - * Note that the object retrieved as indicated by \p obj_id - * refers only to the types specified by #H5O_type_t. - * - * The return values from an operator are: - * - Zero causes the visit iterator to continue, returning zero when all - * group members have been processed. - * - A positive value causes the visit iterator to immediately return that - * positive value, indicating short-circuit success. - * - A negative value causes the visit iterator to immediately return that - * value, indicating failure. + * along the index specified in \p idx_type. * * The H5Ovisit3() \p op_data parameter is a user-defined pointer to the data * required to process objects in the course of the iteration. This pointer @@ -1329,24 +1195,6 @@ H5_DLL ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comm * group change during the iteration, the resulting behavior * is undefined. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. - * * \par Example * An example snippet from test/links.c: * \snippet links.c H5Ovisit3_snip @@ -1411,10 +1259,7 @@ H5_DLL herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes + * unnecessary, so the iteration may begin more quickly. * * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in a @@ -1425,49 +1270,7 @@ H5_DLL herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders - * - * The prototype of the callback function op is as follows (as - * defined in the source code file H5Opublic.h): - * - * \snippet this H5O_iterate2_t_snip - * - * The parameters of this callback function have the following - * values or meanings: - * <table> - * <tr> - * <td>\c obj</td> - * <td>Object that serves as root of the iteration</td> - * </tr> - * <tr> - * <td>\c name</td> - * <td>Name of object, relative to \c obj, being examined at - * current step of the iteration</td> - * </tr> - * <tr> - * <td>\c info</td> - * <td>H5O_info2_t \c struct containing information - * regarding that object</td> - * </tr> - * <tr> - * <td>\c op_data</td> - * <td>User-defined pointer to data required by the application in - * processing the object</td> - * </tr> - * </table> - * - * The H5O_info2_t \c struct is defined in H5Opublic.h as follows: - * \snippet this H5O_info2_t_snip - * - * H5O_token_t is defined in H5public.h as follows: - * \snippet H5public.h H5O_token_t_snip - * - * The #H5O_type_t enum indicates the object type and is - * defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip + * along the index specified in \p idx_type. * * The H5Ovisit_by_name3() \p op_data parameter is a user-defined * pointer to the data required to process objects in the course @@ -1495,24 +1298,6 @@ H5_DLL herr_t H5Ovisit3(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * in the file has been presented to the application for whatever * processing the application requires. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. - * * \par Example * An example snippet from test/links.c: * \snippet links.c H5Ovisit_by_name3_snip @@ -1579,26 +1364,11 @@ H5_DLL herr_t H5Oclose_async(const char *app_file, const char *app_func, unsigne * files. After that, the OS is responsible for ensuring that * the data is actually flushed to disk. * - * \par See Also: - * - H5Dflush() - * - H5Drefresh() - * - H5Oflush() - * - H5Grefresh() - * - H5Oflush() - * - H5Orefresh() - * - H5Tflush() - * - H5Trefresh() - * \par - * - \c H5DOappend() - * - H5Fstart_swmr_write() - * - H5Pget_append_flush() - * - H5Pget_object_flush_cb() - * - H5Pset_append_flush() - * - H5Pset_object_flush_cb() - * \par - * - H5Oare_mdc_flushes_disabled() - * - H5Odisable_mdc_flushes() - * - H5Oenable_mdc_flushes() + * \see H5Dflush(), H5Drefresh(), H5Oflush(), H5Grefresh(), H5Oflush(), + * H5Orefresh(), H5Tflush(), H5Trefresh() + * \see H5DOappend(), H5Fstart_swmr_write(), H5Pget_append_flush(), + * H5Pget_object_flush_cb(), H5Pset_append_flush(), H5Pset_object_flush_cb() + * \see H5Oare_mdc_flushes_disabled(), H5Odisable_mdc_flushes(), H5Oenable_mdc_flushes() * * \since 1.10.0 * @@ -1670,21 +1440,17 @@ H5_DLL herr_t H5Orefresh_async(const char *app_file, const char *app_func, unsig * HDF5 object level (datasets, groups, committed datatypes) * and the entire metadata cache level. * - * \note HDF5 objects include datasets, groups, and committed datatypes. - * Only #hid_t identifiers that represent these objects can be passed to the function. - * \note Passing in a #hid_t identifier that represents any other HDF5 entity is - * considered an error. - * \note It is an error to pass an HDF5 file identifier - * (obtained from H5Fopen() or H5Fcreate()) - * to this function. - * \note Misuse of this function can cause the cache to exhaust - * available memory. - * \note Objects can be returned to the default automatic flush behavior - * with H5Oenable_mdc_flushes(). - * \note Flush prevention only pertains to new or dirty metadata entries. - * Clean entries can be evicted from the cache. - * \note Calling this function on an object that has already had flushes - * disabled will return an error. + * \note HDF5 objects include datasets, groups, and committed datatypes. Only + * #hid_t identifiers that represent these objects can be passed to the + * function. Passing in a #hid_t identifier that represents any other + * HDF5 entity is considered an error. It is an error to pass an HDF5 + * file identifier (obtained from H5Fopen() or H5Fcreate()) to this + * function. Misuse of this function can cause the cache to exhaust + * available memory. Objects can be returned to the default automatic + * flush behavior with H5Oenable_mdc_flushes(). Flush prevention only + * pertains to new or dirty metadata entries. Clean entries can be + * evicted from the cache. Calling this function on an object that has + * already had flushes disabled will return an error. * * \since 1.10.0 * @@ -1714,28 +1480,18 @@ H5_DLL herr_t H5Odisable_mdc_flushes(hid_t object_id); * metadata cache level. * * - * \note HDF5 objects include datasets, groups, and committed datatypes. - * Only #hid_t identifiers that represent these objects can be - * passed to the function. - * - * \note Passing in a #hid_t identifier that represents any other HDF5 entity - * is considered an error. - * - * \note It is an error to pass an HDF5 file identifier - * (obtained from H5Fopen() or H5Fcreate()) - * to this function. - * - * \note Using this function on an object that has not had flushes disabled - * is considered an error. The state of an object can be determined - * with H5Oare_mdc_flushes_disabled(). - * - * \note An object will be returned to the default flush algorithm when it is closed. - * - * \note All objects will be returned to the default flush algorithm when - * the file is closed. - * - * \note An object’s entries will not necessarily be flushed as a result of - * calling this function. + * \note HDF5 objects include datasets, groups, and committed datatypes. Only + * #hid_t identifiers that represent these objects can be passed to the + * function. Passing in a #hid_t identifier that represents any other + * HDF5 entity is considered an error. It is an error to pass an HDF5 + * file identifier (obtained from H5Fopen() or H5Fcreate()) to this + * function. Using this function on an object that has not had flushes + * disabled is considered an error. The state of an object can be + * determined with H5Oare_mdc_flushes_disabled(). An object will be + * returned to the default flush algorithm when it is closed. All objects + * will be returned to the default flush algorithm when the file is + * closed. An object’s entries will not necessarily be flushed as a + * result of calling this function. * * \since 1.10.0 * @@ -1871,6 +1627,7 @@ H5_DLL herr_t H5Otoken_to_str(hid_t loc_id, const H5O_token_t *token, char **tok */ H5_DLL herr_t H5Otoken_from_str(hid_t loc_id, const char *token_str, H5O_token_t *token); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -1894,6 +1651,7 @@ H5_DLL herr_t H5Otoken_from_str(hid_t loc_id, const char *token_str, H5O_token_t #define H5Orefresh_async_wrap H5_NO_EXPAND(H5Orefresh_async) #define H5Ocopy_async_wrap H5_NO_EXPAND(H5Ocopy_async) #endif +/// \endcond /* The canonical 'undefined' token value */ #define H5O_TOKEN_UNDEF (H5OPEN H5O_TOKEN_UNDEF_g) @@ -1908,8 +1666,8 @@ H5_DLLVAR const H5O_token_t H5O_TOKEN_UNDEF_g; /* Macros */ /* Deprecated flags for earlier versions of H5Oget_info* */ -#define H5O_INFO_HDR 0x0008u /* Fill in the hdr field */ -#define H5O_INFO_META_SIZE 0x0010u /* Fill in the meta_size field */ +#define H5O_INFO_HDR 0x0008u /**< Fill in the hdr field */ +#define H5O_INFO_META_SIZE 0x0010u /**< Fill in the meta_size field */ #undef H5O_INFO_ALL #define H5O_INFO_ALL (H5O_INFO_BASIC | H5O_INFO_TIME | H5O_INFO_NUM_ATTRS | H5O_INFO_HDR | H5O_INFO_META_SIZE) @@ -1942,7 +1700,7 @@ typedef struct H5O_info1_t { time_t mtime; /**< Modification time */ time_t ctime; /**< Change time */ time_t btime; /**< Birth time */ - hsize_t num_attrs; /**< # of attributes attached to object */ + hsize_t num_attrs; /**< Number of attributes attached to object */ H5O_hdr_info_t hdr; /**< Object header information */ /* Extra metadata storage for obj & attributes */ struct { @@ -1955,6 +1713,16 @@ typedef struct H5O_info1_t { //! <!-- [H5O_iterate1_t_snip] --> /** * Prototype for H5Ovisit(), H5Ovisit_by_name() operator (versions 1 & 2) + * + * \param[in] obj Object that serves as the root of the iteration; + * the same value as the H5Ovisit1() \c obj_id parameter + * \param[in] name Name of object, relative to \p obj, being examined at current + * step of the iteration + * \param[out] info Information about that object + * \param[in,out] op_data User-defined pointer to data required by the application + * in processing the object + * \return \herr_t_iter + * */ typedef herr_t (*H5O_iterate1_t)(hid_t obj, const char *name, const H5O_info1_t *info, void *op_data); //! <!-- [H5O_iterate1_t_snip] --> @@ -2027,36 +1795,7 @@ H5_DLL hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr); * the function H5Oget_info3() or the macro #H5Oget_info. * * \details H5Oget_info1() specifies an object by its identifier, \p loc_id , and - * retrieves the metadata describing that object in \p oinfo , - * defined as a \c struct of type H5O_info1_t : - * - * \snippet this H5O_info1_t_snip - * - * Note the following about H5O_info1_t : - * - Of the four time fields (\c atime, \c mtime, \c ctime, and \c btime) - * only \c ctime has been implemented. - * - The \c atime value is the last time the object was read or written. - * - The \c mtime value is the last time the raw data in the object was changed. - * - The \c ctime value is the last time the metadata for the object was changed. - * - The \c btime value is the time the object was created. - * - The fields nested in the \c meta_size field are for internal library use only. - * - * The #H5O_type_t \c enum indicates the object type and - * is defined in H5Opublic.h as follows: - * \snippet this H5O_type_t_snip - * - * Note that the object retrieved as indicated by \p loc_id - * refers only to the types specified by #H5O_type_t. - * - * An H5O_hdr_info_t \c struct holds object header metadata and is - * defined in H5Opublic.h as follows: - * \snippet this H5O_hdr_info_t_snip - * - * Valid values for the \c version field are \c H5O_VERSION_1 and \c H5O_VERSION_2. - * Version 2 of the object header is smaller and more efficient than version 1. - * - * Please be aware that the information held by H5O_hdr_info_t may only be useful to - * developers with extensive HDF5 experience. + * retrieves the metadata describing that object in \p oinfo. * * \note If you are iterating through a lot of different objects to * retrieve information via the H5Oget_info() family of routines, @@ -2156,16 +1895,6 @@ H5_DLL herr_t H5Oget_info_by_name1(hid_t loc_id, const char *name, H5O_info1_t * * If \p loc_id fully specifies the group in which the object resides, * \p group_name can be a dot (\c .). * - * \p idx_type is of type #H5_index_t, defined in H5public.h as: - * \snippet H5public.h H5_index_t_snip - * - * \p order is of type #H5_iter_order_t defined in H5public.h as: - * \snippet H5public.h H5_iter_order_t_snip - * - * \p oinfo, in which the object information is returned, is a \c struct of - * type H5O_info1_t . - * \snippet this H5O_info1_t_snip - * * The link access property list, \c lapl_id, is not currently used; * it should be passed in as #H5P_DEFAULT. * @@ -2361,10 +2090,7 @@ H5_DLL herr_t H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes + * unnecessary, so the iteration may begin more quickly. * * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in @@ -2375,56 +2101,7 @@ H5_DLL herr_t H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders - * - * The prototype of the callback function op is as follows (as - * defined in the source code file H5Opublic.h): - * - * \snippet this H5O_iterate1_t_snip - * - * The parameters of this callback function have the following values - * or meanings: - * <table> - * <tr> - * <td>\c obj</td> - * <td>Object that serves as root of the iteration; - * same value as the H5Ovisit1() \p obj_id parameter</td> - * </tr> - * <tr> - * <td>\c name</td> - * <td>Name of object, relative to \c obj, being examined at - * current step of the iteration</td> - * </tr> - * <tr> - * <td>\c info</td> - * <td>H5O_info1_t \c struct containing information - * regarding that object</td> - * </tr> - * <tr> - * <td>\c op_data</td> - * <td>User-defined pointer to data required by the application in - * processing the object</td> - * </tr> - * </table> - * - * The H5O_info1_t \c struct is defined in H5Opublic.h: - * \snippet this H5O_info1_t_snip - * - * The return values from an operator are: - * - Zero causes the visit iterator to continue, returning zero when all - * group members have been processed. - * - A positive value causes the visit iterator to immediately return that - * positive value, indicating short-circuit success. - * - A negative value causes the visit iterator to immediately return that - * value, indicating failure. - * - * The H5Ovisit1() \p op_data parameter is a user-defined pointer to the data - * required to process objects in the course of the iteration. This pointer - * is passed back to each step of the iteration in the callback - * function’s \p op_data parameter. + * along the index specified in \p idx_type. * * H5Lvisit1() and H5Ovisit1() are companion functions: one for * examining and operating on links; the other for examining @@ -2438,24 +2115,6 @@ H5_DLL herr_t H5Oget_info_by_idx2(hid_t loc_id, const char *group_name, H5_index * group change during the iteration, the resulting behavior * is undefined. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. - * * \version 1.10.5 The macro #H5Ovisit was removed and the function * H5Ovisit1() was copied to H5Ovisit(). * \version 1.10.3 Function H5Ovisit() was copied to H5Ovisit1(), @@ -2523,10 +2182,7 @@ H5_DLL herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes + * unnecessary, so the iteration may begin more quickly. * * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in a @@ -2537,10 +2193,7 @@ H5_DLL herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders + * along the index specified in \p idx_type. * * The \p op callback function and the effect of the callback * function’s return value on the application are described @@ -2570,24 +2223,6 @@ H5_DLL herr_t H5Ovisit1(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * in the file has been presented to the application for whatever * processing the application requires. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. - * * \version 1.10.5 The macro #H5Ovisit_by_name was removed and the function * H5Ovisit_by_name1() was copied to #H5Ovisit_by_name. * \version 1.10.3 The H5Ovisit_by_name() function was renamed to H5Ovisit_by_name1(), @@ -2650,10 +2285,7 @@ H5_DLL herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t i * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes + * unnecessary, so the iteration may begin more quickly. * * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in @@ -2664,57 +2296,7 @@ H5_DLL herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t i * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders - * - * The prototype of the callback function op is as follows (as - * defined in the source code file H5Opublic.h): - * - * \snippet this H5O_iterate1_t_snip - * - * The parameters of this callback function have the following values - * or meanings: - * <table> - * <tr> - * <td>\c obj</td> - * <td>Object that serves as root of the iteration; - * same value as the H5Ovisit1() \p obj_id parameter</td> - * </tr> - * <tr> - * <td>\c name</td> - * <td>Name of object, relative to \c obj, being examined at - * current step of the iteration</td> - * </tr> - * <tr> - * <td>\c info</td> - * <td>H5O_info1_t \c struct containing information - * regarding that object</td> - * </tr> - * <tr> - * <td>\c op_data</td> - * <td>User-defined pointer to data required by the application in - * processing the object; a pass-through of the \c op_data pointer - * provided with the H5Ovisit() function call</td> - * </tr> - * </table> - * - * The H5O_info1_t \c struct is defined in H5Opublic.h and - * described in the H5Oget_info1() function entry. - * - * The return values from an operator are: - * - Zero causes the visit iterator to continue, returning zero when all - * group members have been processed. - * - A positive value causes the visit iterator to immediately return that - * positive value, indicating short-circuit success. - * - A negative value causes the visit iterator to immediately return that - * value, indicating failure. - * - * The H5Ovisit2() \p op_data parameter is a user-defined pointer to the data - * required to process objects in the course of the iteration. This pointer - * is passed back to each step of the iteration in the callback - * function’s \p op_data parameter. + * along the index specified in \p idx_type. * * The \p fields parameter contains flags to determine which fields will * be retrieved by the \p op callback function. These flags are defined @@ -2733,23 +2315,6 @@ H5_DLL herr_t H5Ovisit_by_name1(hid_t loc_id, const char *obj_name, H5_index_t i * group change during the iteration, the resulting behavior * is undefined. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. * * \since 1.10.3 * @@ -2814,10 +2379,7 @@ H5_DLL herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * a group have not been indexed by the index type, they will * first be sorted by that index then the iteration will begin; * if the links have been so indexed, the sorting step will be - * unnecessary, so the iteration may begin more quickly. Valid - * values include the following: - * - * \indexes + * unnecessary, so the iteration may begin more quickly. * * Note that the index type passed in \p idx_type is a * <em>best effort</em> setting. If the application passes in a @@ -2828,10 +2390,7 @@ H5_DLL herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * used by the HDF5 library and is always available.) * * \p order specifies the order in which objects are to be inspected - * along the index specified in \p idx_type. Valid values include - * the following: - * - * \orders + * along the index specified in \p idx_type. * * The \p op callback function and the effect of the callback * function’s return value on the application are described @@ -2866,24 +2425,6 @@ H5_DLL herr_t H5Ovisit2(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order * in the file has been presented to the application for whatever * processing the application requires. * - * \note \Bold{Programming Note for C++ Developers Using C Functions:} - * \note If a C routine that takes a function pointer as an argument is - * called from within C++ code, the C routine should be returned - * from normally. - * - * \note Examples of this kind of routine include callbacks such as - * H5Pset_elink_cb() and H5Pset_type_conv_cb() and - * functions such as H5Tconvert() and H5Ewalk2(). - * - * \note Exiting the routine in its normal fashion allows the HDF5 - * C library to clean up its work properly. In other words, if - * the C++ application jumps out of the routine back to the C++ - * “catch” statement, the library is not given the opportunity - * to close any temporary data structures that were set up when - * the routine was called. The C++ application should save some - * state as the routine is started so that any problem that occurs - * might be diagnosed. - * * \since 1.10.3 * */ diff --git a/src/H5PL.c b/src/H5PL.c index 06443f3..30b6c52 100644 --- a/src/H5PL.c +++ b/src/H5PL.c @@ -359,7 +359,7 @@ H5PLget(unsigned int idx, char *path_buf, size_t buf_size) /* 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)); + HDstrncpy(path_buf, path, buf_size); if ((size_t)path_len >= buf_size) path_buf[buf_size - 1] = '\0'; } /* end if */ diff --git a/src/H5PLint.c b/src/H5PLint.c index cf6135d..d20401e 100644 --- a/src/H5PLint.c +++ b/src/H5PLint.c @@ -236,11 +236,13 @@ H5PL_load(H5PL_type_t type, const H5PL_key_t *key) if ((H5PL_plugin_control_mask_g & H5PL_FILTER_PLUGIN) == 0) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "filter plugins disabled") break; + case H5PL_TYPE_VOL: if ((H5PL_plugin_control_mask_g & H5PL_VOL_PLUGIN) == 0) HGOTO_ERROR(H5E_PLUGIN, H5E_CANTLOAD, NULL, "Virtual Object Layer (VOL) driver plugins disabled") break; + case H5PL_TYPE_ERROR: case H5PL_TYPE_NONE: default: @@ -290,7 +292,7 @@ done: * get_plugin_info function pointer, but early (4.4.7, at least) gcc * only allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("pedantic") +H5_GCC_CLANG_DIAG_OFF("pedantic") herr_t H5PL__open(const char *path, H5PL_type_t type, const H5PL_key_t *key, hbool_t *success, H5PL_type_t *plugin_type, const void **plugin_info) @@ -412,7 +414,7 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5PL__open() */ -H5_GCC_DIAG_ON("pedantic") +H5_GCC_CLANG_DIAG_ON("pedantic") /*------------------------------------------------------------------------- * Function: H5PL__close diff --git a/src/H5PLmodule.h b/src/H5PLmodule.h index ab9f1d5..a093096 100644 --- a/src/H5PLmodule.h +++ b/src/H5PLmodule.h @@ -28,8 +28,34 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5PL H5PL - * \brief Plugins - * \todo Describe what programmatically controlling dynamically loaded plugins (H5PL) is all about + * + * Use the functions in this module to manage the loading behavior of HDF5 + * plugins. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet H5PL_examples.c create + * </td> + * <td> + * \snippet H5PL_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet H5PL_examples.c update + * </td> + * <td> + * \snippet H5PL_examples.c delete + * </td> + * </tr> + * </table> + * + * \attention The loading behavior of HDF5 plugins can be controlled via the + * functions described below and certain environment variables, such + * as \c HDF5_PLUGIN_PRELOAD and \c HDF5_PLUGIN_PATH. + * */ #endif /* H5PLmodule_H */ diff --git a/src/H5PLplugin_cache.c b/src/H5PLplugin_cache.c index 2ec0845..b7cdac0 100644 --- a/src/H5PLplugin_cache.c +++ b/src/H5PLplugin_cache.c @@ -242,7 +242,7 @@ done: /* See the other use of H5PL_GET_LIB_FUNC() for an explanation * for why we disable -Wpedantic here. */ -H5_GCC_DIAG_OFF("pedantic") +H5_GCC_CLANG_DIAG_OFF("pedantic") herr_t H5PL__find_plugin_in_cache(const H5PL_search_params_t *search_params, hbool_t *found, const void **plugin_info) @@ -263,35 +263,61 @@ H5PL__find_plugin_in_cache(const H5PL_search_params_t *search_params, hbool_t *f /* Loop over all the plugins, looking for one that matches */ for (u = 0; u < H5PL_num_plugins_g; u++) { - - /* If the plugin type (filter, VOL connector, etc.) and ID match, query the plugin for its info */ - if ((search_params->type == (H5PL_cache_g[u]).type) && - (search_params->key->id == (H5PL_cache_g[u]).key.id)) { - - H5PL_get_plugin_info_t get_plugin_info_function; - const void * 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_PLUGIN, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info") - - /* Call the "get plugin info" function */ - if (NULL == (info = (*get_plugin_info_function)())) - HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info") - - /* Set output parameters */ - *found = TRUE; - *plugin_info = info; - - /* No need to continue processing */ - break; - - } /* end if */ - - } /* end for */ + /* If the plugin type (filter, VOL connector, etc.) match, proceed */ + if (search_params->type == H5PL_cache_g[u].type) { + hbool_t matched = FALSE; /* Whether cached plugin info matches */ + + switch (search_params->type) { + case H5PL_TYPE_FILTER: + if (search_params->key->id == H5PL_cache_g[u].key.id) + matched = TRUE; + break; + + case H5PL_TYPE_VOL: + if (search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_VALUE) { + if (search_params->key->vol.u.value == H5PL_cache_g[u].key.vol.u.value) + matched = TRUE; + } /* end if */ + else if (search_params->key->vol.kind == H5VL_GET_CONNECTOR_BY_NAME) { + if (0 == HDstrcmp(search_params->key->vol.u.name, H5PL_cache_g[u].key.vol.u.name)) + matched = TRUE; + } /* end else-if */ + else + HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, FAIL, "bad VOL plugin search key type") + break; + + case H5PL_TYPE_ERROR: + case H5PL_TYPE_NONE: + default: + HGOTO_ERROR(H5E_PLUGIN, H5E_BADVALUE, FAIL, "bad plugin type") + } /* end switch */ + + /* If the plugin type (filter, VOL connector, etc.) and key match, query the plugin for its info + */ + if (matched) { + H5PL_get_plugin_info_t get_plugin_info_function; + const void * 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_PLUGIN, H5E_CANTGET, FAIL, "can't get function for H5PLget_plugin_info") + + /* Call the "get plugin info" function */ + if (NULL == (info = (*get_plugin_info_function)())) + HGOTO_ERROR(H5E_PLUGIN, H5E_CANTGET, FAIL, "can't get plugin info") + + /* Set output parameters */ + *found = TRUE; + *plugin_info = info; + + /* No need to continue processing */ + break; + } /* end if */ + } /* end if */ + } /* end for */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5PL__find_plugin_in_cache() */ -H5_GCC_DIAG_ON("pedantic") +H5_GCC_CLANG_DIAG_ON("pedantic") diff --git a/src/H5Pdapl.c b/src/H5Pdapl.c index 2ebdbe3..d374b25 100644 --- a/src/H5Pdapl.c +++ b/src/H5Pdapl.c @@ -1453,7 +1453,7 @@ H5Pget_efile_prefix(hid_t plist_id, char *prefix /*out*/, size_t size) /* Copy to user's buffer, if given */ len = HDstrlen(my_prefix); if (prefix) { - HDstrncpy(prefix, my_prefix, MIN(len + 1, size)); + HDstrncpy(prefix, my_prefix, size); if (len >= size) prefix[size - 1] = '\0'; } /* end if */ @@ -1543,7 +1543,7 @@ H5Pget_virtual_prefix(hid_t plist_id, char *prefix /*out*/, size_t size) /* Copy to user's buffer, if given */ len = HDstrlen(my_prefix); if (prefix) { - HDstrncpy(prefix, my_prefix, MIN(len + 1, size)); + HDstrncpy(prefix, my_prefix, size); if (len >= size) prefix[size - 1] = '\0'; } /* end if */ diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c index 046b046..46dc94c 100644 --- a/src/H5Pdxpl.c +++ b/src/H5Pdxpl.c @@ -68,7 +68,7 @@ #define H5D_XFER_BTREE_SPLIT_RATIO_SIZE sizeof(double[3]) #define H5D_XFER_BTREE_SPLIT_RATIO_DEF \ { \ - 0.1f, 0.5f, 0.9f \ + 0.1, 0.5, 0.9 \ } #define H5D_XFER_BTREE_SPLIT_RATIO_ENC H5P__dxfr_btree_split_ratio_enc #define H5D_XFER_BTREE_SPLIT_RATIO_DEC H5P__dxfr_btree_split_ratio_dec @@ -1052,7 +1052,7 @@ H5Pget_data_transform(hid_t plist_id, char *expression /*out*/, size_t size) /* Copy into application buffer */ len = HDstrlen(pexp); if (expression) { - HDstrncpy(expression, pexp, MIN(len + 1, size)); + HDstrncpy(expression, pexp, size); if (len >= size) expression[size - 1] = '\0'; } /* end if */ @@ -2281,7 +2281,7 @@ herr_t H5Pset_dataset_io_hyperslab_selection(hid_t plist_id, unsigned rank, H5S_seloper_t op, const hsize_t start[], const hsize_t stride[], const hsize_t count[], const hsize_t block[]) { - H5P_genplist_t *plist; /* Property list pointer */ + H5P_genplist_t *plist = NULL; /* Property list pointer */ H5S_t * space; /* Dataspace to hold selection */ hbool_t space_created = FALSE; /* Whether a new dataspace has been created */ hbool_t reset_prop_on_error = FALSE; /* Whether to reset the property on failure */ @@ -2371,7 +2371,7 @@ H5Pset_dataset_io_hyperslab_selection(hid_t plist_id, unsigned rank, H5S_seloper done: /* Cleanup on failure */ if (ret_value < 0) { - if (reset_prop_on_error && H5P_poke(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0) + if (reset_prop_on_error && plist && H5P_poke(plist, H5D_XFER_DSET_IO_SEL_NAME, &space) < 0) HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "error setting dataset I/O selection") if (space_created && H5S_close(space) < 0) HDONE_ERROR(H5E_PLIST, H5E_CLOSEERROR, FAIL, "unable to release dataspace") diff --git a/src/H5Pencdec.c b/src/H5Pencdec.c index 5b0ecb6..e2a97f8 100644 --- a/src/H5Pencdec.c +++ b/src/H5Pencdec.c @@ -333,7 +333,7 @@ H5P__encode_cb(H5P_genprop_t *prop, void *_udata) /* Encode (or not, if the 'encode' flag is off) the property's name */ prop_name_len = HDstrlen(prop->name) + 1; if (udata->encode) { - HDstrncpy((char *)*(udata->pp), prop->name, prop_name_len); + HDstrcpy((char *)*(udata->pp), prop->name); *(uint8_t **)(udata->pp) += prop_name_len; } /* end if */ *(udata->enc_size_ptr) += prop_name_len; diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 5332ea6..d20503f 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -5930,6 +5930,64 @@ done: } /* end H5Pget_vol_info() */ /*------------------------------------------------------------------------- + * Function: H5Pget_vol_cap_flags + * + * Purpose: Queries the current VOL connector information for a FAPL to + * retrieve the capability flags for the VOL connector stack, as will + * be used by a file open or create operation that uses this FAPL. + * + * Current capability flags are: + * H5VL_CAP_FLAG_THREADSAFE - Connector is threadsafe + * H5VL_CAP_FLAG_ASYNC - Connector performs operations asynchronously + * H5VL_CAP_FLAG_NATIVE_FILES - Connector produces native file format + * + * Note: This routine supports the use of the HDF5_VOL_CONNECTOR environment + * environment variable to override the VOL connector set programmatically + * for the FAPL (with H5Pset_vol). + * + * Note: The H5VL_CAP_FLAG_ASYNC flag can be checked to see if asynchronous + * operations are supported by the VOL connector stack. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_vol_cap_flags(hid_t plist_id, unsigned *cap_flags) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*Iu", plist_id, cap_flags); + + /* Get the 'cap_flags' from the connector */ + if (cap_flags) { + if (TRUE == H5P_isa_class(plist_id, H5P_FILE_ACCESS)) { + H5P_genplist_t * plist; /* Property list pointer */ + H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ + + /* Get property list for ID */ + if (NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* Get the connector property */ + if (H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get VOL connector property") + + /* Query the capability flags */ + if (H5VL_get_cap_flags(&connector_prop, cap_flags) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get VOL connector capability flags") + } /* end if */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + } /* end if */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_vol_cap_flags() */ + +/*------------------------------------------------------------------------- * Function: H5P__facc_vol_create * connectorose: Create callback for the VOL connector ID & info property. diff --git a/src/H5Pint.c b/src/H5Pint.c index b27a440..90fd1c2 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -4879,7 +4879,8 @@ H5P__copy_prop_plist(hid_t dst_id, hid_t src_id, const char *name) /* If not, get the information required to do an H5Pinsert2 with the property into the destination list */ else { /* Get the pointer to the source property */ - prop = H5P__find_prop_plist(src_plist, name); + if (NULL == (prop = H5P__find_prop_plist(src_plist, name))) + HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist") /* Create property object from parameters */ if (NULL == diff --git a/src/H5Plapl.c b/src/H5Plapl.c index 879e6ed..d00efaf 100644 --- a/src/H5Plapl.c +++ b/src/H5Plapl.c @@ -1044,7 +1044,7 @@ H5Pget_elink_prefix(hid_t plist_id, char *prefix /*out*/, size_t size) /* Copy to user's buffer, if given */ len = HDstrlen(my_prefix); if (prefix) { - HDstrncpy(prefix, my_prefix, MIN(len + 1, size)); + HDstrncpy(prefix, my_prefix, size); if (len >= size) prefix[size - 1] = '\0'; } /* end if */ diff --git a/src/H5Pmodule.h b/src/H5Pmodule.h index 18f30c6..6e92e66 100644 --- a/src/H5Pmodule.h +++ b/src/H5Pmodule.h @@ -30,49 +30,165 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5P H5P - * \brief Property List Interface * - * \details The HDF5 Property List Interface provides a mechanism to take - * advantage of more powerful or unusual features in HDF5. + * Use the functions in this module to manage HDF5 property lists and property + * list classes. HDF5 property lists are the main vehicle to configure the + * behavior of HDF5 API functions. * - * HDF5 objects have properties or characteristics associated with - * them, and there are default properties that handle the most - * common needs. These default properties can be modified using the - * HDF5 Property List Interface. For example, the data storage - * layout property of a dataset is contiguous by default. For better - * performance, the layout can be modified to be chunked or chunked - * and compressed. + * Typically, property lists are created by instantiating one of the built-in + * or user-defined property list classes. After adding suitable properties, + * property lists are used when opening or creating HDF5 items, or when reading + * or writing data. Property lists can be modified by adding or changing + * properties. Property lists are deleted by closing the associated handles. * - * \todo Describe concisely what the functions in this module are about. + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c create + * </td> + * <td> + * \snippet{lineno} H5P_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c update + * </td> + * <td> + * \snippet{lineno} H5P_examples.c delete + * </td> + * </tr> + * </table> * - * \defgroup GPLO General Property List Operations + * \defgroup ALCAPL Attribute and Link Creation Properties * \ingroup H5P - * \defgroup GPLOA General Property List Operations (Advanced) + * Currently, there are only two creation properties that you can use to control + * the creation of HDF5 attributes and links. The first creation property, the + * choice of a character encoding, applies to both attributes and links. + * The second creation property applies to links only, and advises the library + * to automatically create missing intermediate groups when creating new objects. + * + * \defgroup DAPL Dataset Access Properties * \ingroup H5P - * \defgroup FCPL File Creation Properties + * Use dataset access properties to modify the default behavior of the HDF5 + * library when accessing datasets. The properties include adjusting the size + * of the chunk cache, providing prefixes for external content and virtual + * dataset file paths, and controlling flush behavior, etc. These properties + * are \Emph{not} persisted with datasets, and can be adjusted at runtime before + * a dataset is created or opened. + * + * \defgroup DCPL Dataset Creation Properties + * \ingroup H5P + * Use dataset creation properties to control aspects of dataset creation such + * as fill time, storage layout, compression methods, etc. + * Unlike dataset access and transfer properties, creation properties \Emph{are} + * stored with the dataset, and cannot be changed once a dataset has been + * created. + * + * \defgroup DXPL Dataset Transfer Properties * \ingroup H5P + * Use dataset transfer properties to customize certain aspects of reading + * and writing datasets such as transformations, MPI-IO I/O mode, error + * detection, etc. These properties are \Emph{not} persisted with datasets, + * and can be adjusted at runtime before a dataset is read or written. + * * \defgroup FAPL File Access Properties * \ingroup H5P - * \defgroup GCPL Group Creation Properties + * Use file access properties to modify the default behavior of the HDF5 + * library when accessing files. The properties include selecting a virtual + * file driver (VFD), configuring the metadata cache (MDC), control + * file locking, etc. These properties are \Emph{not} persisted with files, and + * can be adjusted at runtime before a file is created or opened. + * + * \defgroup FCPL File Creation Properties * \ingroup H5P - * \defgroup ALCAPL Attribute and Link Creation Properties + * Use file creation properties to control aspects of file creation such + * as setting a file space management strategy or creating a user block. + * Unlike file access properties, creation properties \Emph{are} + * stored with the file, and cannot be changed once a file has been + * created. + * + * \defgroup GAPL General Access Properties * \ingroup H5P - * \defgroup LAPL Link Access Properties + * \todo Should this be as standalone page? + * + * \defgroup GCPL Group Creation Properties * \ingroup H5P - * \defgroup DCPL Dataset Creation Properties + * Use group creation properties to control aspects of group creation such + * as storage layout, compression, and link creation order tracking. + * Unlike file access properties, creation properties \Emph{are} + * stored with the group, and cannot be changed once a group has been + * created. + * + * \defgroup GPLO General Property List Operations * \ingroup H5P - * \defgroup DAPL Dataset Access Properties + * + * Use the functions in this module to manage HDF5 property lists. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c create + * </td> + * <td> + * \snippet{lineno} H5P_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c update + * </td> + * <td> + * \snippet{lineno} H5P_examples.c delete + * </td> + * </tr> + * </table> + * + * \defgroup GPLOA General Property List Operations (Advanced) * \ingroup H5P - * \defgroup DXPL Dataset Transfer Properties + * + * You can create and customize user-defined property list classes using the + * functions described below. Arbitrary user-defined properties can also + * be inserted into existing property lists as so-called temporary properties. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c create_class + * </td> + * <td> + * \snippet{lineno} H5P_examples.c read_class + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5P_examples.c update_class + * </td> + * <td> + * \snippet{lineno} H5P_examples.c delete_class + * </td> + * </tr> + * </table> + * + * \defgroup LAPL Link Access Properties * \ingroup H5P + * + * + * \defgroup MAPL Map Access Properties + * \ingroup H5P + * \defgroup OCPL Object Creation Properties * \ingroup H5P + * + * * \defgroup OCPPL Object Copy Properties * \ingroup H5P - * \defgroup GACPL General Access Properties - * \ingroup H5P - * \defgroup MAPL Map Access Properties - * \ingroup H5P + * + * */ #endif /* H5Pmodule_H */ diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 72a2358..cba7e03 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -22,16 +22,17 @@ /* Public headers needed by this file */ #include "H5public.h" -#include "H5ACpublic.h" -#include "H5Dpublic.h" -#include "H5Fpublic.h" -#include "H5FDpublic.h" -#include "H5Ipublic.h" -#include "H5Lpublic.h" -#include "H5Opublic.h" -#include "H5MMpublic.h" -#include "H5Tpublic.h" -#include "H5Zpublic.h" +#include "H5ACpublic.h" /* Metadata cache */ +#include "H5Dpublic.h" /* Datasets */ +#include "H5Fpublic.h" /* Files */ +#include "H5FDpublic.h" /* File drivers */ +#include "H5Ipublic.h" /* ID management */ +#include "H5Lpublic.h" /* Links */ +#include "H5MMpublic.h" /* Memory management */ +#include "H5Opublic.h" /* Object headers */ +#include "H5Spublic.h" /* Dataspaces */ +#include "H5Tpublic.h" /* Datatypes */ +#include "H5Zpublic.h" /* Data filters */ /*****************/ /* Public Macros */ @@ -100,7 +101,9 @@ #define H5P_CRT_ORDER_TRACKED 0x0001 #define H5P_CRT_ORDER_INDEXED 0x0002 -/* Default value for all property list classes */ +/** + * Default value of type \ref hid_t for all property list classes + */ #define H5P_DEFAULT 0 /* (hid_t) */ #ifdef __cplusplus @@ -113,14 +116,23 @@ extern "C" { /* Define property list class callback function pointer types */ //! <!-- [H5P_cls_create_func_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_cls_create_func_t)(hid_t prop_id, void *create_data); //! <!-- [H5P_cls_create_func_t_snip] --> //! <!-- [H5P_cls_copy_func_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_cls_copy_func_t)(hid_t new_prop_id, hid_t old_prop_id, void *copy_data); //! <!-- [H5P_cls_copy_func_t_snip] --> //! <!-- [H5P_cls_close_func_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_cls_close_func_t)(hid_t prop_id, void *close_data); //! <!-- [H5P_cls_close_func_t_snip] --> @@ -159,12 +171,25 @@ typedef herr_t (*H5P_prp_cb2_t)(hid_t prop_id, const char *name, size_t size, vo typedef H5P_prp_cb1_t H5P_prp_create_func_t; typedef H5P_prp_cb2_t H5P_prp_set_func_t; typedef H5P_prp_cb2_t H5P_prp_get_func_t; +//! <!-- [H5P_prp_encode_func_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_prp_encode_func_t)(const void *value, void **buf, size_t *size); +//! <!-- [H5P_prp_encode_func_t_snip] --> +//! <!-- [H5P_prp_decode_func_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_prp_decode_func_t)(const void **buf, void *value); +//! <!-- [H5P_prp_decode_func_t_snip] --> typedef H5P_prp_cb2_t H5P_prp_delete_func_t; typedef H5P_prp_cb1_t H5P_prp_copy_func_t; //! <!-- [H5P_prp_compare_func_t_snip] --> +/** + * \todo Document me! + */ typedef int (*H5P_prp_compare_func_t)(const void *value1, const void *value2, size_t size); //! <!-- [H5P_prp_compare_func_t_snip] --> @@ -172,6 +197,9 @@ typedef H5P_prp_cb1_t H5P_prp_close_func_t; /* Define property list iteration function type */ //! <!-- [H5P_iterate_t_snip] --> +/** + * \todo Document me! + */ typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data); //! <!-- [H5P_iterate_t_snip] --> @@ -2212,7 +2240,7 @@ H5_DLL herr_t H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flag */ H5_DLL herr_t H5Pset_attr_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense); /** - * \ingroup OCPL + * \ingroup DCPL * * \brief Sets deflate (GNU gzip) compression method and compression level * @@ -2221,6 +2249,8 @@ H5_DLL herr_t H5Pset_attr_phase_change(hid_t plist_id, unsigned max_compact, uns * * \return \herr_t * + * \par_compr_note + * * \details H5Pset_deflate() sets the deflate compression method and the * compression level, \p level, for a dataset or group creation * property list, \p plist_id. @@ -5212,9 +5242,37 @@ H5_DLL herr_t H5Pset_small_data_block_size(hid_t fapl_id, hsize_t size); */ H5_DLL herr_t H5Pset_vol(hid_t plist_id, hid_t new_vol_id, const void *new_vol_info); +/** + * \ingroup FAPL + * + * \brief Query the capability flags for the VOL connector that will be used + * with this file access property list (FAPL). + * + * \fapl_id{plist_id} + * \param[out] cap_flags Flags that indicate the VOL connector capabilities + * + * \return \herr_t + * + * \details H5Pget_vol_cap_flags() queries the current VOL connector information + * for a FAPL to retrieve the capability flags for the VOL + * connector stack, as will be used by a file open or create + * operation that uses this FAPL. + * + * \note This routine supports the use of the HDF5_VOL_CONNECTOR environment + * variable to override the VOL connector set programmatically for the + * FAPL (with H5Pset_vol). + * + * \note The H5VL_CAP_FLAG_ASYNC flag can be checked to see if asynchronous + * operations are supported by the VOL connector stack. + * + * \since 1.13.0 + * + */ +H5_DLL herr_t H5Pget_vol_cap_flags(hid_t plist_id, unsigned *cap_flags); + #ifdef H5_HAVE_PARALLEL /** - * \ingroup GACPL + * \ingroup GAPL * * \brief Sets metadata I/O mode for read operations to collective or independent (default) * @@ -5283,7 +5341,7 @@ H5_DLL herr_t H5Pset_vol(hid_t plist_id, hid_t new_vol_id, const void *new_vol_i */ H5_DLL herr_t H5Pset_all_coll_metadata_ops(hid_t plist_id, hbool_t is_collective); /** - * \ingroup GACPL + * \ingroup GAPL * * \brief Retrieves metadata read mode setting * @@ -6247,6 +6305,8 @@ H5_DLL herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value * * \return \herr_t * + * \par_compr_note + * * \details H5Pset_shuffle() sets the shuffle filter, #H5Z_FILTER_SHUFFLE, * in the dataset creation property list \p plist_id. The shuffle * filter de-interlaces a block of data by reordering the bytes. @@ -6318,6 +6378,8 @@ H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout); * * \return \herr_t * + * \par_compr_note + * * \details H5Pset_nbit() sets the N-Bit filter, #H5Z_FILTER_NBIT, in the * dataset creation property list \p plist_id. * @@ -6411,6 +6473,8 @@ H5_DLL herr_t H5Pset_nbit(hid_t plist_id); * * \return \herr_t * + * \par_compr_note + * * \details H5Pset_scaleoffset() sets the scale-offset filter, * #H5Z_FILTER_SCALEOFFSET, for a dataset. * @@ -6520,6 +6584,8 @@ H5_DLL herr_t H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, * * \return \herr_t * + * \par_compr_note + * * \details H5Pset_szip() sets an SZIP compression filter, #H5Z_FILTER_SZIP, * for a dataset. SZIP is a compression method designed for use with * scientific data. @@ -7430,10 +7496,6 @@ H5_DLL size_t H5Pget_buffer(hid_t plist_id, void **tconv /*out*/, void **bkg /*o * If an error occurs, the buffer pointed to by \p expression is * unchanged, and the function returns a negative value. * - * \par Example - * An example snippet from examples/h5_dtransform.c: - * \snippet h5_dtransform.c H5Pget_data_transform_snip - * * \since 1.8.0 * */ @@ -8009,6 +8071,44 @@ H5_DLL herr_t H5Pget_mpio_actual_io_mode(hid_t plist_id, H5D_mpio_actual_io_mode H5_DLL herr_t H5Pget_mpio_no_collective_cause(hid_t plist_id, uint32_t *local_no_collective_cause, uint32_t *global_no_collective_cause); #endif /* H5_HAVE_PARALLEL */ +/** + * + * \ingroup DXPL + * + * \brief Sets a hyperslab file selection for a dataset I/O operation + * + * \param[in] plist_id Property list identifier + * \param[in] rank Number of dimensions of selection + * \param[in] op Operation to perform on current selection + * \param[in] start Offset of start of hyperslab + * \param[in] stride Hyperslab stride + * \param[in] count Number of blocks included in hyperslab + * \param[in] block Size of block in hyperslab + * + * \return \herr_t + * + * \details H5Pset_dataset_io_hyperslab_selection() is designed to be used + * in conjunction with using #H5S_PLIST for the file dataspace + * ID when making a call to H5Dread() or H5Dwrite(). When used + * with #H5S_PLIST, the selection created by one or more calls to + * this routine is used for determining which dataset elements to + * access. + * + * \p rank is the dimensionality of the selection and determines + * the size of the \p start, \p stride, \p count, and \p block arrays. + * \p rank must be between 1 and #H5S_MAX_RANK, inclusive. + * + * The \p op, \p start, \p stride, \p count, and \p block parameters + * behave identically to their behavior for H5Sselect_hyperslab(), + * please see the documentation for that routine for details about + * their use. + * + * \since 1.13.0 + * + */ +H5_DLL herr_t H5Pset_dataset_io_hyperslab_selection(hid_t plist_id, unsigned rank, H5S_seloper_t op, + const hsize_t start[], const hsize_t stride[], + const hsize_t count[], const hsize_t block[]); /* Link creation property list (LCPL) routines */ /** @@ -9398,9 +9498,6 @@ H5_DLL herr_t H5Pset_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t func, v * The #H5P_prp_cb2_t is as follows: * \snippet this H5P_prp_cb2_t_snip * - * - * \cpp_c_api_note - * */ /* Function prototypes */ @@ -9514,8 +9611,7 @@ H5_DLL herr_t H5Pregister1(hid_t cls_id, const char *name, size_t size, void *de * * The #H5P_prp_cb2_t is as follows: * \snippet this H5P_prp_cb2_t_snip - - * \cpp_c_api_note + * */ H5_DLL herr_t H5Pinsert1(hid_t plist_id, const char *name, size_t size, void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get, diff --git a/src/H5R.c b/src/H5R.c index 1413c1c..102af7f 100644 --- a/src/H5R.c +++ b/src/H5R.c @@ -79,14 +79,16 @@ static hid_t H5R__open_attr_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t herr_t H5Rcreate_object(hid_t loc_id, const char *name, hid_t oapl_id, H5R_ref_t *ref_ptr) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t obj_type; /* Object type of loc_id */ - hid_t file_id = H5I_INVALID_HID; /* File ID */ - H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID; /* File ID */ + H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ + H5VL_object_specific_args_t obj_spec_vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t file_get_vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*si*Rr", loc_id, name, oapl_id, ref_ptr); @@ -121,9 +123,12 @@ H5Rcreate_object(hid_t loc_id, const char *name, hid_t oapl_id, H5R_ref_t *ref_p if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + file_get_vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + file_get_vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &file_get_vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") /* Set location parameters */ @@ -132,15 +137,18 @@ H5Rcreate_object(hid_t loc_id, const char *name, hid_t oapl_id, H5R_ref_t *ref_p loc_params.loc_data.loc_by_name.lapl_id = oapl_id; loc_params.obj_type = obj_type; + /* Set up VOL callback arguments */ + obj_spec_vol_cb_args.op_type = H5VL_OBJECT_LOOKUP; + obj_spec_vol_cb_args.args.lookup.token_ptr = &obj_token; + /* Get the object token */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &obj_token) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &obj_spec_vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") /* Create the reference (do not pass filename, since file_id is attached) */ HDmemset(ref_ptr, 0, H5R_REF_BUF_SIZE); - if (H5R__create_object((const H5O_token_t *)&obj_token, cont_info.token_size, (H5R_ref_priv_t *)ref_ptr) < - 0) + if (H5R__create_object(&obj_token, cont_info.token_size, (H5R_ref_priv_t *)ref_ptr) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create object reference") /* Attach loc_id to reference and hold reference to it */ @@ -167,15 +175,17 @@ done: herr_t H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, hid_t oapl_id, H5R_ref_t *ref_ptr) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t obj_type; /* Object type of loc_id */ - hid_t file_id = H5I_INVALID_HID; /* File ID */ - H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - struct H5S_t * space = NULL; /* Pointer to dataspace containing region */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID; /* File ID */ + H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ + H5VL_object_specific_args_t obj_spec_vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t file_get_vol_cb_args; /* Arguments to VOL callback */ + struct H5S_t * space = NULL; /* Pointer to dataspace containing region */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*sii*Rr", loc_id, name, space_id, oapl_id, ref_ptr); @@ -185,7 +195,7 @@ H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, hid_t oapl_id, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") if (!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") - if ((space_id == H5I_INVALID_HID) || (space_id == H5S_ALL)) + if ((space_id == H5I_INVALID_HID) || (space_id == H5S_ALL) || (space_id == H5S_BLOCK)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "reference region dataspace id must be valid") if (NULL == (space = (struct H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") @@ -214,9 +224,12 @@ H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, hid_t oapl_id, if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + file_get_vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + file_get_vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &file_get_vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") /* Set location parameters */ @@ -225,9 +238,13 @@ H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id, hid_t oapl_id, loc_params.loc_data.loc_by_name.lapl_id = oapl_id; loc_params.obj_type = obj_type; + /* Set up VOL callback arguments */ + obj_spec_vol_cb_args.op_type = H5VL_OBJECT_LOOKUP; + obj_spec_vol_cb_args.args.lookup.token_ptr = &obj_token; + /* Get the object token */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &obj_token) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &obj_spec_vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") /* Create the reference (do not pass filename, since file_id is attached) */ @@ -259,14 +276,16 @@ done: herr_t H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, hid_t oapl_id, H5R_ref_t *ref_ptr) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t obj_type; /* Object type of loc_id */ - hid_t file_id = H5I_INVALID_HID; /* File ID */ - H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t obj_type; /* Object type of loc_id */ + hid_t file_id = H5I_INVALID_HID; /* File ID */ + H5VL_object_t * vol_obj_file = NULL; /* Object of file_id */ + H5VL_object_specific_args_t obj_spec_vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t file_get_vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*s*si*Rr", loc_id, name, attr_name, oapl_id, ref_ptr); @@ -303,9 +322,12 @@ H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, hid_t oapl if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + file_get_vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + file_get_vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get(vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &file_get_vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") /* Set location parameters */ @@ -314,9 +336,13 @@ H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name, hid_t oapl loc_params.loc_data.loc_by_name.lapl_id = oapl_id; loc_params.obj_type = obj_type; + /* Set up VOL callback arguments */ + obj_spec_vol_cb_args.op_type = H5VL_OBJECT_LOOKUP; + obj_spec_vol_cb_args.args.lookup.token_ptr = &obj_token; + /* Get the object token */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &obj_token) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &obj_spec_vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") /* Create the reference (do not pass filename, since file_id is attached) */ @@ -611,15 +637,16 @@ H5R__open_region_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, vo hid_t loc_id; /* Reference location ID */ H5VL_object_t * tmp_vol_obj = NULL; /* Object for loc_id */ H5VL_object_t **vol_obj_ptr = - (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5I_type_t opened_type; /* Opened object type */ - void * opened_obj = NULL; /* Opened object */ - hid_t opened_obj_id = H5I_INVALID_HID; /* Opened object ID */ - H5S_t * space = NULL; /* Dataspace pointer (copy) */ - hid_t space_id = H5I_INVALID_HID; /* Dataspace ID */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5O_token_t obj_token = {0}; /* Object token */ + H5I_type_t opened_type; /* Opened object type */ + void * opened_obj = NULL; /* Opened object */ + hid_t opened_obj_id = H5I_INVALID_HID; /* Opened object ID */ + H5S_t * space = NULL; /* Dataspace pointer (copy) */ + hid_t space_id = H5I_INVALID_HID; /* Dataspace ID */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_STATIC @@ -662,10 +689,14 @@ H5R__open_region_api_common(H5R_ref_t *ref_ptr, hid_t rapl_id, hid_t oapl_id, vo if (NULL == (opened_obj = H5VL_vol_object(opened_obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_SPACE; + vol_cb_args.args.get_space.space_id = H5I_INVALID_HID; + /* Get dataspace from object */ - if (H5VL_dataset_get(opened_obj, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &space_id) < 0) + if (H5VL_dataset_get(opened_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get dataspace from dataset") + space_id = vol_cb_args.args.get_space.space_id; if (NULL == (space = (struct H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a dataspace") @@ -940,11 +971,12 @@ done: herr_t H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type /*out*/) { - hid_t loc_id; /* Reference location ID */ - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - herr_t ret_value = SUCCEED; /* Return value */ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "*Rrix", ref_ptr, rapl_id, obj_type); @@ -959,11 +991,10 @@ H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type /*out*/ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") /* Retrieve loc_id from reference */ - if (H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + if (H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) /* Attempt to re-open file and pass rapl_id as a fapl_id */ if ((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, FAIL, "cannot re-open referenced file") - } /* Get object token */ if (H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) @@ -978,9 +1009,12 @@ H5Rget_obj_type3(H5R_ref_t *ref_ptr, hid_t rapl_id, H5O_type_t *obj_type /*out*/ loc_params.loc_data.loc_by_token.token = &obj_token; loc_params.obj_type = H5I_get_type(loc_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_TYPE; + vol_cb_args.args.get_type.obj_type = obj_type; + /* Retrieve object's type */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - obj_type) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve object type") done: @@ -1021,15 +1055,27 @@ H5Rget_file_name(const H5R_ref_t *ref_ptr, char *buf /*out*/, size_t size) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to retrieve file name") } else { - H5VL_object_t *vol_obj = NULL; /* Object of loc_id */ + H5VL_object_t * vol_obj; /* Object of loc_id */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t file_name_len = 0; /* Length of file name */ /* Retrieve VOL file object */ if (NULL == (vol_obj = H5VL_vol_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid location identifier") - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, H5I_FILE, - size, buf, &ret_value) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_NAME; + vol_cb_args.args.get_name.type = H5I_FILE; + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = buf; + vol_cb_args.args.get_name.file_name_len = &file_name_len; + + /* Get file name */ + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "unable to get file name") + + /* Set return value */ + ret_value = (ssize_t)file_name_len; } done: @@ -1049,11 +1095,13 @@ done: ssize_t H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf /*out*/, size_t size) { - hid_t loc_id; /* Reference location ID */ - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - ssize_t ret_value = 0; /* Return value */ + hid_t loc_id; /* Reference location ID */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + size_t obj_name_len = 0; /* Length of object's name */ + ssize_t ret_value = 0; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE4("Zs", "*Rrixz", ref_ptr, rapl_id, buf, size); @@ -1068,11 +1116,10 @@ H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf /*out*/, size_t siz HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not a property list") /* Retrieve loc_id from reference */ - if (H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) { + if (H5I_INVALID_HID == (loc_id = H5R__get_loc_id((const H5R_ref_priv_t *)ref_ptr))) /* Attempt to re-open file and pass rapl_id as a fapl_id */ if ((loc_id = H5R__reopen_file((H5R_ref_priv_t *)ref_ptr, rapl_id)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENFILE, (-1), "cannot re-open referenced file") - } /* Get object token */ if (H5R__get_obj_token((const H5R_ref_priv_t *)ref_ptr, &obj_token, NULL) < 0) @@ -1087,11 +1134,19 @@ H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *buf /*out*/, size_t siz loc_params.loc_data.loc_by_token.token = &obj_token; loc_params.obj_type = H5I_get_type(loc_id); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_NAME; + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = buf; + vol_cb_args.args.get_name.name_len = &obj_name_len; + /* Retrieve object's name */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value, buf, size) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "can't retrieve object name") + /* Set return value */ + ret_value = (ssize_t)obj_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Rget_obj_name() */ diff --git a/src/H5RS.c b/src/H5RS.c index 96d55e7..d9915f2 100644 --- a/src/H5RS.c +++ b/src/H5RS.c @@ -349,7 +349,7 @@ done: * format_templ in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") H5_ATTR_FORMAT(printf, 2, 3) herr_t H5RS_asprintf_cat(H5RS_str_t *rs, const char *fmt, ...) @@ -392,7 +392,7 @@ H5RS_asprintf_cat(H5RS_str_t *rs, const char *fmt, ...) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5RS_asprintf_cat() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: H5RS_acat @@ -698,7 +698,7 @@ H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2) const H5RS_str_t *rs; IN: Ref-counted string to compute length of RETURNS - Returns non-negative value on success, negative value on failure + Returns non-negative value on success, can't fail DESCRIPTION Compute the length of a ref-counted string. [same as strlen()] GLOBAL VARIABLES @@ -706,7 +706,7 @@ H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2) EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -ssize_t +size_t H5RS_len(const H5RS_str_t *rs) { FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -715,7 +715,7 @@ H5RS_len(const H5RS_str_t *rs) HDassert(rs); HDassert(rs->s); - FUNC_LEAVE_NOAPI((ssize_t)HDstrlen(rs->s)) + FUNC_LEAVE_NOAPI(HDstrlen(rs->s)) } /* end H5RS_len() */ /*-------------------------------------------------------------------------- diff --git a/src/H5RSprivate.h b/src/H5RSprivate.h index 7d2b728..ebca1a3 100644 --- a/src/H5RSprivate.h +++ b/src/H5RSprivate.h @@ -53,7 +53,7 @@ H5_DLL herr_t H5RS_acat(H5RS_str_t *rs, const char *s); H5_DLL herr_t H5RS_ancat(H5RS_str_t *rs, const char *s, size_t len); H5_DLL herr_t H5RS_aputc(H5RS_str_t *rs, int c); H5_DLL int H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2); -H5_DLL ssize_t H5RS_len(const H5RS_str_t *rs); +H5_DLL size_t H5RS_len(const H5RS_str_t *rs); H5_DLL char * H5RS_get_str(const H5RS_str_t *rs); H5_DLL unsigned H5RS_get_count(const H5RS_str_t *rs); diff --git a/src/H5Rdeprec.c b/src/H5Rdeprec.c index d5f5a7d..3f1d70f 100644 --- a/src/H5Rdeprec.c +++ b/src/H5Rdeprec.c @@ -94,7 +94,8 @@ H5R__decode_token_compat(H5VL_object_t *vol_obj, H5I_type_t type, H5R_type_t ref hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ H5VL_object_t * vol_obj_file = NULL; H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - herr_t ret_value = SUCCEED; + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + herr_t ret_value = SUCCEED; FUNC_ENTER_STATIC @@ -119,9 +120,12 @@ H5R__decode_token_compat(H5VL_object_t *vol_obj, H5I_type_t type, H5R_type_t ref if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get((const H5VL_object_t *)vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") if (ref_type == H5R_OBJECT1) { @@ -240,13 +244,14 @@ done: H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5O_type_t obj_type; /* Object type */ - const unsigned char *buf = (const unsigned char *)ref; /* Reference buffer */ - H5G_obj_t ret_value; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + const unsigned char * buf = (const unsigned char *)ref; /* Reference buffer */ + H5O_type_t obj_type = H5O_TYPE_UNKNOWN; /* Type of the referenced object */ + H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_API(H5G_UNKNOWN) H5TRACE3("Go", "iRt*x", id, ref_type, ref); @@ -274,9 +279,12 @@ H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref) loc_params.loc_data.loc_by_token.token = &obj_token; loc_params.obj_type = vol_obj_type; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_TYPE; + vol_cb_args.args.get_type.obj_type = &obj_type; + /* Retrieve object's type */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &obj_type) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5G_UNKNOWN, "can't retrieve object type") /* Set return value */ @@ -365,15 +373,17 @@ done: herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ - void * vol_obj_file = NULL; - unsigned char * buf = (unsigned char *)ref; /* Return reference pointer */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ + H5VL_object_specific_args_t obj_spec_vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t file_get_vol_cb_args; /* Arguments to VOL callback */ + hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ + void * vol_obj_file = NULL; + unsigned char * buf = (unsigned char *)ref; /* Return reference pointer */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "*xi*sRti", ref, loc_id, name, ref_type, space_id); @@ -417,9 +427,13 @@ H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t loc_params.loc_data.loc_by_name.lapl_id = H5P_LINK_ACCESS_DEFAULT; loc_params.obj_type = vol_obj_type; + /* Set up VOL callback arguments */ + obj_spec_vol_cb_args.op_type = H5VL_OBJECT_LOOKUP; + obj_spec_vol_cb_args.args.lookup.token_ptr = &obj_token; + /* Get the object token */ - if (H5VL_object_specific(vol_obj, &loc_params, H5VL_OBJECT_LOOKUP, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &obj_token) < 0) + if (H5VL_object_specific(vol_obj, &loc_params, &obj_spec_vol_cb_args, H5P_DATASET_XFER_DEFAULT, + H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to retrieve object token") /* Get the file for the object */ @@ -430,9 +444,12 @@ H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* Set up VOL callback arguments */ + file_get_vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + file_get_vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get((const H5VL_object_t *)vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &file_get_vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "unable to get container info") /* Create reference */ @@ -483,12 +500,13 @@ done: herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj_type /*out*/) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - const unsigned char *buf = (const unsigned char *)ref; /* Reference pointer */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + const unsigned char * buf = (const unsigned char *)ref; /* Reference pointer */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "iRt*xx", id, ref_type, ref, obj_type); @@ -516,9 +534,12 @@ H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj loc_params.loc_data.loc_by_token.token = &obj_token; loc_params.obj_type = vol_obj_type; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_TYPE; + vol_cb_args.args.get_type.obj_type = obj_type; + /* Retrieve object's type */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - obj_type) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve object type") done: @@ -612,12 +633,13 @@ H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ void * vol_obj_file = NULL; /* VOL file */ H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - H5F_t * f = NULL; /* Native file */ - size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; /* Reference buffer size */ - H5S_t * space = NULL; /* Dataspace object */ - hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ - const unsigned char * buf = (const unsigned char *)ref; /* Reference pointer */ - hid_t ret_value; /* Return value */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5F_t * f = NULL; /* Native file */ + size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE; /* Reference buffer size */ + H5S_t * space = NULL; /* Dataspace object */ + hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */ + const unsigned char * buf = (const unsigned char *)ref; /* Reference pointer */ + hid_t ret_value; /* Return value */ FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE3("i", "iRt*x", id, ref_type, ref); @@ -658,9 +680,12 @@ H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) if (NULL == (vol_obj_file = H5VL_vol_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid location identifier") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get((const H5VL_object_t *)vol_obj_file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, &cont_info) < 0) + if (H5VL_file_get(vol_obj_file, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "unable to get container info") /* Retrieve file from VOL object */ @@ -695,12 +720,14 @@ done: ssize_t H5Rget_name(hid_t id, H5R_type_t ref_type, const void *ref, char *name /*out*/, size_t size) { - H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ - H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ - H5VL_loc_params_t loc_params; /* Location parameters */ - H5O_token_t obj_token = {0}; /* Object token */ - const unsigned char *buf = (const unsigned char *)ref; /* Reference pointer */ - ssize_t ret_value = -1; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object of loc_id */ + H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */ + H5VL_object_get_args_t vol_cb_args; /* Arguments to VOL callback */ + H5VL_loc_params_t loc_params; /* Location parameters */ + H5O_token_t obj_token = {0}; /* Object token */ + const unsigned char * buf = (const unsigned char *)ref; /* Reference pointer */ + size_t obj_name_len = 0; /* Length of object's name */ + ssize_t ret_value = -1; /* Return value */ FUNC_ENTER_API((-1)) H5TRACE5("Zs", "iRt*xxz", id, ref_type, ref, name, size); @@ -728,11 +755,19 @@ H5Rget_name(hid_t id, H5R_type_t ref_type, const void *ref, char *name /*out*/, loc_params.loc_data.loc_by_token.token = &obj_token; loc_params.obj_type = vol_obj_type; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_OBJECT_GET_NAME; + vol_cb_args.args.get_name.buf_size = size; + vol_cb_args.args.get_name.buf = name; + vol_cb_args.args.get_name.name_len = &obj_name_len; + /* Retrieve object's name */ - if (H5VL_object_get(vol_obj, &loc_params, H5VL_OBJECT_GET_NAME, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value, name, size) < 0) + if (H5VL_object_get(vol_obj, &loc_params, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "can't retrieve object name") + /* Set return value */ + ret_value = (ssize_t)obj_name_len; + done: FUNC_LEAVE_API(ret_value) } /* end H5Rget_name() */ diff --git a/src/H5Rint.c b/src/H5Rint.c index b714f09..e1a5dcd 100644 --- a/src/H5Rint.c +++ b/src/H5Rint.c @@ -588,11 +588,18 @@ H5R__reopen_file(H5R_ref_priv_t *ref, hid_t fapl_id) supported = 0; if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, H5I_INVALID_HID, "can't check for 'post open' operation") - if (supported & H5VL_OPT_QUERY_SUPPORTED) - if (H5VL_file_optional(vol_obj, H5VL_NATIVE_FILE_POST_OPEN, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL) < 0) + if (supported & H5VL_OPT_QUERY_SUPPORTED) { + H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_NATIVE_FILE_POST_OPEN; + vol_cb_args.args = NULL; + + /* Make the 'post open' callback */ + if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, H5I_INVALID_HID, "unable to make file 'post open' callback") + } /* end if */ /* Attach loc_id to reference */ if (H5R__set_loc_id((H5R_ref_priv_t *)ref, ret_value, FALSE, TRUE) < 0) diff --git a/src/H5Rmodule.h b/src/H5Rmodule.h index 2a34d56..fe28bb2 100644 --- a/src/H5Rmodule.h +++ b/src/H5Rmodule.h @@ -27,9 +27,32 @@ /** * \defgroup H5R H5R - * \brief Reference Interface - * \details The HDF5 Reference Interface, H5R, provides a mechanism for managing - * HDF5 referenced objects. + * + * Use the functions in this module to manage HDF5 references. Referents can + * be HDF5 objects, attributes, and selections on datasets a.k.a. dataset + * regions. + * + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5R_examples.c create + * </td> + * <td> + * \snippet{lineno} H5R_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5R_examples.c update + * </td> + * <td> + * \snippet{lineno} H5R_examples.c delete + * </td> + * </tr> + * </table> + * */ #endif /* H5Rmodule_H */ diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index b33960e..ef798ea 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -30,9 +30,11 @@ #define H5R_OBJ_REF_BUF_SIZE sizeof(haddr_t) #define H5R_DSET_REG_REF_BUF_SIZE (sizeof(haddr_t) + 4) -/* Default reference buffer size. - * Note! Be careful with the sizes of the references because they should really - * depend on the run-time values in the file. +/** + * Default reference buffer size. + * + * \internal Note! Be careful with the sizes of the references because they + * should really depend on the run-time values in the file. */ #define H5R_REF_BUF_SIZE (64) @@ -560,6 +562,7 @@ H5_DLL ssize_t H5Rget_obj_name(H5R_ref_t *ref_ptr, hid_t rapl_id, char *name, si */ H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *name, size_t size); +/// \cond DEV /* API Wrappers for async routines */ /* (Must be defined _after_ the function prototype) */ /* (And must only defined when included in application code, not the library) */ @@ -574,6 +577,7 @@ H5_DLL ssize_t H5Rget_attr_name(const H5R_ref_t *ref_ptr, char *name, size_t siz #define H5Ropen_region_async_wrap H5_NO_EXPAND(H5Ropen_region_async) #define H5Ropen_attr_async_wrap H5_NO_EXPAND(H5Ropen_attr_async) #endif /* H5R_MODULE */ +/// \endcond /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5SL.c b/src/H5SL.c index 166019b..ba9721c 100644 --- a/src/H5SL.c +++ b/src/H5SL.c @@ -209,7 +209,7 @@ /* Check if we need to increase allocation of forward pointers */ \ if (LVL + 1 >= 1u << X->log_nalloc) { \ H5SL_node_t **_tmp; \ - HDassert(LVL + 1 == 1u << X->log_nalloc); \ + HDassert(LVL + 1 == 1U << X->log_nalloc); \ /* Double the amount of allocated space */ \ X->log_nalloc++; \ \ @@ -251,7 +251,7 @@ /* Check if we can reduce the allocation of forward pointers */ \ if (LVL <= 1u << (X->log_nalloc - 1)) { \ H5SL_node_t **_tmp; \ - HDassert(LVL == 1u << (X->log_nalloc - 1)); \ + HDassert(LVL == 1U << (X->log_nalloc - 1)); \ X->log_nalloc--; \ \ /* Allocate space for new forward pointers */ \ diff --git a/src/H5SM.c b/src/H5SM.c index e8ce4b2..03fb08c 100644 --- a/src/H5SM.c +++ b/src/H5SM.c @@ -1079,7 +1079,7 @@ H5SM_try_share(H5F_t *f, H5O_t *open_oh, unsigned defer_flags, unsigned type_id, ssize_t index_num; htri_t tri_ret; #ifndef NDEBUG - unsigned deferred_type = -1u; + unsigned deferred_type = -1U; #endif htri_t ret_value = TRUE; diff --git a/src/H5Smodule.h b/src/H5Smodule.h index bb33eb8..010f4a6 100644 --- a/src/H5Smodule.h +++ b/src/H5Smodule.h @@ -30,29 +30,36 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5S H5S - * \brief Dataspace Interface * - * \details The Dataspace Interface provides functions for creating and - * working with dataspaces. + * Use the functions in this module to manage HDF5 dataspaces \Emph{and} selections. * - * A dataspace has two roles: + * HDF5 dataspaces describe the \Emph{shape} of datasets in memory or in HDF5 + * files. Dataspaces can be empty (#H5S_NULL), a singleton (#H5S_SCALAR), or + * a multi-dimensional, regular grid (#H5S_SIMPLE). Dataspaces can be re-shaped. * - * \li It contains the spatial information (logical layout) of a - * dataset stored in a file. - * \li It describes an application’s data buffers and data elements - * participating in I/O. In other words, it can be used to - * select a portion or subset of a dataset. + * Subsets of dataspaces can be "book-marked" or used to restrict I/O operations + * using \Emph{selections}. Furthermore, certain set operations are supported + * for selections. * - * The spatial information of a dataset in a file includes the - * rank and dimensions of the dataset, which are a permanent part - * of the dataset definition. It can have dimensions that are fixed - * (unchanging) or unlimited, which means they can grow in size - * (or are extendible). - * - * A dataspace can consist of: - * \li no elements (NULL) - * \li a single element (scalar), or - * \li a simple array. + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5S_examples.c create + * </td> + * <td> + * \snippet{lineno} H5S_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5S_examples.c update + * </td> + * <td> + * \snippet{lineno} H5S_examples.c delete + * </td> + * </tr> + * </table> * */ diff --git a/src/H5Spublic.h b/src/H5Spublic.h index 7962035..30ca813 100644 --- a/src/H5Spublic.h +++ b/src/H5Spublic.h @@ -26,98 +26,101 @@ #define H5S_BLOCK 1 /* (hid_t) */ #define H5S_PLIST 2 /* (hid_t) */ -/* Define value for 'unlimited' dimensions */ -#define H5S_UNLIMITED HSIZE_UNDEF +#define H5S_UNLIMITED HSIZE_UNDEF /**< Value for 'unlimited' dimensions */ -/* Define user-level maximum number of dimensions */ +/** + * The maximum dataspace rank or number of dimensions + */ #define H5S_MAX_RANK 32 /* Flags for selection iterators */ #define H5S_SEL_ITER_GET_SEQ_LIST_SORTED \ - 0x0001 /* Retrieve elements from iterator \ - * in increasing offset order, for \ - * each call to retrieve sequences. \ - * Currently, this only applies to \ - * point selections, as hyperslab \ - * selections are always returned \ - * in increasing offset order. \ - * \ - * Note that the order is only \ - * increasing for each call to \ - * get_seq_list, the next set of \ - * sequences could start with an \ - * earlier offset than the previous \ - * one. \ + 0x0001 /**< Retrieve elements from iterator in increasing offset order, for \ + * each call to retrieve sequences. Currently, this only applies to \ + * point selections, as hyperslab selections are always returned in \ + * increasing offset order. Note that the order is only increasing \ + * for each call to H5Sget_seq_list(), the next set of sequences \ + * could start with an earlier offset than the previous one. \ */ #define H5S_SEL_ITER_SHARE_WITH_DATASPACE \ - 0x0002 /* Don't copy the dataspace \ - * selection when creating the \ - * selection iterator. \ - * \ - * This can improve performance \ - * of creating the iterator, but \ - * the dataspace _MUST_NOT_ be \ - * modified or closed until the \ - * selection iterator is closed \ - * or the iterator's behavior \ - * will be undefined. \ + 0x0002 /**< Don't copy the dataspace selection when creating the selection \ + * iterator. This can improve performance of creating the iterator, \ + * but the dataspace \Bold{MUST NOT} be modified or closed until the \ + * selection iterator is closed or the iterator's behavior will be \ + * undefined. \ */ -/* Different types of dataspaces */ +/** + * Types of dataspaces + */ typedef enum H5S_class_t { - H5S_NO_CLASS = -1, /*error */ - H5S_SCALAR = 0, /*scalar variable */ - H5S_SIMPLE = 1, /*simple dataspace */ - H5S_NULL = 2 /*null dataspace */ + H5S_NO_CLASS = -1, /**< Error */ + H5S_SCALAR = 0, /**< Singleton (scalar) */ + H5S_SIMPLE = 1, /**< Regular grid */ + H5S_NULL = 2 /**< Empty set */ } H5S_class_t; -/* Different ways of combining selections */ +/** + * Different ways of combining selections + */ typedef enum H5S_seloper_t { - H5S_SELECT_NOOP = -1, /* error */ - H5S_SELECT_SET = 0, /* Select "set" operation */ - H5S_SELECT_OR, /* Binary "or" operation for hyperslabs + H5S_SELECT_NOOP = -1, /**< Error */ + H5S_SELECT_SET = 0, /**< Select "set" operation */ + H5S_SELECT_OR, /**< Binary "or" operation for hyperslabs * (add new selection to existing selection) + * \code * Original region: AAAAAAAAAA * New region: BBBBBBBBBB * A or B: CCCCCCCCCCCCCCCC + * \endcode */ - H5S_SELECT_AND, /* Binary "and" operation for hyperslabs + H5S_SELECT_AND, /**< Binary "and" operation for hyperslabs * (only leave overlapped regions in selection) + * \code * Original region: AAAAAAAAAA * New region: BBBBBBBBBB * A and B: CCCC + * \endcode */ - H5S_SELECT_XOR, /* Binary "xor" operation for hyperslabs + H5S_SELECT_XOR, /**< Binary "xor" operation for hyperslabs * (only leave non-overlapped regions in selection) + * \code * Original region: AAAAAAAAAA * New region: BBBBBBBBBB * A xor B: CCCCCC CCCCCC + * \endcode */ - H5S_SELECT_NOTB, /* Binary "not" operation for hyperslabs + H5S_SELECT_NOTB, /**< Binary "not" operation for hyperslabs * (only leave non-overlapped regions in original selection) + * \code * Original region: AAAAAAAAAA * New region: BBBBBBBBBB * A not B: CCCCCC + * \endcode */ - H5S_SELECT_NOTA, /* Binary "not" operation for hyperslabs + H5S_SELECT_NOTA, /**< Binary "not" operation for hyperslabs * (only leave non-overlapped regions in new selection) + * \code * Original region: AAAAAAAAAA * New region: BBBBBBBBBB * B not A: CCCCCC + * \endcode */ - H5S_SELECT_APPEND, /* Append elements to end of point selection */ - H5S_SELECT_PREPEND, /* Prepend elements to beginning of point selection */ - H5S_SELECT_INVALID /* Invalid upper bound on selection operations */ + H5S_SELECT_APPEND, /**< Append elements to end of point selection */ + H5S_SELECT_PREPEND, /**< Prepend elements to beginning of point selection */ + H5S_SELECT_INVALID /**< Invalid upper bound on selection operations */ } H5S_seloper_t; -/* Enumerated type for the type of selection */ +/** + * Selection type + */ typedef enum { - H5S_SEL_ERROR = -1, /* Error */ - H5S_SEL_NONE = 0, /* Nothing selected */ - H5S_SEL_POINTS = 1, /* Points / elements selected */ - H5S_SEL_HYPERSLABS = 2, /* Hyperslab selected */ - H5S_SEL_ALL = 3, /* Entire extent selected */ - H5S_SEL_N /*THIS MUST BE LAST */ + H5S_SEL_ERROR = -1, /**< Error */ + H5S_SEL_NONE = 0, /**< Empty selection */ + H5S_SEL_POINTS = 1, /**< Set of points */ + H5S_SEL_HYPERSLABS = 2, /**< Hyperslab */ + H5S_SEL_ALL = 3, /**< Everything */ + H5S_SEL_N /**< Sentinel \internal THIS MUST BE LAST */ } H5S_sel_type; #ifdef __cplusplus @@ -1318,9 +1321,6 @@ H5_DLL herr_t H5Sset_extent_none(hid_t space_id); * \details H5Sset_extent_simple() sets or resets the size of an existing * dataspace. * - * \p rank is the dimensionality, or number of dimensions, of the - * dataspace. - * * \p dims is an array of size \p rank which contains the new size * of each dimension in the dataspace. \p max is an array of size * \p rank which contains the maximum size of each dimension in @@ -1329,10 +1329,6 @@ H5_DLL herr_t H5Sset_extent_none(hid_t space_id); * Any previous extent is removed from the dataspace, the dataspace * type is set to #H5S_SIMPLE, and the extent is set as specified. * - * Note that a dataset must be chunked if \p dims does not equal - * \p max. - * - * * \version 1.4.0 Fortran subroutine was introduced. * \since 1.0.0 * diff --git a/src/H5T.c b/src/H5T.c index b6bfb9a..19a3d39 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -290,7 +290,7 @@ #define H5T_INIT_TYPE_SET_SIZE(SIZE) \ { \ dt->shared->size = SIZE; \ - dt->shared->u.atomic.prec = 8 * SIZE; \ + dt->shared->u.atomic.prec = 8 * (SIZE); \ } #define H5T_INIT_TYPE_NOSET_SIZE(SIZE) \ @@ -327,7 +327,7 @@ H5_GLUE3(H5T_INIT_TYPE_, GUTS, _CORE) \ \ /* Register result */ \ - if ((GLOBAL = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0) \ + if (((GLOBAL) = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0) \ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype atom") \ } @@ -560,8 +560,8 @@ size_t H5T_NATIVE_UINT_FAST64_ALIGN_g = 0; /* Useful floating-point values for conversion routines */ /* (+/- Inf for all floating-point types) */ -float H5T_NATIVE_FLOAT_POS_INF_g = 0.0f; -float H5T_NATIVE_FLOAT_NEG_INF_g = 0.0f; +float H5T_NATIVE_FLOAT_POS_INF_g = 0.0F; +float H5T_NATIVE_FLOAT_NEG_INF_g = 0.0F; double H5T_NATIVE_DOUBLE_POS_INF_g = 0.0; double H5T_NATIVE_DOUBLE_NEG_INF_g = 0.0; @@ -1892,19 +1892,24 @@ H5Tcopy(hid_t obj_id) break; case H5I_DATASET: { - H5VL_object_t *vol_obj = NULL; /* Dataset structure */ + H5VL_object_t * vol_obj; /* Object for obj_id */ + H5VL_dataset_get_args_t vol_cb_args; /* Arguments to VOL callback */ /* The argument is a dataset handle */ if (NULL == (vol_obj = (H5VL_object_t *)H5I_object_verify(obj_id, H5I_DATASET))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "type_id is not a dataset ID") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATASET_GET_TYPE; + vol_cb_args.args.get_type.type_id = H5I_INVALID_HID; + /* Get the datatype from the dataset * NOTE: This will have to be closed after we're done with it. */ - if (H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_TYPE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &dset_tid) < 0) + if (H5VL_dataset_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, H5I_INVALID_HID, "unable to get datatype from the dataset") + dset_tid = vol_cb_args.args.get_type.type_id; /* Unwrap the type ID */ if (NULL == (dt = (H5T_t *)H5I_object(dset_tid))) diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index 91801c6..d079e71 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -790,12 +790,19 @@ H5Tget_create_plist(hid_t dtype_id) } /* end if */ /* If the datatype is committed, retrieve further information */ else { - H5VL_object_t *vol_obj = type->vol_obj; + H5VL_object_t * vol_obj = type->vol_obj; + H5VL_datatype_get_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATATYPE_GET_TCPL; + vol_cb_args.args.get_tcpl.tcpl_id = H5I_INVALID_HID; /* Get the property list through the VOL */ - if (H5VL_datatype_get(vol_obj, H5VL_DATATYPE_GET_TCPL, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &ret_value) < 0) + if (H5VL_datatype_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, H5I_INVALID_HID, "can't get object creation info") + + /* Set return value */ + ret_value = vol_cb_args.args.get_tcpl.tcpl_id; } /* end else */ done: @@ -829,15 +836,21 @@ H5Tflush(hid_t type_id) if (!H5T_is_named(dt)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a committed datatype") - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(type_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info") - /* Flush metadata for named datatype */ - if (dt->vol_obj) - if (H5VL_datatype_specific(dt->vol_obj, H5VL_DATATYPE_FLUSH, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, type_id) < 0) + if (dt->vol_obj) { + H5VL_datatype_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up collective metadata if appropriate */ + if (H5CX_set_loc(type_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info") + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATATYPE_FLUSH; + vol_cb_args.args.flush.type_id = type_id; + + if (H5VL_datatype_specific(dt->vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFLUSH, FAIL, "unable to flush datatype") + } done: FUNC_LEAVE_API(ret_value) @@ -870,15 +883,21 @@ H5Trefresh(hid_t type_id) if (!H5T_is_named(dt)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a committed datatype") - /* Set up collective metadata if appropriate */ - if (H5CX_set_loc(type_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info") - /* Refresh the datatype's metadata */ - if (dt->vol_obj) - if (H5VL_datatype_specific(dt->vol_obj, H5VL_DATATYPE_REFRESH, H5P_DATASET_XFER_DEFAULT, - H5_REQUEST_NULL, type_id) < 0) + if (dt->vol_obj) { + H5VL_datatype_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up collective metadata if appropriate */ + if (H5CX_set_loc(type_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't set access property list info") + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATATYPE_REFRESH; + vol_cb_args.args.refresh.type_id = type_id; + + if (H5VL_datatype_specific(dt->vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL, "unable to refresh datatype") + } done: FUNC_LEAVE_API(ret_value) @@ -1222,32 +1241,41 @@ H5T_update_shared(H5T_t *dt) H5T_t * H5T_construct_datatype(H5VL_object_t *vol_obj) { - ssize_t nalloc; - void * buf = NULL; - H5T_t * dt = NULL; /* datatype object from VOL connector */ - H5T_t * ret_value = NULL; + H5T_t * dt = NULL; /* Datatype object from VOL connector */ + H5VL_datatype_get_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t nalloc = 0; /* Size required to store serialized form of datatype */ + void * buf = NULL; /* Buffer to store serialized datatype */ + H5T_t * ret_value = NULL; FUNC_ENTER_NOAPI(NULL) - /* get required buf size for encoding the datatype */ - if (H5VL_datatype_get(vol_obj, H5VL_DATATYPE_GET_BINARY, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &nalloc, NULL, 0) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATATYPE_GET_BINARY_SIZE; + vol_cb_args.args.get_binary_size.size = &nalloc; + + /* Get required buf size for encoding the datatype */ + if (H5VL_datatype_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to get datatype serialized size") - /* allocate buffer to store binary description of the datatype */ - if (NULL == (buf = (void *)H5MM_calloc((size_t)nalloc))) + /* Allocate buffer to store binary description of the datatype */ + if (NULL == (buf = (void *)H5MM_calloc(nalloc))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for datatype") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_DATATYPE_GET_BINARY; + vol_cb_args.args.get_binary.buf = buf; + vol_cb_args.args.get_binary.buf_size = nalloc; + /* get binary description of the datatype */ - if (H5VL_datatype_get(vol_obj, H5VL_DATATYPE_GET_BINARY, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &nalloc, buf, (size_t)nalloc) < 0) + if (H5VL_datatype_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to get serialized datatype") - if (NULL == (dt = H5T_decode((size_t)nalloc, (const unsigned char *)buf))) + /* Construct datatype, from serialized form in buffer */ + if (NULL == (dt = H5T_decode(nalloc, buf))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "can't decode datatype") - dt->vol_obj = vol_obj; + /* Set return value */ ret_value = dt; done: @@ -1407,3 +1435,34 @@ H5T_already_vol_managed(const H5T_t *dt) FUNC_LEAVE_NOAPI(dt->vol_obj != NULL) } /* end H5T_already_vol_managed() */ + +/*------------------------------------------------------------------------- + * Function: H5T_invoke_vol_optional + * + * Purpose: Invokes an optional VOL connector-specific operation on a named datatype + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_invoke_vol_optional(H5T_t *dt, H5VL_optional_args_t *args, hid_t dxpl_id, void **req, + H5VL_object_t **vol_obj_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check that datatype is committed */ + if (!H5T_is_named(dt)) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a committed datatype") + + /* Only invoke callback if VOL object is set for the datatype */ + if (dt->vol_obj) + if (H5VL_datatype_optional_op(dt->vol_obj, args, dxpl_id, req, vol_obj_ptr) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_invoke_vol_optional() */ diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 0c98633..18cbcf1 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -7725,9 +7725,9 @@ herr_t H5T__conv_float_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, SCHAR, float, signed char, SCHAR_MIN, SCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7747,9 +7747,9 @@ herr_t H5T__conv_float_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, UCHAR, float, unsigned char, 0, UCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7769,9 +7769,9 @@ herr_t H5T__conv_double_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, SCHAR, double, signed char, SCHAR_MIN, SCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7791,9 +7791,9 @@ herr_t H5T__conv_double_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, UCHAR, double, unsigned char, 0, UCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7813,9 +7813,9 @@ herr_t H5T__conv_ldouble_schar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, SCHAR, long double, signed char, SCHAR_MIN, SCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7835,9 +7835,9 @@ herr_t H5T__conv_ldouble_uchar(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, UCHAR, long double, unsigned char, 0, UCHAR_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7857,9 +7857,9 @@ herr_t H5T__conv_float_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, SHORT, float, short, SHRT_MIN, SHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7879,9 +7879,9 @@ herr_t H5T__conv_float_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, USHORT, float, unsigned short, 0, USHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7901,9 +7901,9 @@ herr_t H5T__conv_double_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, SHORT, double, short, SHRT_MIN, SHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7923,9 +7923,9 @@ herr_t H5T__conv_double_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, USHORT, double, unsigned short, 0, USHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7945,9 +7945,9 @@ herr_t H5T__conv_ldouble_short(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, SHORT, long double, short, SHRT_MIN, SHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7967,9 +7967,9 @@ herr_t H5T__conv_ldouble_ushort(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, USHORT, long double, unsigned short, 0, USHRT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -7989,9 +7989,9 @@ herr_t H5T__conv_float_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, INT, float, int, INT_MIN, INT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8011,9 +8011,9 @@ herr_t H5T__conv_float_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, UINT, float, unsigned int, 0, UINT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8033,9 +8033,9 @@ herr_t H5T__conv_double_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, INT, double, int, INT_MIN, INT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8055,9 +8055,9 @@ herr_t H5T__conv_double_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, UINT, double, unsigned int, 0, UINT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8077,9 +8077,9 @@ herr_t H5T__conv_ldouble_int(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, INT, long double, int, INT_MIN, INT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8099,9 +8099,9 @@ herr_t H5T__conv_ldouble_uint(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, UINT, long double, unsigned int, 0, UINT_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8121,9 +8121,9 @@ herr_t H5T__conv_float_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, LONG, float, long, LONG_MIN, LONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8143,9 +8143,9 @@ herr_t H5T__conv_float_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, ULONG, float, unsigned long, 0, ULONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8165,9 +8165,9 @@ herr_t H5T__conv_double_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, LONG, double, long, LONG_MIN, LONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8187,9 +8187,9 @@ herr_t H5T__conv_double_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, ULONG, double, unsigned long, 0, ULONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8209,9 +8209,9 @@ herr_t H5T__conv_ldouble_long(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, LONG, long double, long, LONG_MIN, LONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8231,9 +8231,9 @@ herr_t H5T__conv_ldouble_ulong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, ULONG, long double, unsigned long, 0, ULONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8253,9 +8253,9 @@ herr_t H5T__conv_float_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, LLONG, float, long long, LLONG_MIN, LLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8275,9 +8275,9 @@ herr_t H5T__conv_float_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(FLOAT, ULLONG, float, unsigned long long, 0, ULLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8297,9 +8297,9 @@ herr_t H5T__conv_double_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, LLONG, double, long long, LLONG_MIN, LLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8319,9 +8319,9 @@ herr_t H5T__conv_double_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(DOUBLE, ULLONG, double, unsigned long long, 0, ULLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } /*------------------------------------------------------------------------- @@ -8342,9 +8342,9 @@ herr_t H5T__conv_ldouble_llong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, LLONG, long double, long long, LLONG_MIN, LLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } #endif /*H5T_CONV_INTERNAL_LDOUBLE_LLONG*/ @@ -8366,9 +8366,9 @@ herr_t H5T__conv_ldouble_ullong(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t H5_ATTR_UNUSED bkg_stride, void *buf, void H5_ATTR_UNUSED *bkg) { - H5_GCC_DIAG_OFF("float-equal") + H5_GCC_CLANG_DIAG_OFF("float-equal") H5T_CONV_Fx(LDOUBLE, ULLONG, long double, unsigned long long, 0, ULLONG_MAX); - H5_GCC_DIAG_ON("float-equal") + H5_GCC_CLANG_DIAG_ON("float-equal") } #endif /*H5T_CONV_INTERNAL_LDOUBLE_ULLONG*/ diff --git a/src/H5Tmodule.h b/src/H5Tmodule.h index c489edc..73424fb 100644 --- a/src/H5Tmodule.h +++ b/src/H5Tmodule.h @@ -29,10 +29,38 @@ #define H5_MY_PKG_ERR H5E_DATATYPE #define H5_MY_PKG_INIT YES -/** - * \defgroup H5T H5T - * \brief Datatype Interface - * \todo Describe concisely what the functions in this module are about. +/**\defgroup H5T H5T + * + * Use the functions in this module to manage HDF5 datatypes. + * + * HDF5 datatypes describe the element type of HDF5 datasets and attributes. + * There's a large set of predefined datatypes, but users may find it useful + * to define new datatypes through a process called \Emph{derivation}. + * + * The element type is automatically persisted as part of the HDF5 metadata of + * attributes and datasets. Additionally, datatype definitions can be persisted + * to HDF5 files and linked to groups as HDF5 datatype objects or so-called + * \Emph{committed datatypes}. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5T_examples.c create + * </td> + * <td> + * \snippet{lineno} H5T_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5T_examples.c update + * </td> + * <td> + * \snippet{lineno} H5T_examples.c delete + * </td> + * </tr> + * </table> * * \defgroup ARRAY Array Datatypes * \ingroup H5T diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 2a45e17..6624096 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -59,10 +59,7 @@ typedef struct H5T_path_t H5T_path_t; struct H5S_t; /* How to copy a datatype */ -typedef enum H5T_copy_t { - H5T_COPY_TRANSIENT, - H5T_COPY_ALL, -} H5T_copy_t; +typedef enum H5T_copy_t { H5T_COPY_TRANSIENT, H5T_COPY_ALL } H5T_copy_t; /* Location of datatype information */ typedef enum { @@ -155,6 +152,8 @@ H5_DLL herr_t H5T_save_refresh_state(hid_t tid, struct H5O_shared_t *cached_H5O H5_DLL herr_t H5T_restore_refresh_state(hid_t tid, struct H5O_shared_t *cached_H5O_shared); H5_DLL hbool_t H5T_already_vol_managed(const H5T_t *dt); H5_DLL htri_t H5T_is_vl_storage(const H5T_t *dt); +H5_DLL herr_t H5T_invoke_vol_optional(H5T_t *dt, H5VL_optional_args_t *args, hid_t dxpl_id, void **req, + H5VL_object_t **vol_obj_ptr); /* Reference specific functions */ H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt); diff --git a/src/H5Tref.c b/src/H5Tref.c index 1114c25..cac8cf6 100644 --- a/src/H5Tref.c +++ b/src/H5Tref.c @@ -289,12 +289,16 @@ H5T__ref_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) } /* end else-if */ else { H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ size_t ref_encode_size; H5R_ref_priv_t fixed_ref; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get(file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &cont_info) < 0) + if (H5VL_file_get(file, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get container info") /* Retrieve min encode size (when references have no vlen part) */ @@ -434,8 +438,10 @@ H5T__ref_mem_getsize(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf /* Force re-calculating encoding size if any flags are set */ if (flags || !src_ref->encode_size) { - char file_name_buf_static[256]; /* File name */ - ssize_t file_name_len; /* Size of file name buffer */ + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + char * file_name = NULL; /* Actual file name */ + char file_name_buf_static[256]; /* File name */ + size_t file_name_len = 0; /* Length of file name */ /* Pass the correct encoding version for the selection depending on the * file libver bounds, this is later retrieved in H5S hyper encode */ @@ -458,21 +464,38 @@ H5T__ref_mem_getsize(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf H5CX_set_libver_bounds(NULL); } /* end if */ + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_NAME; + vol_cb_args.args.get_name.type = H5I_FILE; + vol_cb_args.args.get_name.buf_size = sizeof(file_name_buf_static); + vol_cb_args.args.get_name.buf = file_name_buf_static; + vol_cb_args.args.get_name.file_name_len = &file_name_len; + /* Get file name */ - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, NULL, H5I_FILE, - sizeof(file_name_buf_static), file_name_buf_static, &file_name_len) < 0) + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name") - if (file_name_len >= (ssize_t)sizeof(file_name_buf_static)) { - if (NULL == (file_name_buf_dyn = (char *)H5MM_malloc((size_t)file_name_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, 0, "can't allocate space for file name") - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, NULL, H5I_FILE, - (size_t)file_name_len + 1, file_name_buf_dyn, &file_name_len) < 0) + + /* Check if we need to allocate a buffer for the file name */ + if (file_name_len >= sizeof(file_name_buf_static)) { + /* Allocate file name buffer */ + if (NULL == (file_name_buf_dyn = H5MM_malloc(file_name_len + 1))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, 0, "can't allocate space for file name") + + /* Update VOL callback arguments */ + vol_cb_args.args.get_name.buf_size = file_name_len + 1; + vol_cb_args.args.get_name.buf = file_name_buf_dyn; + + /* Get file name again */ + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name") + + file_name = file_name_buf_dyn; } /* end if */ + else + file_name = file_name_buf_static; /* Determine encoding size */ - if (H5R__encode(file_name_buf_dyn ? file_name_buf_dyn : file_name_buf_static, src_ref, NULL, - &ret_value, flags) < 0) + if (H5R__encode(file_name, src_ref, NULL, &ret_value, flags) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, 0, "unable to determine encoding size") } /* end if */ else { @@ -506,10 +529,10 @@ H5T__ref_mem_read(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, s H5VL_object_t * vol_obj; /* VOL object for src ref's location */ const H5R_ref_priv_t *src_ref = (const H5R_ref_priv_t *)src_buf; hbool_t files_equal = TRUE; /* Whether src & dst references are in same file */ + char * file_name = NULL; /* Actual file name */ char file_name_buf_static[256] = {'\0'}; /* File name */ char * file_name_buf_dyn = NULL; /* Pointer to dynamically allocated buffer for file name, if static buffer is too small */ - ssize_t file_name_len; /* Size of file name buffer */ unsigned flags = 0; /* References flags */ herr_t ret_value = SUCCEED; /* Return value */ @@ -560,21 +583,42 @@ H5T__ref_mem_read(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, s /* Get file name (if external reference) */ if (flags) { - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, NULL, H5I_FILE, - sizeof(file_name_buf_static), file_name_buf_static, &file_name_len) < 0) + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t file_name_len = 0; /* Length of file name */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_NAME; + vol_cb_args.args.get_name.type = H5I_FILE; + vol_cb_args.args.get_name.buf_size = sizeof(file_name_buf_static); + vol_cb_args.args.get_name.buf = file_name_buf_static; + vol_cb_args.args.get_name.file_name_len = &file_name_len; + + /* Get file name */ + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name") - if (file_name_len >= (ssize_t)sizeof(file_name_buf_static)) { - if (NULL == (file_name_buf_dyn = (char *)H5MM_malloc((size_t)file_name_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, 0, "can't allocate space for file name") - if (H5VL_file_get(vol_obj, H5VL_FILE_GET_NAME, H5P_DATASET_XFER_DEFAULT, NULL, H5I_FILE, - (size_t)file_name_len + 1, file_name_buf_dyn, &file_name_len) < 0) + + /* Check if we need to allocate a buffer for the file name */ + if (file_name_len >= sizeof(file_name_buf_static)) { + /* Allocate file name buffer */ + if (NULL == (file_name_buf_dyn = H5MM_malloc(file_name_len + 1))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, 0, "can't allocate space for file name") + + /* Update VOL callback arguments */ + vol_cb_args.args.get_name.buf_size = file_name_len + 1; + vol_cb_args.args.get_name.buf = file_name_buf_dyn; + + /* Get file name again */ + if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name") + + file_name = file_name_buf_dyn; } /* end if */ - } /* end if */ + else + file_name = file_name_buf_static; + } /* end if */ /* Encode reference */ - if (H5R__encode(file_name_buf_dyn ? file_name_buf_dyn : file_name_buf_static, src_ref, - (unsigned char *)dst_buf, &dst_size, flags) < 0) + if (H5R__encode(file_name, src_ref, (unsigned char *)dst_buf, &dst_size, flags) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "Cannot encode reference") done: @@ -731,11 +775,17 @@ H5T__ref_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, hbool_t *isnull = FALSE; } else { + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + /* Skip the size / header */ p = (const uint8_t *)src_buf + H5R_ENCODE_HEADER_SIZE + H5_SIZEOF_UINT32_T; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_ISNULL; + vol_cb_args.args.is_null.isnull = isnull; + /* Check if blob ID is "nil" */ - if (H5VL_blob_specific(src_file, (void *)p, H5VL_BLOB_ISNULL, isnull) < 0) + if (H5VL_blob_specific(src_file, (void *)p, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to check if a blob ID is 'nil'") } @@ -755,9 +805,10 @@ done: static herr_t H5T__ref_disk_setnull(H5VL_object_t *dst_file, void *dst_buf, void *bg_buf) { - uint8_t *q = (uint8_t *)dst_buf; - uint8_t *p_bg = (uint8_t *)bg_buf; - herr_t ret_value = SUCCEED; + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + uint8_t * q = (uint8_t *)dst_buf; + uint8_t * p_bg = (uint8_t *)bg_buf; + herr_t ret_value = SUCCEED; FUNC_ENTER_STATIC H5T_REF_LOG_DEBUG(""); @@ -770,8 +821,11 @@ H5T__ref_disk_setnull(H5VL_object_t *dst_file, void *dst_buf, void *bg_buf) /* Skip the size / header */ p_bg += (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_DELETE; + /* Remove blob for old data */ - if (H5VL_blob_specific(dst_file, (void *)p_bg, H5VL_BLOB_DELETE) < 0) + if (H5VL_blob_specific(dst_file, (void *)p_bg, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") } /* end if */ @@ -782,8 +836,11 @@ H5T__ref_disk_setnull(H5VL_object_t *dst_file, void *dst_buf, void *bg_buf) /* Set the size */ UINT32ENCODE(q, 0); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_SETNULL; + /* Set blob ID to "nil" */ - if (H5VL_blob_specific(dst_file, q, H5VL_BLOB_SETNULL) < 0) + if (H5VL_blob_specific(dst_file, q, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set a blob ID to 'nil'") done: @@ -913,15 +970,19 @@ H5T__ref_disk_write(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, /* TODO Should get rid of bg stuff */ if (p_bg) { - size_t p_buf_size_left = dst_size; + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + size_t p_buf_size_left = dst_size; /* Skip the size / header */ p_bg += (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE); HDassert(p_buf_size_left > (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE)); p_buf_size_left -= (H5_SIZEOF_UINT32_T + H5R_ENCODE_HEADER_SIZE); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_DELETE; + /* Remove blob for old data */ - if (H5VL_blob_specific(dst_file, (void *)p_bg, H5VL_BLOB_DELETE) < 0) + if (H5VL_blob_specific(dst_file, (void *)p_bg, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") } /* end if */ diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index 39d14f3..080d725 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -247,8 +247,7 @@ done: htri_t H5T__vlen_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) { - H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; - htri_t ret_value = FALSE; /* Indicate success, but no location change */ + htri_t ret_value = FALSE; /* Indicate success, but no location change */ FUNC_ENTER_PACKAGE @@ -293,15 +292,22 @@ H5T__vlen_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) dt->shared->u.vlen.file = NULL; break; - case H5T_LOC_DISK: /* Disk based VL datatype */ + /* Disk based VL datatype */ + case H5T_LOC_DISK: { + H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; + H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ + HDassert(file); /* Mark this type as being stored on disk */ dt->shared->u.vlen.loc = H5T_LOC_DISK; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; + vol_cb_args.args.get_cont_info.info = &cont_info; + /* Get container info */ - if (H5VL_file_get(file, H5VL_FILE_GET_CONT_INFO, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - &cont_info) < 0) + if (H5VL_file_get(file, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get container info") /* The datatype size is equal to 4 bytes for the sequence length @@ -319,6 +325,7 @@ H5T__vlen_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) if (H5T_own_vol_obj(dt, file) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't give ownership of VOL object") break; + } case H5T_LOC_BADLOC: /* Allow undefined location. In H5Odtype.c, H5O_dtype_decode sets undefined @@ -841,8 +848,9 @@ H5T__vlen_disk_getlen(H5VL_object_t H5_ATTR_UNUSED *file, const void *_vl, size_ static herr_t H5T__vlen_disk_isnull(const H5VL_object_t *file, void *_vl, hbool_t *isnull) { - uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + uint8_t * vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -854,8 +862,12 @@ H5T__vlen_disk_isnull(const H5VL_object_t *file, void *_vl, hbool_t *isnull) /* Skip the sequence's length */ vl += 4; + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_ISNULL; + vol_cb_args.args.is_null.isnull = isnull; + /* Check if blob ID is "nil" */ - if (H5VL_blob_specific(file, vl, H5VL_BLOB_ISNULL, isnull) < 0) + if (H5VL_blob_specific(file, vl, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to check if a blob ID is 'nil'") done: @@ -877,8 +889,9 @@ done: static herr_t H5T__vlen_disk_setnull(H5VL_object_t *file, void *_vl, void *bg) { - uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + uint8_t * vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -895,8 +908,11 @@ H5T__vlen_disk_setnull(H5VL_object_t *file, void *_vl, void *bg) /* Set the length of the sequence */ UINT32ENCODE(vl, 0); + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_SETNULL; + /* Set blob ID to "nil" */ - if (H5VL_blob_specific(file, vl, H5VL_BLOB_SETNULL) < 0) + if (H5VL_blob_specific(file, vl, &vol_cb_args) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set a blob ID to 'nil'") done: @@ -1013,10 +1029,16 @@ H5T__vlen_disk_delete(H5VL_object_t *file, const void *_vl) UINT32DECODE(vl, seq_len); /* Delete object, if length > 0 */ - if (seq_len > 0) - if (H5VL_blob_specific(file, (void *)vl, H5VL_BLOB_DELETE) < 0) /* Casting away 'const' OK -QAK */ + if (seq_len > 0) { + H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_BLOB_DELETE; + + if (H5VL_blob_specific(file, (void *)vl, &vol_cb_args) < 0) /* Casting away 'const' OK -QAK */ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") - } /* end if */ + } /* end if */ + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5VL.c b/src/H5VL.c index a77a6f3..2cece6d 100644 --- a/src/H5VL.c +++ b/src/H5VL.c @@ -764,6 +764,39 @@ done: } /* H5VLretrieve_lib_state() */ /*--------------------------------------------------------------------------- + * Function: H5VLstart_lib_state + * + * Purpose: Opens a new internal state for the HDF5 library. + * + * Note: This routine is _only_ for HDF5 VOL connector authors! It is + * _not_ part of the public API for HDF5 application developers. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Friday, February 5, 2021 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLstart_lib_state(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ + FUNC_ENTER_API_NOINIT + H5TRACE0("e", ""); + + /* Start a new library state */ + if (H5VL_start_lib_state() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't start new library state") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* H5VLstart_lib_state() */ + +/*--------------------------------------------------------------------------- * Function: H5VLrestore_lib_state * * Purpose: Restores the internal state of the HDF5 library. @@ -801,16 +834,16 @@ done: } /* H5VLrestore_lib_state() */ /*--------------------------------------------------------------------------- - * Function: H5VLreset_lib_state + * Function: H5VLfinish_lib_state * - * Purpose: Resets the internal state of the HDF5 library, undoing the - * affects of H5VLrestore_lib_state. + * Purpose: Closes the internal state of the HDF5 library, undoing the + * affects of H5VLstart_lib_state. * * Note: This routine is _only_ for HDF5 VOL connector authors! It is * _not_ part of the public API for HDF5 application developers. * * Note: This routine must be called as a "pair" with - * H5VLrestore_lib_state. It can be called before / after / + * H5VLstart_lib_state. It can be called before / after / * independently of H5VLfree_lib_state. * * Return: Success: Non-negative @@ -822,7 +855,7 @@ done: *--------------------------------------------------------------------------- */ herr_t -H5VLreset_lib_state(void) +H5VLfinish_lib_state(void) { herr_t ret_value = SUCCEED; /* Return value */ @@ -831,12 +864,12 @@ H5VLreset_lib_state(void) H5TRACE0("e", ""); /* Reset the library state */ - if (H5VL_reset_lib_state() < 0) + if (H5VL_finish_lib_state() < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset library state") done: FUNC_LEAVE_API_NOINIT(ret_value) -} /* H5VLreset_lib_state() */ +} /* H5VLfinish_lib_state() */ /*--------------------------------------------------------------------------- * Function: H5VLfree_lib_state @@ -911,3 +944,136 @@ H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_type, uint64_t done: FUNC_LEAVE_API(ret_value) } /* H5VLquery_optional() */ + +/*--------------------------------------------------------------------------- + * Function: H5VLregister_opt_operation + * + * Purpose: Allow a VOL connector to register a new optional operation + * for a VOL object subclass. The operation name must be runtime + * unique for each operation, preferably avoiding naming clashes + * by using a Uniform Type Identifier (UTI, + *https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html) + * for each operation name. The value returned in the 'op_val' + * pointer will be unique for that VOL connector to use for its + * operation on that subclass. + * + * For example, registering a 'prefetch' operation for the + * caching VOL connector written at the ALCF at Argonne National + * Laboratory could have a UTI of: "gov.anl.alcf.cache.prefetch", + * and the "evict" operation for the same connector could have a + * UTI of: "gov.anl.alcf.cache.evict". Registering a "suspend + * background threads" operation for the asynchronous VOL connector + * written at NERSC at Lawrence Berkeley National Laboratory could + * have a UTI of: "gov.lbnl.nersc.async.suspend_bkg_threads". + * + * Note: The first 1024 values of each subclass's optional operations + * are reserved for the native VOL connector's use. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLregister_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "VS*sx", subcls, op_name, op_val); + + /* Check args */ + if (NULL == op_val) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer") + if (NULL == op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer") + if ('\0' == *op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string") + if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || + (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || + (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type") + + /* Register the operation */ + if (H5VL__register_opt_operation(subcls, op_name, op_val) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, FAIL, "can't register dynamic optional operation: '%s'", + op_name) + +done: + FUNC_LEAVE_API(ret_value) +} /* H5VLregister_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VLfind_opt_operation + * + * Purpose: Look up a optional operation for a VOL object subclass, by name. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLfind_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "VS*sx", subcls, op_name, op_val); + + /* Check args */ + if (NULL == op_val) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer") + if (NULL == op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer") + if ('\0' == *op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string") + if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || + (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || + (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type") + + /* Find the operation */ + if (H5VL__find_opt_operation(subcls, op_name, op_val) < 0) + HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "can't find dynamic optional operation: '%s'", op_name) + +done: + FUNC_LEAVE_API(ret_value) +} /* H5VLfind_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VLunregister_opt_operation + * + * Purpose: Unregister a optional operation for a VOL object subclass, by name. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VLunregister_opt_operation(H5VL_subclass_t subcls, const char *op_name) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "VS*s", subcls, op_name); + + /* Check args */ + if (NULL == op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer") + if ('\0' == *op_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string") + if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || + (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || + (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type") + + /* Unregister the operation */ + if (H5VL__unregister_opt_operation(subcls, op_name) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "can't unregister dynamic optional operation: '%s'", + op_name) + +done: + FUNC_LEAVE_API(ret_value) +} /* H5VLunregister_opt_operation() */ diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 80134a7..fcab19f 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -29,11 +29,13 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ +#include "H5ESprivate.h" /* Event Sets */ #include "H5Fprivate.h" /* File access */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ #include "H5PLprivate.h" /* Plugins */ +#include "H5Tprivate.h" /* Datatypes */ #include "H5VLpkg.h" /* Virtual Object Layer */ /****************/ @@ -54,6 +56,10 @@ typedef struct H5VL_file_open_find_connector_t { hid_t fapl_id; } H5VL_file_open_find_connector_t; +/* Typedef for common callback form of registered optional operations */ +typedef herr_t (*H5VL_reg_opt_oper_t)(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); + /********************/ /* Package Typedefs */ /********************/ @@ -70,13 +76,12 @@ static herr_t H5VL__attr_read(void *obj, const H5VL_class_t *cls, hid_t mem_type void **req); static herr_t H5VL__attr_write(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, const void *buf, hid_t dxpl_id, void **req); -static herr_t H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); +static herr_t H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL__attr_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_attr_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); static herr_t H5VL__attr_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req); static void * H5VL__dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name, hid_t lcpl_id, hid_t type_id, hid_t space_id, @@ -87,26 +92,24 @@ static herr_t H5VL__dataset_read(void *dset, const H5VL_class_t *cls, hid_t mem_ hid_t file_space_id, hid_t dxpl_id, void *buf, void **req); static herr_t H5VL__dataset_write(void *obj, const H5VL_class_t *cls, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf, void **req); -static herr_t H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, - H5VL_dataset_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_dataset_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, H5VL_dataset_specific_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); static herr_t H5VL__dataset_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req); static void * H5VL__datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, void **req); static void * H5VL__datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); -static herr_t H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, - H5VL_datatype_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_datatype_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, H5VL_datatype_specific_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); static herr_t H5VL__datatype_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req); static void * H5VL__file_create(const H5VL_class_t *cls, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req); @@ -114,28 +117,28 @@ static void * H5VL__file_open(const H5VL_class_t *cls, const char *name, unsigne hid_t dxpl_id, void **req); static herr_t H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_info, void *op_data); -static herr_t H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_file_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); static herr_t H5VL__file_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req); static void * H5VL__group_create(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req); static void * H5VL__group_open(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); -static herr_t H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_group_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); static herr_t H5VL__group_close(void *obj, const H5VL_class_t *cls, hid_t dxpl_id, void **req); -static herr_t H5VL__link_create(H5VL_link_create_type_t create_type, void *obj, - const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, hid_t lcpl_id, - hid_t lapl_id, hid_t dxpl_id, void **req, va_list arguments); +static herr_t H5VL__link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, + void **req); static herr_t H5VL__link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); @@ -143,12 +146,11 @@ static herr_t H5VL__link_move(void *src_obj, const H5VL_loc_params_t *loc_params const H5VL_loc_params_t *loc_params2, const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); static herr_t H5VL__link_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL__link_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL__link_optional(void *obj, const H5VL_class_t *cls, H5VL_link_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL__link_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); static void * H5VL__object_open(void *obj, const H5VL_loc_params_t *params, const H5VL_class_t *cls, H5I_type_t *opened_type, hid_t dxpl_id, void **req); static herr_t H5VL__object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_params, const char *src_name, @@ -156,12 +158,11 @@ static herr_t H5VL__object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_ const H5VL_class_t *cls, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); static herr_t H5VL__object_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL__object_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL__object_optional(void *obj, const H5VL_class_t *cls, H5VL_object_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL__object_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL__introspect_get_conn_cls(void *obj, const H5VL_class_t *cls, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); static herr_t H5VL__introspect_opt_query(void *obj, const H5VL_class_t *cls, H5VL_subclass_t subcls, @@ -170,27 +171,25 @@ static herr_t H5VL__request_wait(void *req, const H5VL_class_t *cls, uint64_t ti H5VL_request_status_t *status); static herr_t H5VL__request_notify(void *req, const H5VL_class_t *cls, H5VL_request_notify_t cb, void *ctx); static herr_t H5VL__request_cancel(void *req, const H5VL_class_t *cls, H5VL_request_status_t *status); -static herr_t H5VL__request_specific(void *req, const H5VL_class_t *cls, - H5VL_request_specific_t specific_type, va_list arguments); -static herr_t H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_request_optional_t opt_type, - va_list arguments); +static herr_t H5VL__request_specific(void *req, const H5VL_class_t *cls, H5VL_request_specific_args_t *args); +static herr_t H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_optional_args_t *args); static herr_t H5VL__request_free(void *req, const H5VL_class_t *cls); static herr_t H5VL__blob_put(void *obj, const H5VL_class_t *cls, const void *buf, size_t size, void *blob_id, void *ctx); static herr_t H5VL__blob_get(void *obj, const H5VL_class_t *cls, const void *blob_id, void *buf, size_t size, void *ctx); static herr_t H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, - H5VL_blob_specific_t specific_type, va_list arguments); + H5VL_blob_specific_args_t *args); static herr_t H5VL__blob_optional(void *obj, const H5VL_class_t *cls, void *blob_id, - H5VL_blob_optional_t opt_type, va_list arguments); + H5VL_optional_args_t *args); static herr_t H5VL__token_cmp(void *obj, const H5VL_class_t *cls, const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value); static herr_t H5VL__token_to_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls, const H5O_token_t *token, char **token_str); static herr_t H5VL__token_from_str(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls, const char *token_str, H5O_token_t *token); -static herr_t H5VL__optional(void *obj, const H5VL_class_t *cls, int op_type, hid_t dxpl_id, void **req, - va_list arguments); +static herr_t H5VL__optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); /*********************/ /* Package Variables */ @@ -329,6 +328,50 @@ done: } /* H5VLget_value */ /*------------------------------------------------------------------------- + * Function: H5VL__common_optional_op + * + * Purpose: Performs an optional connector-specific operation on an object + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__common_optional_op(hid_t id, H5I_type_t id_type, H5VL_reg_opt_oper_t reg_opt_op, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req, H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for id */ + H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for id */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check ID type & get VOL object */ + if (NULL == (*vol_obj_ptr = (H5VL_object_t *)H5I_object_verify(id, id_type))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid identifier") + + /* Set wrapper info in API context */ + if (H5VL_set_vol_wrapper(*vol_obj_ptr) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + /* (Must return value from callback, for iterators) */ + if ((ret_value = + (*reg_opt_op)((*vol_obj_ptr)->data, (*vol_obj_ptr)->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback"); + +done: + /* Reset object wrapping info in API context */ + if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__common_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL_copy_connector_info * * Purpose: Copy the VOL info for a connector @@ -1341,8 +1384,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1353,7 +1395,7 @@ H5VL__attr_get(void *obj, const H5VL_class_t *cls, H5VL_attr_get_t get_type, hid HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr get' method") /* Call the corresponding VOL callback */ - if ((cls->attr_cls.get)(obj, get_type, dxpl_id, req, arguments) < 0) + if ((cls->attr_cls.get)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "attribute get failed") done: @@ -1371,10 +1413,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_attr_get(const H5VL_object_t *vol_obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, ...) +H5VL_attr_get(const H5VL_object_t *vol_obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1386,16 +1426,10 @@ H5VL_attr_get(const H5VL_object_t *vol_obj, H5VL_attr_get_t get_type, hid_t dxpl vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__attr_get(vol_obj->data, vol_obj->connector->cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__attr_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "attribute get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -1414,23 +1448,24 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req /*out*/, - va_list arguments) +H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVaixx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + if (NULL == args) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument struct") /* Call the corresponding internal VOL routine */ - if (H5VL__attr_get(obj, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__attr_get(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to get attribute information") done: @@ -1449,7 +1484,7 @@ done: */ static herr_t H5VL__attr_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1460,8 +1495,9 @@ H5VL__attr_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_c HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr specific' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->attr_cls.specific)(obj, loc_params, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->attr_cls.specific)(obj, loc_params, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute 'specific' callback"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1479,10 +1515,8 @@ done: */ herr_t H5VL_attr_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, ...) + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1494,17 +1528,12 @@ H5VL_attr_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_pa vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = H5VL__attr_specific(vol_obj->data, loc_params, vol_obj->connector->cls, specific_type, - dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = + H5VL__attr_specific(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute 'specific' callback"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -1524,13 +1553,13 @@ done: */ herr_t H5VLattr_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVbixx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -1539,8 +1568,9 @@ H5VLattr_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connecto HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__attr_specific(obj, loc_params, cls, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__attr_specific(obj, loc_params, cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute 'specific' callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) @@ -1557,8 +1587,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_attr_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -1569,8 +1598,9 @@ H5VL__attr_optional(void *obj, const H5VL_class_t *cls, H5VL_attr_optional_t opt HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'attr optional' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->attr_cls.optional)(obj, opt_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->attr_cls.optional)(obj, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute optional callback"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1587,11 +1617,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_attr_optional(const H5VL_object_t *vol_obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, void **req, - ...) +H5VL_attr_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1603,17 +1630,11 @@ H5VL_attr_optional(const H5VL_object_t *vol_obj, H5VL_attr_optional_t opt_type, vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = H5VL__attr_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, - arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__attr_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute optional callback"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -1632,14 +1653,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLattr_optional(void *obj, hid_t connector_id, H5VL_attr_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLattr_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVsixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -1648,14 +1669,58 @@ H5VLattr_optional(void *obj, hid_t connector_id, H5VL_attr_optional_t opt_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__attr_optional(obj, cls, opt_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__attr_optional(obj, cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute attribute optional callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) } /* end H5VLattr_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLattr_optional_op + * + * Purpose: Performs an optional connector-specific operation on an attribute + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLattr_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t attr_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Attribute VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*!ii", app_file, app_func, app_line, attr_id, args, dxpl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Call the common VOL connector optional routine */ + if ((ret_value = H5VL__common_optional_op(attr_id, H5I_ATTR, H5VL__attr_optional, args, dxpl_id, + token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute attribute optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, attr_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLattr_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__attr_close * * Purpose: Closes an attribute through the VOL @@ -2169,8 +2234,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2181,7 +2246,7 @@ H5VL__dataset_get(void *obj, const H5VL_class_t *cls, H5VL_dataset_get_t get_typ HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset get' method") /* Call the corresponding VOL callback */ - if ((cls->dataset_cls.get)(obj, get_type, dxpl_id, req, arguments) < 0) + if ((cls->dataset_cls.get)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "dataset get failed") done: @@ -2199,10 +2264,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, ...) +H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2214,16 +2277,10 @@ H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_t get_type, hid_ vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__dataset_get(vol_obj->data, vol_obj->connector->cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__dataset_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "dataset get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -2242,14 +2299,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdataset_get(void *obj, hid_t connector_id, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req /*out*/, - va_list arguments) +H5VLdataset_get(void *obj, hid_t connector_id, H5VL_dataset_get_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVcixx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2258,7 +2315,7 @@ H5VLdataset_get(void *obj, hid_t connector_id, H5VL_dataset_get_t get_type, hid_ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__dataset_get(obj, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__dataset_get(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute dataset get callback") done: @@ -2276,8 +2333,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, H5VL_dataset_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments) +H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2288,7 +2345,7 @@ H5VL__dataset_specific(void *obj, const H5VL_class_t *cls, H5VL_dataset_specific HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset specific' method") /* Call the corresponding VOL callback */ - if ((cls->dataset_cls.specific)(obj, specific_type, dxpl_id, req, arguments) < 0) + if ((cls->dataset_cls.specific)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset specific callback") done: @@ -2306,11 +2363,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_dataset_specific(const H5VL_object_t *vol_obj, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, - void **req, ...) +H5VL_dataset_specific(const H5VL_object_t *vol_obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, + void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2322,17 +2377,10 @@ H5VL_dataset_specific(const H5VL_object_t *vol_obj, H5VL_dataset_specific_t spec vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__dataset_specific(vol_obj->data, vol_obj->connector->cls, specific_type, dxpl_id, req, - arguments) < 0) + if (H5VL__dataset_specific(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset specific callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -2351,14 +2399,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVdixx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2367,7 +2415,7 @@ H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_t spec HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__dataset_specific(obj, cls, specific_type, dxpl_id, req, arguments) < 0) + if (H5VL__dataset_specific(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset specific callback") done: @@ -2385,8 +2433,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2397,7 +2445,7 @@ H5VL__dataset_optional(void *obj, const H5VL_class_t *cls, H5VL_dataset_optional HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'dataset optional' method") /* Call the corresponding VOL callback */ - if ((cls->dataset_cls.optional)(obj, opt_type, dxpl_id, req, arguments) < 0) + if ((cls->dataset_cls.optional)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback") done: @@ -2415,11 +2463,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_dataset_optional(const H5VL_object_t *vol_obj, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, - void **req, ...) +H5VL_dataset_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2431,16 +2476,10 @@ H5VL_dataset_optional(const H5VL_object_t *vol_obj, H5VL_dataset_optional_t opt_ vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__dataset_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__dataset_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -2459,14 +2498,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVtixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2475,7 +2514,7 @@ H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_dataset_optional_t opt_ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__dataset_optional(obj, cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__dataset_optional(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback") done: @@ -2483,6 +2522,49 @@ done: } /* end H5VLdataset_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLdataset_optional_op + * + * Purpose: Performs an optional connector-specific operation on a dataset + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLdataset_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t dset_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Dataset VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*!ii", app_file, app_func, app_line, dset_id, args, dxpl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Call the corresponding internal VOL routine */ + if (H5VL__common_optional_op(dset_id, H5I_DATASET, H5VL__dataset_optional, args, dxpl_id, token_ptr, + &vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute dataset optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, dset_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdataset_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__dataset_close * * Purpose: Closes a dataset through the VOL @@ -2807,8 +2889,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2819,8 +2901,8 @@ H5VL__datatype_get(void *obj, const H5VL_class_t *cls, H5VL_datatype_get_t get_t HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'datatype get' method") /* Call the corresponding VOL callback */ - if ((cls->datatype_cls.get)(obj, get_type, dxpl_id, req, arguments) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "datatype get failed") + if ((cls->datatype_cls.get)(obj, args, dxpl_id, req) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "datatype 'get' failed") done: FUNC_LEAVE_NOAPI(ret_value) @@ -2837,10 +2919,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_datatype_get(const H5VL_object_t *vol_obj, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, ...) +H5VL_datatype_get(const H5VL_object_t *vol_obj, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2852,16 +2932,10 @@ H5VL_datatype_get(const H5VL_object_t *vol_obj, H5VL_datatype_get_t get_type, hi vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__datatype_get(vol_obj->data, vol_obj->connector->cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__datatype_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "datatype get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -2880,14 +2954,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdatatype_get(void *obj, hid_t connector_id, H5VL_datatype_get_t get_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLdatatype_get(void *obj, hid_t connector_id, H5VL_datatype_get_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVeixx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -2895,12 +2969,8 @@ H5VLdatatype_get(void *obj, hid_t connector_id, H5VL_datatype_get_t get_type, hi if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") - /* Check if the corresponding VOL callback exists */ - if (NULL == cls->datatype_cls.get) - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no `datatype get' method") - /* Call the corresponding internal VOL routine */ - if (H5VL__datatype_get(obj, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__datatype_get(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute datatype get callback") done: @@ -2918,8 +2988,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, H5VL_datatype_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments) +H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, H5VL_datatype_specific_args_t *args, + hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2930,7 +3000,7 @@ H5VL__datatype_specific(void *obj, const H5VL_class_t *cls, H5VL_datatype_specif HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'datatype specific' method") /* Call the corresponding VOL callback */ - if ((cls->datatype_cls.specific)(obj, specific_type, dxpl_id, req, arguments) < 0) + if ((cls->datatype_cls.specific)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype specific callback") done: @@ -2948,11 +3018,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_datatype_specific(const H5VL_object_t *vol_obj, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, - void **req, ...) +H5VL_datatype_specific(const H5VL_object_t *vol_obj, H5VL_datatype_specific_args_t *args, hid_t dxpl_id, + void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2964,17 +3032,10 @@ H5VL_datatype_specific(const H5VL_object_t *vol_obj, H5VL_datatype_specific_t sp vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__datatype_specific(vol_obj->data, vol_obj->connector->cls, specific_type, dxpl_id, req, - arguments) < 0) + if (H5VL__datatype_specific(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype specific callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -2993,14 +3054,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVfixx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -3009,7 +3070,7 @@ H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_t sp HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__datatype_specific(obj, cls, specific_type, dxpl_id, req, arguments) < 0) + if (H5VL__datatype_specific(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype specific callback") done: @@ -3027,8 +3088,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -3039,7 +3100,7 @@ H5VL__datatype_optional(void *obj, const H5VL_class_t *cls, H5VL_datatype_option HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'datatype optional' method") /* Call the corresponding VOL callback */ - if ((cls->datatype_cls.optional)(obj, opt_type, dxpl_id, req, arguments) < 0) + if ((cls->datatype_cls.optional)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback") done: @@ -3057,11 +3118,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_datatype_optional(const H5VL_object_t *vol_obj, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, - void **req, ...) +H5VL_datatype_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -3073,17 +3131,10 @@ H5VL_datatype_optional(const H5VL_object_t *vol_obj, H5VL_datatype_optional_t op vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__datatype_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, arguments) < - 0) + if (H5VL__datatype_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -3092,6 +3143,50 @@ done: } /* end H5VL_datatype_optional() */ /*------------------------------------------------------------------------- + * Function: H5VL_datatype_optional_op + * + * Purpose: Optional operation specific to connectors. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_datatype_optional_op(H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req, + H5VL_object_t **_vol_obj_ptr) +{ + H5VL_object_t * tmp_vol_obj = NULL; /* Object for id */ + H5VL_object_t **vol_obj_ptr = (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for id */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(vol_obj); + + /* Set up vol_obj_ptr */ + *vol_obj_ptr = vol_obj; + + /* Set wrapper info in API context */ + if (H5VL_set_vol_wrapper(*vol_obj_ptr) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + if (H5VL__datatype_optional((*vol_obj_ptr)->data, (*vol_obj_ptr)->connector->cls, args, dxpl_id, req) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback") + +done: + /* Reset object wrapping info in API context */ + if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_datatype_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VLdatatype_optional * * Purpose: Performs an optional connector-specific operation on a datatype @@ -3102,14 +3197,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVuixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -3118,7 +3213,7 @@ H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_datatype_optional_t op HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__datatype_optional(obj, cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__datatype_optional(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute datatype optional callback") done: @@ -3126,6 +3221,53 @@ done: } /* end H5VLdatatype_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLdatatype_optional_op + * + * Purpose: Performs an optional connector-specific operation on a datatype + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLdatatype_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t type_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) +{ + H5T_t * dt; /* Datatype for this operation */ + H5VL_object_t *vol_obj = NULL; /* Datatype VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*!ii", app_file, app_func, app_line, type_id, args, dxpl_id, es_id); + + /* Check args */ + if (NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Only invoke callback if VOL object is set for the datatype */ + if (H5T_invoke_vol_optional(dt, args, dxpl_id, token_ptr, &vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to invoke datatype optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, type_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdatatype_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__datatype_close * * Purpose: Closes a datatype through the VOL @@ -3380,14 +3522,16 @@ static herr_t H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_info, void *op_data) { H5VL_file_open_find_connector_t *udata = (H5VL_file_open_find_connector_t *)op_data; - const H5VL_class_t * cls = (const H5VL_class_t *)plugin_info; + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ + const H5VL_class_t * cls = (const H5VL_class_t *)plugin_info; H5P_genplist_t * fapl_plist; H5P_genplist_t * fapl_plist_copy; + hbool_t is_accessible = FALSE; /* Whether file is accessible */ + ssize_t num_errors = 0; herr_t status; - htri_t is_accessible = FALSE; - hid_t connector_id = H5I_INVALID_HID; - hid_t fapl_id = H5I_INVALID_HID; - herr_t ret_value = H5_ITER_CONT; + hid_t connector_id = H5I_INVALID_HID; + hid_t fapl_id = H5I_INVALID_HID; + herr_t ret_value = H5_ITER_CONT; FUNC_ENTER_STATIC @@ -3416,19 +3560,40 @@ H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_in if (H5P_set_vol(fapl_plist_copy, connector_id, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, H5_ITER_ERROR, "can't set VOL connector on fapl") + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_IS_ACCESSIBLE; + vol_cb_args.args.is_accessible.filename = udata->filename; + vol_cb_args.args.is_accessible.fapl_id = fapl_id; + vol_cb_args.args.is_accessible.accessible = &is_accessible; + + /* Store current error stack size */ + if ((num_errors = H5Eget_num(H5E_DEFAULT)) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, H5_ITER_ERROR, "can't get current error stack size") + /* Check if file is accessible with given VOL connector */ H5E_BEGIN_TRY { - status = H5VL_file_specific(NULL, H5VL_FILE_IS_ACCESSIBLE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, - fapl_id, udata->filename, &is_accessible); + status = H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL); } H5E_END_TRY; - /* If the file was accessible with the current VOL connector, return - * the FAPL with that VOL connector set on it. Errors are ignored here - * as some VOL connectors may not support H5Fis_accessible. - */ - if (status == SUCCEED && is_accessible > 0) { + if (status < 0) { + ssize_t new_num_errors = 0; + + /* Pop any errors generated by the above call */ + if ((new_num_errors = H5Eget_num(H5E_DEFAULT)) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, H5_ITER_ERROR, "can't get current error stack size") + if (new_num_errors > num_errors) { + new_num_errors -= num_errors; + if (H5Epop(H5E_DEFAULT, (size_t)new_num_errors) < 0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTRELEASE, H5_ITER_ERROR, "can't sanitize error stack") + } + } + else if (status == SUCCEED && is_accessible) { + /* If the file was accessible with the current VOL connector, return + * the FAPL with that VOL connector set on it. + */ + /* Modify 'connector_prop' to point to the VOL connector that * was actually used to open the file, rather than the original * VOL connector that was requested. @@ -3438,7 +3603,7 @@ H5VL__file_open_find_connector_cb(H5PL_type_t plugin_type, const void *plugin_in udata->fapl_id = fapl_id; ret_value = H5_ITER_STOP; - } /* end if */ + } done: if (ret_value != H5_ITER_STOP) { @@ -3479,21 +3644,18 @@ H5VL_file_open(H5VL_connector_prop_t *connector_prop, const char *name, unsigned /* Call the corresponding internal VOL routine */ if (NULL == (ret_value = H5VL__file_open(cls, name, flags, fapl_id, dxpl_id, req))) { - H5VL_file_open_find_connector_t find_connector_ud; - hbool_t find_connector; - hbool_t connector_available = FALSE; + hbool_t is_default_conn = TRUE; /* Opening the file failed - Determine whether we should search * the plugin path to see if any other VOL connectors are available - * to attempt to open the file with. This only occurs if no particular - * VOL connector was specified (either via a FAPL or the - * HDF5_VOL_CONNECTOR environment variable). + * to attempt to open the file with. This only occurs if the default + * VOL connector was used for the initial file open attempt. */ - find_connector = !getenv("HDF5_VOL_CONNECTOR") && ((H5P_FILE_ACCESS_DEFAULT == fapl_id) || - connector_prop->connector_id == H5_DEFAULT_VOL); + H5VL__is_default_conn(fapl_id, connector_prop->connector_id, &is_default_conn); - if (find_connector) { - herr_t iter_ret; + if (is_default_conn) { + H5VL_file_open_find_connector_t find_connector_ud; + herr_t iter_ret; find_connector_ud.connector_prop = connector_prop; find_connector_ud.filename = name; @@ -3505,24 +3667,24 @@ H5VL_file_open(H5VL_connector_prop_t *connector_prop, const char *name, unsigned if (iter_ret < 0) HGOTO_ERROR(H5E_VOL, H5E_BADITER, NULL, "failed to iterate over available VOL connector plugins") - else if (iter_ret) - connector_available = TRUE; + else if (iter_ret) { + /* If one of the available VOL connector plugins is + * able to open the file, clear the error stack from any + * previous file open failures and then open the file. + * Otherwise, if no VOL connectors are available, throw + * error from original file open failure. + */ + H5E_clear_stack(NULL); + + if (NULL == (ret_value = H5VL__file_open(find_connector_ud.cls, name, flags, + find_connector_ud.fapl_id, dxpl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, + "can't open file '%s' with VOL connector '%s'", name, + find_connector_ud.cls->name) + } + else + HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "open failed") } /* end if */ - - /* If one of the available VOL connector plugins is - * able to open the file, clear the error stack from any - * previous file open failures and then open the file. - * Otherwise, if no VOL connectors are available, throw - * error from original file open failure. - */ - if (connector_available) { - H5E_clear_stack(NULL); - - if (NULL == (ret_value = H5VL__file_open(find_connector_ud.cls, name, flags, - find_connector_ud.fapl_id, dxpl_id, req))) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "can't open file '%s' with VOL connector '%s'", - name, find_connector_ud.cls->name) - } else HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "open failed") } /* end if */ @@ -3581,8 +3743,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -3593,7 +3754,7 @@ H5VL__file_get(void *obj, const H5VL_class_t *cls, H5VL_file_get_t get_type, hid HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'file get' method") /* Call the corresponding VOL callback */ - if ((cls->file_cls.get)(obj, get_type, dxpl_id, req, arguments) < 0) + if ((cls->file_cls.get)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "file get failed") done: @@ -3611,10 +3772,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, ...) +H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -3626,16 +3785,10 @@ H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_t get_type, hid_t dxpl vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__file_get(vol_obj->data, vol_obj->connector->cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "file get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -3654,14 +3807,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLfile_get(void *obj, hid_t connector_id, H5VL_file_get_t get_type, hid_t dxpl_id, void **req /*out*/, - va_list arguments) +H5VLfile_get(void *obj, hid_t connector_id, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVgixx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -3670,7 +3822,7 @@ H5VLfile_get(void *obj, hid_t connector_id, H5VL_file_get_t get_type, hid_t dxpl HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__file_get(obj, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_get(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute file get callback") done: @@ -3688,8 +3840,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -3700,7 +3852,7 @@ H5VL__file_specific(void *obj, const H5VL_class_t *cls, H5VL_file_specific_t spe HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'file specific' method") /* Call the corresponding VOL callback */ - if ((cls->file_cls.specific)(obj, specific_type, dxpl_id, req, arguments) < 0) + if ((cls->file_cls.specific)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file specific failed") done: @@ -3718,33 +3870,28 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req, ...) +H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_args_t *args, hid_t dxpl_id, void **req) { const H5VL_class_t *cls; /* VOL connector's class struct */ - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - /* Start access to the varargs, so they are available in all situations below */ - HDva_start(arguments, req); - arg_started = TRUE; - /* Special treatment of file access check & delete operations */ /* (Retrieve the VOL connector from the FAPL, since the file isn't open) */ - if (specific_type == H5VL_FILE_IS_ACCESSIBLE || specific_type == H5VL_FILE_DELETE) { + if (args->op_type == H5VL_FILE_IS_ACCESSIBLE || args->op_type == H5VL_FILE_DELETE) { H5P_genplist_t * plist; /* Property list pointer */ H5VL_connector_prop_t connector_prop; /* Property for VOL connector ID & info */ - va_list tmp_args; /* argument list passed from the API call */ hid_t fapl_id; /* File access property list for accessing the file */ /* Get the file access property list to access the file */ - HDva_copy(tmp_args, arguments); - fapl_id = HDva_arg(tmp_args, hid_t); - HDva_end(tmp_args); + if (args->op_type == H5VL_FILE_IS_ACCESSIBLE) + fapl_id = args->args.is_accessible.fapl_id; + else { + HDassert(args->op_type == H5VL_FILE_DELETE); + fapl_id = args->args.del.fapl_id; + } /* Get the VOL info from the FAPL */ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) @@ -3770,14 +3917,10 @@ H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_t specific_t } /* end else */ /* Call the corresponding internal VOL routine */ - if (H5VL__file_specific(vol_obj ? vol_obj->data : NULL, cls, specific_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_specific(vol_obj ? vol_obj->data : NULL, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file specific failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -3798,21 +3941,21 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVhixx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__file_specific(obj, cls, specific_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_specific(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute file specific callback") done: @@ -3830,8 +3973,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_file_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -3842,7 +3984,7 @@ H5VL__file_optional(void *obj, const H5VL_class_t *cls, H5VL_file_optional_t opt HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'file optional' method") /* Call the corresponding VOL callback */ - if ((cls->file_cls.optional)(obj, opt_type, dxpl_id, req, arguments) < 0) + if ((cls->file_cls.optional)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file optional failed") done: @@ -3860,11 +4002,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_file_optional(const H5VL_object_t *vol_obj, H5VL_file_optional_t opt_type, hid_t dxpl_id, void **req, - ...) +H5VL_file_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -3876,16 +4015,10 @@ H5VL_file_optional(const H5VL_object_t *vol_obj, H5VL_file_optional_t opt_type, vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__file_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file optional failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -3904,14 +4037,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLfile_optional(void *obj, hid_t connector_id, H5VL_file_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLfile_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVvixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -3920,7 +4053,7 @@ H5VLfile_optional(void *obj, hid_t connector_id, H5VL_file_optional_t opt_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__file_optional(obj, cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__file_optional(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute file optional callback") done: @@ -3928,6 +4061,49 @@ done: } /* end H5VLfile_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLfile_optional_op + * + * Purpose: Performs an optional connector-specific operation on a file + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLfile_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* File VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*!ii", app_file, app_func, app_line, file_id, args, dxpl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Call the corresponding internal VOL routine */ + if (H5VL__common_optional_op(file_id, H5I_FILE, H5VL__file_optional, args, dxpl_id, token_ptr, &vol_obj) < + 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute file optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, file_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLfile_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__file_close * * Purpose: Closes a file through the VOL @@ -4244,8 +4420,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -4256,7 +4431,7 @@ H5VL__group_get(void *obj, const H5VL_class_t *cls, H5VL_group_get_t get_type, h HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'group get' method") /* Call the corresponding VOL callback */ - if ((cls->group_cls.get)(obj, get_type, dxpl_id, req, arguments) < 0) + if ((cls->group_cls.get)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "group get failed") done: @@ -4274,10 +4449,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_group_get(const H5VL_object_t *vol_obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, ...) +H5VL_group_get(const H5VL_object_t *vol_obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -4289,16 +4462,10 @@ H5VL_group_get(const H5VL_object_t *vol_obj, H5VL_group_get_t get_type, hid_t dx vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__group_get(vol_obj->data, vol_obj->connector->cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__group_get(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "group get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -4317,14 +4484,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_t get_type, hid_t dxpl_id, void **req /*out*/, - va_list arguments) +H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiViixx", obj, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -4333,7 +4499,7 @@ H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_t get_type, hid_t dx HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__group_get(obj, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__group_get(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute group get callback") done: @@ -4351,8 +4517,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -4363,7 +4529,7 @@ H5VL__group_specific(void *obj, const H5VL_class_t *cls, H5VL_group_specific_t s HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'group specific' method") /* Call the corresponding VOL callback */ - if ((cls->group_cls.specific)(obj, specific_type, dxpl_id, req, arguments) < 0) + if ((cls->group_cls.specific)(obj, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group specific callback") done: @@ -4381,11 +4547,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_group_specific(const H5VL_object_t *vol_obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, - void **req, ...) +H5VL_group_specific(const H5VL_object_t *vol_obj, H5VL_group_specific_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -4397,17 +4560,10 @@ H5VL_group_specific(const H5VL_object_t *vol_obj, H5VL_group_specific_t specific vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__group_specific(vol_obj->data, vol_obj->connector->cls, specific_type, dxpl_id, req, arguments) < - 0) + if (H5VL__group_specific(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group specific callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -4426,14 +4582,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_t specific_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVjixx", obj, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -4442,7 +4598,7 @@ H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_t specific HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__group_specific(obj, cls, specific_type, dxpl_id, req, arguments) < 0) + if (H5VL__group_specific(obj, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group specific callback") done: @@ -4460,8 +4616,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -4472,8 +4628,9 @@ H5VL__group_optional(void *obj, const H5VL_class_t *cls, H5VL_group_optional_t o HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'group optional' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->group_cls.optional)(obj, opt_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->group_cls.optional)(obj, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute group optional callback"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -4490,11 +4647,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_group_optional(const H5VL_object_t *vol_obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, void **req, - ...) +H5VL_group_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -4506,17 +4660,11 @@ H5VL_group_optional(const H5VL_object_t *vol_obj, H5VL_group_optional_t opt_type vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = H5VL__group_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, - arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__group_optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute group optional callback"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -4535,14 +4683,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVwixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -4551,14 +4699,58 @@ H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_group_optional_t opt_type HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__group_optional(obj, cls, opt_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group optional callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__group_optional(obj, cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute group optional callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) } /* end H5VLgroup_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLgroup_optional_op + * + * Purpose: Performs an optional connector-specific operation on a group + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLgroup_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t group_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) +{ + H5VL_object_t *vol_obj = NULL; /* Group VOL object */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE7("e", "*s*sIui*!ii", app_file, app_func, app_line, group_id, args, dxpl_id, es_id); + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Call the corresponding internal VOL routine */ + if ((ret_value = H5VL__common_optional_op(group_id, H5I_GROUP, H5VL__group_optional, args, dxpl_id, + token_ptr, &vol_obj)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute group optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, + H5ARG_TRACE7(__func__, "*s*sIui*!ii", app_file, app_func, app_line, group_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLgroup_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__group_close * * Purpose: Closes a group through the VOL @@ -4672,9 +4864,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__link_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, - const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, - va_list arguments) +H5VL__link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + const H5VL_class_t *cls, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -4685,7 +4876,7 @@ H5VL__link_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link create' method") /* Call the corresponding VOL callback */ - if ((cls->link_cls.create)(create_type, obj, loc_params, lcpl_id, lapl_id, dxpl_id, req, arguments) < 0) + if ((cls->link_cls.create)(args, obj, loc_params, lcpl_id, lapl_id, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "link create failed") done: @@ -4703,31 +4894,19 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_link_create(H5VL_link_create_type_t create_type, const H5VL_object_t *vol_obj, - const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, - ...) +H5VL_link_create(H5VL_link_create_args_t *args, const H5VL_object_t *vol_obj, + const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req) { - H5VL_object_t tmp_vol_obj; /* Temporary object */ - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ + H5VL_object_t tmp_vol_obj; /* Temporary VOL object */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) - /* Start the varargs, so they can be copied */ - HDva_start(arguments, req); - arg_started = TRUE; - /* Special case for hard links */ - if (H5VL_LINK_CREATE_HARD == create_type && NULL == vol_obj->data) { - va_list tmp_arguments; /* Copy of argument list passed in */ - - /* Get the VOL data pointer from the varargs */ - HDva_copy(tmp_arguments, arguments); - tmp_vol_obj.data = HDva_arg(tmp_arguments, void *); - HDva_end(tmp_arguments); - } /* end if */ + if (H5VL_LINK_CREATE_HARD == args->op_type && NULL == vol_obj->data) + /* Get the VOL data pointer from the arguments */ + tmp_vol_obj.data = args->args.hard.curr_obj; else /* Use the VOL object passed in */ tmp_vol_obj.data = vol_obj->data; @@ -4739,15 +4918,11 @@ H5VL_link_create(H5VL_link_create_type_t create_type, const H5VL_object_t *vol_o vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - if (H5VL__link_create(create_type, vol_obj->data, loc_params, vol_obj->connector->cls, lcpl_id, lapl_id, - dxpl_id, req, arguments) < 0) + if (H5VL__link_create(args, vol_obj->data, loc_params, vol_obj->connector->cls, lcpl_id, lapl_id, dxpl_id, + req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "link create failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -4768,23 +4943,21 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLlink_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, - hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req /*out*/, - va_list arguments) +H5VLlink_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE9("e", "Vk*x*#iiiixx", create_type, obj, loc_params, connector_id, lcpl_id, lapl_id, dxpl_id, req, - arguments); + H5TRACE8("e", "*!*x*#iiiix", args, obj, loc_params, connector_id, lcpl_id, lapl_id, dxpl_id, req); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__link_create(create_type, obj, loc_params, cls, lcpl_id, lapl_id, dxpl_id, req, arguments) < 0) + if (H5VL__link_create(args, obj, loc_params, cls, lcpl_id, lapl_id, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "unable to create link") done: @@ -5017,7 +5190,7 @@ done: */ static herr_t H5VL__link_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5028,7 +5201,7 @@ H5VL__link_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_ HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link get' method") /* Call the corresponding VOL callback */ - if ((cls->link_cls.get)(obj, loc_params, get_type, dxpl_id, req, arguments) < 0) + if ((cls->link_cls.get)(obj, loc_params, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "link get failed") done: @@ -5046,11 +5219,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_link_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, - hid_t dxpl_id, void **req, ...) +H5VL_link_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t *args, + hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5062,17 +5233,10 @@ H5VL_link_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__link_get(vol_obj->data, loc_params, vol_obj->connector->cls, get_type, dxpl_id, req, - arguments) < 0) + if (H5VL__link_get(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "link get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5091,14 +5255,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_link_get_t get_type, - hid_t dxpl_id, void **req /*out*/, va_list arguments) +H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_link_get_args_t *args, + hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVlixx", obj, loc_params, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5107,7 +5271,7 @@ H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__link_get(obj, loc_params, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__link_get(obj, loc_params, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute link get callback") done: @@ -5126,7 +5290,7 @@ done: */ static herr_t H5VL__link_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5137,8 +5301,9 @@ H5VL__link_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_c HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link specific' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->link_cls.specific)(obj, loc_params, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->link_cls.specific)(obj, loc_params, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute link specific callback"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -5156,10 +5321,8 @@ done: */ herr_t H5VL_link_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, ...) + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5171,17 +5334,12 @@ H5VL_link_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_pa vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = H5VL__link_specific(vol_obj->data, loc_params, vol_obj->connector->cls, specific_type, - dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = + H5VL__link_specific(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute link specific callback"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5201,13 +5359,13 @@ done: */ herr_t H5VLlink_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVmixx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5216,8 +5374,9 @@ H5VLlink_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connecto HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__link_specific(obj, loc_params, cls, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__link_specific(obj, loc_params, cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute link specific callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) @@ -5234,8 +5393,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__link_optional(void *obj, const H5VL_class_t *cls, H5VL_link_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__link_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5246,7 +5405,7 @@ H5VL__link_optional(void *obj, const H5VL_class_t *cls, H5VL_link_optional_t opt HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'link optional' method") /* Call the corresponding VOL callback */ - if ((cls->link_cls.optional)(obj, opt_type, dxpl_id, req, arguments) < 0) + if ((cls->link_cls.optional)(obj, loc_params, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback") done: @@ -5264,11 +5423,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_link_optional(const H5VL_object_t *vol_obj, H5VL_link_optional_t opt_type, hid_t dxpl_id, void **req, - ...) +H5VL_link_optional(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5280,16 +5437,10 @@ H5VL_link_optional(const H5VL_object_t *vol_obj, H5VL_link_optional_t opt_type, vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__link_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__link_optional(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5308,14 +5459,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLlink_optional(void *obj, hid_t connector_id, H5VL_link_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLlink_optional(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVxixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5324,7 +5475,7 @@ H5VLlink_optional(void *obj, hid_t connector_id, H5VL_link_optional_t opt_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__link_optional(obj, cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__link_optional(obj, loc_params, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback") done: @@ -5332,37 +5483,98 @@ done: } /* end H5VLlink_optional() */ /*------------------------------------------------------------------------- - * Function: H5VL__object_open + * Function: H5VLlink_optional_op * - * Purpose: Opens a object through the VOL + * Purpose: Performs an optional connector-specific operation on a link * - * Return: Success: Pointer to the object - * Failure: NULL + * Return: Success: Non-negative + * Failure: Negative * *------------------------------------------------------------------------- */ -static void * -H5VL__object_open(void *obj, const H5VL_loc_params_t *params, const H5VL_class_t *cls, - H5I_type_t *opened_type, hid_t dxpl_id, void **req) +herr_t +H5VLlink_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t lapl_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id) { - void *ret_value = NULL; /* Return value */ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_API(FAIL) + H5TRACE9("e", "*s*sIui*si*!ii", app_file, app_func, app_line, loc_id, name, lapl_id, args, dxpl_id, + es_id); - /* Check if the corresponding VOL callback exists */ - if (NULL == cls->object_cls.open) - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'object open' method") + /* Check arguments */ + /* name is verified in H5VL_setup_name_args() */ - /* Call the corresponding VOL callback */ - if (NULL == (ret_value = (cls->object_cls.open)(obj, params, opened_type, dxpl_id, req))) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "object open failed") + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, &vol_obj, &loc_params) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set link access arguments") -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL__object_open() */ + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ -/*------------------------------------------------------------------------- - * Function: H5VL_object_open + /* Set wrapper info in API context */ + if (H5VL_set_vol_wrapper(vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + if (H5VL__link_optional(vol_obj->data, &loc_params, vol_obj->connector->cls, args, dxpl_id, token_ptr) < + 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute link optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, H5ARG_TRACE9(__func__, "*s*sIui*si*!ii", app_file, app_func, app_line, loc_id, name, lapl_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + /* Reset object wrapping info in API context */ + if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_API(ret_value) +} /* end H5VLlink_optional_op() */ + +/*------------------------------------------------------------------------- + * Function: H5VL__object_open + * + * Purpose: Opens a object through the VOL + * + * Return: Success: Pointer to the object + * Failure: NULL + * + *------------------------------------------------------------------------- + */ +static void * +H5VL__object_open(void *obj, const H5VL_loc_params_t *params, const H5VL_class_t *cls, + H5I_type_t *opened_type, hid_t dxpl_id, void **req) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check if the corresponding VOL callback exists */ + if (NULL == cls->object_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "VOL connector has no 'object open' method") + + /* Call the corresponding VOL callback */ + if (NULL == (ret_value = (cls->object_cls.open)(obj, params, opened_type, dxpl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPENOBJ, NULL, "object open failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__object_open() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_object_open * * Purpose: Opens a object through the VOL * @@ -5556,7 +5768,7 @@ done: */ static herr_t H5VL__object_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5567,7 +5779,7 @@ H5VL__object_get(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_clas HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'object get' method") /* Call the corresponding VOL callback */ - if ((cls->object_cls.get)(obj, loc_params, get_type, dxpl_id, req, arguments) < 0) + if ((cls->object_cls.get)(obj, loc_params, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") done: @@ -5585,11 +5797,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_object_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, - hid_t dxpl_id, void **req, ...) +H5VL_object_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5601,17 +5811,10 @@ H5VL_object_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_param vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__object_get(vol_obj->data, loc_params, vol_obj->connector->cls, get_type, dxpl_id, req, - arguments) < 0) + if (H5VL__object_get(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5630,14 +5833,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, H5VL_object_get_t get_type, - hid_t dxpl_id, void **req /*out*/, va_list arguments) +H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVnixx", obj, loc_params, connector_id, get_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5646,7 +5849,7 @@ H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_i HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__object_get(obj, loc_params, cls, get_type, dxpl_id, req, arguments) < 0) + if (H5VL__object_get(obj, loc_params, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to execute object get callback") done: @@ -5665,7 +5868,7 @@ done: */ static herr_t H5VL__object_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments) + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5676,8 +5879,9 @@ H5VL__object_specific(void *obj, const H5VL_loc_params_t *loc_params, const H5VL HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'object specific' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->object_cls.specific)(obj, loc_params, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "object specific failed") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->object_cls.specific)(obj, loc_params, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "object specific failed"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -5695,10 +5899,8 @@ done: */ herr_t H5VL_object_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, ...) + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5710,17 +5912,12 @@ H5VL_object_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_ vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = H5VL__object_specific(vol_obj->data, loc_params, vol_obj->connector->cls, specific_type, - dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "object specific failed") + /* (Must return value from callback, for iterators) */ + if ((ret_value = H5VL__object_specific(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, + req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "object specific failed"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5740,14 +5937,13 @@ done: */ herr_t H5VLobject_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req /*out*/, - va_list arguments) + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE7("e", "*x*#iVoixx", obj, loc_params, connector_id, specific_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5755,13 +5951,10 @@ H5VLobject_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connec if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") - /* Check if the corresponding VOL callback exists */ - if (NULL == cls->object_cls.specific) - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no `object specific' method") - /* Bypass the H5VLint layer, calling the VOL callback directly */ - if ((ret_value = (cls->object_cls.specific)(obj, loc_params, specific_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object specific callback") + /* (Must return value from callback, for iterators) */ + if ((ret_value = (cls->object_cls.specific)(obj, loc_params, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute object specific callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) @@ -5778,8 +5971,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__object_optional(void *obj, const H5VL_class_t *cls, H5VL_object_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL__object_optional(void *obj, const H5VL_loc_params_t *loc_params, const H5VL_class_t *cls, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -5790,7 +5983,7 @@ H5VL__object_optional(void *obj, const H5VL_class_t *cls, H5VL_object_optional_t HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'object optional' method") /* Call the corresponding VOL callback */ - if ((cls->object_cls.optional)(obj, opt_type, dxpl_id, req, arguments) < 0) + if ((cls->object_cls.optional)(obj, loc_params, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback") done: @@ -5808,11 +6001,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_object_optional(const H5VL_object_t *vol_obj, H5VL_object_optional_t opt_type, hid_t dxpl_id, void **req, - ...) +H5VL_object_optional(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -5824,16 +6015,10 @@ H5VL_object_optional(const H5VL_object_t *vol_obj, H5VL_object_optional_t opt_ty vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if (H5VL__object_optional(vol_obj->data, vol_obj->connector->cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__object_optional(vol_obj->data, loc_params, vol_obj->connector->cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") @@ -5852,14 +6037,14 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLobject_optional(void *obj, hid_t connector_id, H5VL_object_optional_t opt_type, hid_t dxpl_id, - void **req /*out*/, va_list arguments) +H5VLobject_optional(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiVyixx", obj, connector_id, opt_type, dxpl_id, req, arguments); + H5TRACE6("e", "*x*#i*!ix", obj, loc_params, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -5868,7 +6053,7 @@ H5VLobject_optional(void *obj, hid_t connector_id, H5VL_object_optional_t opt_ty HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if (H5VL__object_optional(obj, cls, opt_type, dxpl_id, req, arguments) < 0) + if (H5VL__object_optional(obj, loc_params, cls, args, dxpl_id, req) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback") done: @@ -5876,6 +6061,68 @@ done: } /* end H5VLobject_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLobject_optional_op + * + * Purpose: Performs an optional connector-specific operation on an object + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLobject_optional_op(const char *app_file, const char *app_func, unsigned app_line, hid_t loc_id, + const char *name, hid_t lapl_id, H5VL_optional_args_t *args, hid_t dxpl_id, + hid_t es_id) +{ + H5VL_object_t * vol_obj = NULL; /* Object for loc_id */ + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + void * token = NULL; /* Request token for async operation */ + void ** token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE9("e", "*s*sIui*si*!ii", app_file, app_func, app_line, loc_id, name, lapl_id, args, dxpl_id, + es_id); + + /* Check arguments */ + /* name is verified in H5VL_setup_name_args() */ + + /* Set up object access arguments */ + if (H5VL_setup_name_args(loc_id, name, FALSE, lapl_id, &vol_obj, &loc_params) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set link access arguments") + + /* Set up request token pointer for asynchronous operation */ + if (H5ES_NONE != es_id) + token_ptr = &token; /* Point at token for VOL connector to set up */ + + /* Set wrapper info in API context */ + if (H5VL_set_vol_wrapper(vol_obj) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ + if (H5VL__object_optional(vol_obj->data, &loc_params, vol_obj->connector->cls, args, dxpl_id, token_ptr) < + 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute object optional callback") + + /* If a token was created, add the token to the event set */ + if (NULL != token) + /* clang-format off */ + if (H5ES_insert(es_id, vol_obj->connector, token, H5ARG_TRACE9(__func__, "*s*sIui*si*!ii", app_file, app_func, app_line, loc_id, name, lapl_id, args, dxpl_id, es_id)) < 0) + /* clang-format on */ + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert token into event set") + +done: + /* Reset object wrapping info in API context */ + if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + + FUNC_LEAVE_API(ret_value) +} /* end H5VLobject_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__introspect_get_conn_cls * * Purpose: Calls the connector-specific callback to query the connector @@ -5989,6 +6236,76 @@ done: } /* end H5VLintrospect_get_conn_cls() */ /*------------------------------------------------------------------------- + * Function: H5VL_introspect_get_cap_flags + * + * Purpose: Calls the connector-specific callback to query the connector's + * capability flags. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_introspect_get_cap_flags(const void *info, const H5VL_class_t *cls, unsigned *cap_flags) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(cls); + HDassert(cap_flags); + + /* Check if the corresponding VOL callback exists */ + if (NULL == cls->introspect_cls.get_cap_flags) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'get_cap_flags' method") + + /* Call the corresponding VOL callback */ + if ((cls->introspect_cls.get_cap_flags)(info, cap_flags) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query connector capability flags") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_introspect_get_cap_flags() */ + +/*------------------------------------------------------------------------- + * Function: H5VLintrospect_get_cap_flags + * + * Purpose: Calls the connector-specific callback to query the connector's + * capability flags. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLintrospect_get_cap_flags(const void *info, hid_t connector_id, unsigned *cap_flags /*out*/) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE3("e", "*xix", info, connector_id, cap_flags); + + /* Check args */ + if (NULL == cap_flags) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL conn_cls pointer") + + /* Get class pointer */ + if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding internal VOL routine */ + if (H5VL_introspect_get_cap_flags(info, cls, cap_flags) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query connector's capability flags") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLintrospect_get_cap_flags() */ + +/*------------------------------------------------------------------------- * Function: H5VL__introspect_opt_query * * Purpose: Calls the connector-specific callback to query if an optional @@ -6135,28 +6452,18 @@ done: herr_t H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5VL_request_status_t *status) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity checks */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ if (H5VL__request_wait(vol_obj->data, vol_obj->connector->cls, timeout, status) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request wait failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_wait() */ @@ -6239,28 +6546,18 @@ done: herr_t H5VL_request_notify(const H5VL_object_t *vol_obj, H5VL_request_notify_t cb, void *ctx) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ if (H5VL__request_notify(vol_obj->data, vol_obj->connector->cls, cb, ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "request notify failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_notify() */ @@ -6342,28 +6639,18 @@ done: herr_t H5VL_request_cancel(const H5VL_object_t *vol_obj, H5VL_request_status_t *status) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ if (H5VL__request_cancel(vol_obj->data, vol_obj->connector->cls, status) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request cancel failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_cancel() */ @@ -6378,13 +6665,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLrequest_cancel(void *req, hid_t connector_id, H5VL_request_status_t *status) +H5VLrequest_cancel(void *req, hid_t connector_id, H5VL_request_status_t *status /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE3("e", "*xi*#", req, connector_id, status); + H5TRACE3("e", "*xix", req, connector_id, status); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) @@ -6409,8 +6696,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__request_specific(void *req, const H5VL_class_t *cls, H5VL_request_specific_t specific_type, - va_list arguments) +H5VL__request_specific(void *req, const H5VL_class_t *cls, H5VL_request_specific_args_t *args) { herr_t ret_value = SUCCEED; /* Return value */ @@ -6425,7 +6711,7 @@ H5VL__request_specific(void *req, const H5VL_class_t *cls, H5VL_request_specific HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async specific' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->request_cls.specific)(req, specific_type, arguments)) < 0) + if ((cls->request_cls.specific)(req, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request specific callback") @@ -6444,40 +6730,21 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_t specific_type, ...) +H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_args_t *args) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - HDva_start(arguments, specific_type); - arg_started = TRUE; - if ((ret_value = - H5VL__request_specific(vol_obj->data, vol_obj->connector->cls, specific_type, arguments)) < 0) + if (H5VL__request_specific(vol_obj->data, vol_obj->connector->cls, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request specific callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_specific() */ @@ -6492,20 +6759,20 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_t specific_type, va_list arguments) +H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_args_t *args) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE4("e", "*xiVrx", req, connector_id, specific_type, arguments); + H5TRACE3("e", "*xi*!", req, connector_id, args); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__request_specific(req, cls, specific_type, arguments)) < 0) + if (H5VL__request_specific(req, cls, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request specific callback") @@ -6524,8 +6791,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_request_optional_t opt_type, - va_list arguments) +H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_optional_args_t *args) { herr_t ret_value = SUCCEED; /* Return value */ @@ -6540,7 +6806,7 @@ H5VL__request_optional(void *req, const H5VL_class_t *cls, H5VL_request_optional HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'async optional' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->request_cls.optional)(req, opt_type, arguments)) < 0) + if ((cls->request_cls.optional)(req, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request optional callback") @@ -6559,39 +6825,21 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_request_optional_t opt_type, ...) +H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - HDva_start(arguments, opt_type); - arg_started = TRUE; - if ((ret_value = H5VL__request_optional(vol_obj->data, vol_obj->connector->cls, opt_type, arguments)) < 0) + if (H5VL__request_optional(vol_obj->data, vol_obj->connector->cls, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_optional() */ @@ -6606,20 +6854,20 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLrequest_optional(void *req, hid_t connector_id, H5VL_request_optional_t opt_type, va_list arguments) +H5VLrequest_optional(void *req, hid_t connector_id, H5VL_optional_args_t *args) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE4("e", "*xiVzx", req, connector_id, opt_type, arguments); + H5TRACE3("e", "*xi*!", req, connector_id, args); /* Get class pointer */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__request_optional(req, cls, opt_type, arguments)) < 0) + if (H5VL__request_optional(req, cls, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute asynchronous request optional callback") @@ -6628,6 +6876,43 @@ done: } /* end H5VLrequest_optional() */ /*------------------------------------------------------------------------- + * Function: H5VLrequest_optional_op + * + * Purpose: Performs an optional connector-specific operation on a request + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLrequest_optional_op(void *req, hid_t connector_id, H5VL_optional_args_t *args) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("e", "*xi*!", req, connector_id, args); + + /* Check arguments */ + if (NULL == req) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid request") + if (NULL == args) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid arguments") + + /* Get class pointer */ + if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding internal VOL routine */ + if (H5VL__request_optional(req, cls, args) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute request optional callback") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLrequest_optional_op() */ + +/*------------------------------------------------------------------------- * Function: H5VL__request_free * * Purpose: Frees an asynchronous request through the VOL @@ -6673,28 +6958,18 @@ done: herr_t H5VL_request_free(const H5VL_object_t *vol_obj) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(vol_obj); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding VOL callback */ if (H5VL__request_free(vol_obj->data, vol_obj->connector->cls) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "request free failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_request_free() */ @@ -6778,8 +7053,7 @@ done: herr_t H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, void *blob_id, void *ctx) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -6788,19 +7062,11 @@ H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, void * HDassert(size == 0 || buf); HDassert(blob_id); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding VOL callback */ if (H5VL__blob_put(vol_obj->data, vol_obj->connector->cls, buf, size, blob_id, ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_blob_put() */ @@ -6882,8 +7148,7 @@ done: herr_t H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, size_t size, void *ctx) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -6892,19 +7157,11 @@ H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, size HDassert(blob_id); HDassert(buf); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding VOL callback */ if (H5VL__blob_get(vol_obj->data, vol_obj->connector->cls, blob_id, buf, size, ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_blob_get() */ @@ -6953,8 +7210,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob_specific_t specific_type, - va_list arguments) +H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob_specific_args_t *args) { herr_t ret_value = SUCCEED; /* Return value */ @@ -6970,7 +7226,7 @@ H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob specific' method") /* Call the corresponding VOL callback */ - if ((cls->blob_cls.specific)(obj, blob_id, specific_type, arguments) < 0) + if ((cls->blob_cls.specific)(obj, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback") done: @@ -6988,12 +7244,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specific_t specific_type, ...) +H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specific_args_t *args) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -7001,27 +7254,11 @@ H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specif HDassert(vol_obj); HDassert(blob_id); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - HDva_start(arguments, specific_type); - arg_started = TRUE; - if ((ret_value = H5VL__blob_specific(vol_obj->data, vol_obj->connector->cls, blob_id, specific_type, - arguments)) < 0) + if (H5VL__blob_specific(vol_obj->data, vol_obj->connector->cls, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_blob_specific() */ @@ -7035,14 +7272,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specific_t specific_type, - va_list arguments) +H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specific_args_t *args) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE5("e", "*xi*xVBx", obj, connector_id, blob_id, specific_type, arguments); + H5TRACE4("e", "*xi*x*!", obj, connector_id, blob_id, args); /* Get class pointer */ if (NULL == obj) @@ -7051,7 +7287,7 @@ H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specif HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding VOL callback */ - if (H5VL__blob_specific(obj, cls, blob_id, specific_type, arguments) < 0) + if (H5VL__blob_specific(obj, cls, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "blob specific operation failed") done: @@ -7071,8 +7307,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__blob_optional(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob_optional_t opt_type, - va_list arguments) +H5VL__blob_optional(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_optional_args_t *args) { herr_t ret_value = SUCCEED; /* Return value */ @@ -7088,7 +7323,7 @@ H5VL__blob_optional(void *obj, const H5VL_class_t *cls, void *blob_id, H5VL_blob HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob optional' method") /* Call the corresponding VOL callback */ - if ((cls->blob_cls.optional)(obj, blob_id, opt_type, arguments) < 0) + if ((cls->blob_cls.optional)(obj, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob optional callback") done: @@ -7106,12 +7341,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_optional_t opt_type, ...) +H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_optional_args_t *args) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -7119,27 +7351,11 @@ H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_option HDassert(vol_obj); HDassert(blob_id); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - HDva_start(arguments, opt_type); - arg_started = TRUE; - if ((ret_value = - H5VL__blob_optional(vol_obj->data, vol_obj->connector->cls, blob_id, opt_type, arguments)) < 0) + if (H5VL__blob_optional(vol_obj->data, vol_obj->connector->cls, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob optional callback") done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_blob_optional() */ @@ -7153,14 +7369,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_optional_t opt_type, - va_list arguments) +H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_optional_args_t *args) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE5("e", "*xi*xVAx", obj, connector_id, blob_id, opt_type, arguments); + H5TRACE4("e", "*xi*x*!", obj, connector_id, blob_id, args); /* Get class pointer */ if (NULL == obj) @@ -7169,7 +7384,7 @@ H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_option HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding VOL callback */ - if (H5VL__blob_optional(obj, cls, blob_id, opt_type, arguments) < 0) + if (H5VL__blob_optional(obj, cls, blob_id, args) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "blob optional operation failed") done: @@ -7243,8 +7458,7 @@ herr_t H5VL_token_cmp(const H5VL_object_t *vol_obj, const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -7252,20 +7466,11 @@ H5VL_token_cmp(const H5VL_object_t *vol_obj, const H5O_token_t *token1, const H5 HDassert(vol_obj); HDassert(cmp_value); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__token_cmp(vol_obj->data, vol_obj->connector->cls, token1, token2, cmp_value)) < 0) + if (H5VL__token_cmp(vol_obj->data, vol_obj->connector->cls, token1, token2, cmp_value) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "token compare failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_token_cmp() */ @@ -7362,8 +7567,7 @@ herr_t H5VL_token_to_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, const H5O_token_t *token, char **token_str) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -7372,21 +7576,11 @@ H5VL_token_to_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, const H5O_t HDassert(token); HDassert(token_str); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__token_to_str(vol_obj->data, obj_type, vol_obj->connector->cls, token, token_str)) < - 0) + if (H5VL__token_to_str(vol_obj->data, obj_type, vol_obj->connector->cls, token, token_str) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "token serialization failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_token_to_str() */ @@ -7480,8 +7674,7 @@ herr_t H5VL_token_from_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, const char *token_str, H5O_token_t *token) { - hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -7490,21 +7683,11 @@ H5VL_token_from_str(const H5VL_object_t *vol_obj, H5I_type_t obj_type, const cha HDassert(token); HDassert(token_str); - /* Set wrapper info in API context */ - if (H5VL_set_vol_wrapper(vol_obj) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") - vol_wrapper_set = TRUE; - /* Call the corresponding internal VOL routine */ - if ((ret_value = - H5VL__token_from_str(vol_obj->data, obj_type, vol_obj->connector->cls, token_str, token)) < 0) + if (H5VL__token_from_str(vol_obj->data, obj_type, vol_obj->connector->cls, token_str, token) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "token deserialization failed") done: - /* Reset object wrapping info in API context */ - if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_token_from_str() */ @@ -7557,7 +7740,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5VL__optional(void *obj, const H5VL_class_t *cls, int op_type, hid_t dxpl_id, void **req, va_list arguments) +H5VL__optional(void *obj, const H5VL_class_t *cls, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { herr_t ret_value = SUCCEED; /* Return value */ @@ -7568,8 +7751,8 @@ H5VL__optional(void *obj, const H5VL_class_t *cls, int op_type, hid_t dxpl_id, v HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'optional' method") /* Call the corresponding VOL callback */ - if ((ret_value = (cls->optional)(obj, op_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, ret_value, "unable to execute optional callback") + if ((ret_value = (cls->optional)(obj, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback"); done: FUNC_LEAVE_NOAPI(ret_value) @@ -7586,10 +7769,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_optional(const H5VL_object_t *vol_obj, int op_type, hid_t dxpl_id, void **req, ...) +H5VL_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ @@ -7601,20 +7782,13 @@ H5VL_optional(const H5VL_object_t *vol_obj, int op_type, hid_t dxpl_id, void **r vol_wrapper_set = TRUE; /* Call the corresponding internal VOL routine */ - HDva_start(arguments, req); - arg_started = TRUE; - if ((ret_value = - H5VL__optional(vol_obj->data, vol_obj->connector->cls, op_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute optional callback") + if ((ret_value = H5VL__optional(vol_obj->data, vol_obj->connector->cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback"); done: - /* End access to the va_list, if we started it */ - if (arg_started) - HDva_end(arguments); - /* Reset object wrapping info in API context */ if (vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTRESET, ret_value, "can't reset VOL wrapper info") + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_optional() */ @@ -7630,13 +7804,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VLoptional(void *obj, hid_t connector_id, int op_type, hid_t dxpl_id, void **req /*out*/, va_list arguments) +H5VLoptional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, void **req /*out*/) { H5VL_class_t *cls; /* VOL connector's class struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API_NOINIT - H5TRACE6("e", "*xiIsixx", obj, connector_id, op_type, dxpl_id, req, arguments); + H5TRACE5("e", "*xi*!ix", obj, connector_id, args, dxpl_id, req); /* Check args and get class pointer */ if (NULL == obj) @@ -7645,8 +7819,8 @@ H5VLoptional(void *obj, hid_t connector_id, int op_type, hid_t dxpl_id, void **r HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") /* Call the corresponding internal VOL routine */ - if ((ret_value = H5VL__optional(obj, cls, op_type, dxpl_id, req, arguments)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, ret_value, "unable to execute optional callback") + if ((ret_value = H5VL__optional(obj, cls, args, dxpl_id, req)) < 0) + HERROR(H5E_VOL, H5E_CANTOPERATE, "unable to execute optional callback"); done: FUNC_LEAVE_API_NOINIT(ret_value) diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index 63613bc..af3530c 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -20,6 +20,7 @@ /* Public headers needed by this file */ #include "H5public.h" /* Generic Functions */ #include "H5Apublic.h" /* Attributes */ +#include "H5Dpublic.h" /* Datasets */ #include "H5ESpublic.h" /* Event Stack */ #include "H5Fpublic.h" /* Files */ #include "H5Ipublic.h" /* IDs */ @@ -33,8 +34,10 @@ /*****************/ /* Capability flags for connector */ -#define H5VL_CAP_FLAG_NONE 0 /* No special connector capabilities */ -#define H5VL_CAP_FLAG_THREADSAFE 0x01 /* Connector is threadsafe */ +#define H5VL_CAP_FLAG_NONE 0 /* No special connector capabilities */ +#define H5VL_CAP_FLAG_THREADSAFE 0x01 /* Connector is threadsafe */ +#define H5VL_CAP_FLAG_ASYNC 0x02 /* Connector performs operations asynchronously*/ +#define H5VL_CAP_FLAG_NATIVE_FILES 0x04 /* Connector produces native file format */ /* Container info version */ #define H5VL_CONTAINER_INFO_VERSION 0x01 /* Container info struct version */ @@ -42,11 +45,64 @@ /* The maximum size allowed for blobs */ #define H5VL_MAX_BLOB_ID_SIZE (16) /* Allow for 128-bits blob IDs */ +/* # of optional operations reserved for the native VOL connector */ +#define H5VL_RESERVED_NATIVE_OPTIONAL 1024 + /*******************/ /* Public Typedefs */ /*******************/ -/* types for attribute GET callback */ +/* Types for different ways that objects are located in an HDF5 container */ +typedef enum H5VL_loc_type_t { + H5VL_OBJECT_BY_SELF, + H5VL_OBJECT_BY_NAME, + H5VL_OBJECT_BY_IDX, + H5VL_OBJECT_BY_TOKEN +} H5VL_loc_type_t; + +typedef struct H5VL_loc_by_name { + const char *name; + hid_t lapl_id; +} H5VL_loc_by_name_t; + +typedef struct H5VL_loc_by_idx { + const char * name; + H5_index_t idx_type; + H5_iter_order_t order; + hsize_t n; + hid_t lapl_id; +} H5VL_loc_by_idx_t; + +typedef struct H5VL_loc_by_token { + H5O_token_t *token; +} H5VL_loc_by_token_t; + +/* Structure to hold parameters for object locations. + * Either: BY_SELF, BY_NAME, BY_IDX, BY_TOKEN + * + * Note: Leave loc_by_token as the first union member so we + * can perform the simplest initialization of the struct + * without raising warnings. + * + * Note: BY_SELF requires no union members. + */ +typedef struct H5VL_loc_params_t { + H5I_type_t obj_type; + H5VL_loc_type_t type; + union { + H5VL_loc_by_token_t loc_by_token; + H5VL_loc_by_name_t loc_by_name; + H5VL_loc_by_idx_t loc_by_idx; + } loc_data; +} H5VL_loc_params_t; + +/* Struct for all 'optional' callbacks */ +typedef struct H5VL_optional_args_t { + int op_type; /* Operation to perform */ + void *args; /* Pointer to operation's argument struct */ +} H5VL_optional_args_t; + +/* Values for attribute 'get' operations */ typedef enum H5VL_attr_get_t { H5VL_ATTR_GET_ACPL, /* creation property list */ H5VL_ATTR_GET_INFO, /* info */ @@ -56,18 +112,115 @@ typedef enum H5VL_attr_get_t { H5VL_ATTR_GET_TYPE /* datatype */ } H5VL_attr_get_t; -/* types for attribute SPECFIC callback */ +/* Parameters for attribute 'get_name' operation */ +typedef struct H5VL_attr_get_name_args_t { + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + size_t buf_size; /* Size of attribute name buffer */ + char * buf; /* Buffer for attribute name (OUT) */ + size_t * attr_name_len; /* Actual length of attribute name (OUT) */ +} H5VL_attr_get_name_args_t; + +/* Parameters for attribute 'get_info' operation */ +typedef struct H5VL_attr_get_info_args_t { + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + const char * attr_name; /* Attribute name (for get_info_by_name) */ + H5A_info_t * ainfo; /* Attribute info (OUT) */ +} H5VL_attr_get_info_args_t; + +/* Parameters for attribute 'get' operations */ +typedef struct H5VL_attr_get_args_t { + H5VL_attr_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_ATTR_GET_ACPL */ + struct { + hid_t acpl_id; /* Attribute creation property list ID (OUT) */ + } get_acpl; + + /* H5VL_ATTR_GET_INFO */ + H5VL_attr_get_info_args_t get_info; /* Attribute info */ + + /* H5VL_ATTR_GET_NAME */ + H5VL_attr_get_name_args_t get_name; /* Attribute name */ + + /* H5VL_ATTR_GET_SPACE */ + struct { + hid_t space_id; /* Dataspace ID (OUT) */ + } get_space; + + /* H5VL_ATTR_GET_STORAGE_SIZE */ + struct { + hsize_t *data_size; /* Size of attribute in file (OUT) */ + } get_storage_size; + + /* H5VL_ATTR_GET_TYPE */ + struct { + hid_t type_id; /* Datatype ID (OUT) */ + } get_type; + } args; +} H5VL_attr_get_args_t; + +/* Values for attribute 'specific' operation */ typedef enum H5VL_attr_specific_t { - H5VL_ATTR_DELETE, /* H5Adelete(_by_name/idx) */ - H5VL_ATTR_EXISTS, /* H5Aexists(_by_name) */ - H5VL_ATTR_ITER, /* H5Aiterate(_by_name) */ - H5VL_ATTR_RENAME /* H5Arename(_by_name) */ + H5VL_ATTR_DELETE, /* H5Adelete(_by_name) */ + H5VL_ATTR_DELETE_BY_IDX, /* H5Adelete_by_idx */ + H5VL_ATTR_EXISTS, /* H5Aexists(_by_name) */ + H5VL_ATTR_ITER, /* H5Aiterate(_by_name) */ + H5VL_ATTR_RENAME /* H5Arename(_by_name) */ } H5VL_attr_specific_t; +/* Parameters for attribute 'iterate' operation */ +typedef struct H5VL_attr_iterate_args_t { + H5_index_t idx_type; /* Type of index to iterate over */ + H5_iter_order_t order; /* Order of index iteration */ + hsize_t * idx; /* Start/stop iteration index (IN/OUT) */ + H5A_operator2_t op; /* Iteration callback function */ + void * op_data; /* Iteration callback context */ +} H5VL_attr_iterate_args_t; + +/* Parameters for attribute 'delete_by_idx' operation */ +typedef struct H5VL_attr_delete_by_idx_args_t { + H5_index_t idx_type; /* Type of index to iterate over */ + H5_iter_order_t order; /* Order of index iteration */ + hsize_t n; /* Iteration index */ +} H5VL_attr_delete_by_idx_args_t; + +/* Parameters for attribute 'specific' operations */ +typedef struct H5VL_attr_specific_args_t { + H5VL_attr_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_ATTR_DELETE */ + struct { + const char *name; /* Name of attribute to delete */ + } del; + + /* H5VL_ATTR_DELETE_BY_IDX */ + H5VL_attr_delete_by_idx_args_t delete_by_idx; + + /* H5VL_ATTR_EXISTS */ + struct { + const char *name; /* Name of attribute to check */ + hbool_t * exists; /* Whether attribute exists (OUT) */ + } exists; + + /* H5VL_ATTR_ITER */ + H5VL_attr_iterate_args_t iterate; + + /* H5VL_ATTR_RENAME */ + struct { + const char *old_name; /* Name of attribute to rename */ + const char *new_name; /* New attribute name */ + } rename; + } args; +} H5VL_attr_specific_args_t; + /* Typedef for VOL connector attribute optional VOL operations */ typedef int H5VL_attr_optional_t; -/* types for dataset GET callback */ +/* Values for dataset 'get' operation */ typedef enum H5VL_dataset_get_t { H5VL_DATASET_GET_DAPL, /* access property list */ H5VL_DATASET_GET_DCPL, /* creation property list */ @@ -77,32 +230,146 @@ typedef enum H5VL_dataset_get_t { H5VL_DATASET_GET_TYPE /* datatype */ } H5VL_dataset_get_t; -/* types for dataset SPECFIC callback */ +/* Parameters for dataset 'get' operations */ +typedef struct H5VL_dataset_get_args_t { + H5VL_dataset_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_DATASET_GET_DAPL */ + struct { + hid_t dapl_id; /* Dataset access property list ID (OUT) */ + } get_dapl; + + /* H5VL_DATASET_GET_DCPL */ + struct { + hid_t dcpl_id; /* Dataset creation property list ID (OUT) */ + } get_dcpl; + + /* H5VL_DATASET_GET_SPACE */ + struct { + hid_t space_id; /* Dataspace ID (OUT) */ + } get_space; + + /* H5VL_DATASET_GET_SPACE_STATUS */ + struct { + H5D_space_status_t *status; /* Storage space allocation status (OUT) */ + } get_space_status; + + /* H5VL_DATASET_GET_STORAGE_SIZE */ + struct { + hsize_t *storage_size; /* Size of dataset's storage (OUT) */ + } get_storage_size; + + /* H5VL_DATASET_GET_TYPE */ + struct { + hid_t type_id; /* Datatype ID (OUT) */ + } get_type; + } args; +} H5VL_dataset_get_args_t; + +/* Values for dataset 'specific' operation */ typedef enum H5VL_dataset_specific_t { H5VL_DATASET_SET_EXTENT, /* H5Dset_extent */ H5VL_DATASET_FLUSH, /* H5Dflush */ - H5VL_DATASET_REFRESH, /* H5Drefresh */ - H5VL_DATASET_WAIT, /* H5Dwait */ - H5VL_DATASET_CHUNK_ITER /* H5Dchunk_iter */ + H5VL_DATASET_REFRESH /* H5Drefresh */ } H5VL_dataset_specific_t; +/* Parameters for dataset 'specific' operations */ +typedef struct H5VL_dataset_specific_args_t { + H5VL_dataset_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_DATASET_SET_EXTENT */ + struct { + const hsize_t *size; /* New dataspace extent */ + } set_extent; + + /* H5VL_DATASET_FLUSH */ + struct { + hid_t dset_id; /* Dataset ID (IN) */ + } flush; + + /* H5VL_DATASET_REFRESH */ + struct { + hid_t dset_id; /* Dataset ID (IN) */ + } refresh; + } args; +} H5VL_dataset_specific_args_t; + /* Typedef for VOL connector dataset optional VOL operations */ typedef int H5VL_dataset_optional_t; -/* types for datatype GET callback */ +/* Values for datatype 'get' operation */ typedef enum H5VL_datatype_get_t { - H5VL_DATATYPE_GET_BINARY, /* get serialized form of transient type */ - H5VL_DATATYPE_GET_TCPL /* datatype creation property list */ + H5VL_DATATYPE_GET_BINARY_SIZE, /* Get size of serialized form of transient type */ + H5VL_DATATYPE_GET_BINARY, /* Get serialized form of transient type */ + H5VL_DATATYPE_GET_TCPL /* Datatype creation property list */ } H5VL_datatype_get_t; -/* types for datatype SPECFIC callback */ -typedef enum H5VL_datatype_specific_t { H5VL_DATATYPE_FLUSH, H5VL_DATATYPE_REFRESH } H5VL_datatype_specific_t; +/* Parameters for datatype 'get' operations */ +typedef struct H5VL_datatype_get_args_t { + H5VL_datatype_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_DATATYPE_GET_BINARY_SIZE */ + struct { + size_t *size; /* Size of serialized form of datatype (OUT) */ + } get_binary_size; + + /* H5VL_DATATYPE_GET_BINARY */ + struct { + void * buf; /* Buffer to store serialized form of datatype (OUT) */ + size_t buf_size; /* Size of serialized datatype buffer */ + } get_binary; + + /* H5VL_DATATYPE_GET_TCPL */ + struct { + hid_t tcpl_id; /* Named datatype creation property list ID (OUT) */ + } get_tcpl; + } args; +} H5VL_datatype_get_args_t; + +/* Values for datatype 'specific' operation */ +typedef enum H5VL_datatype_specific_t { + H5VL_DATATYPE_FLUSH, /* H5Tflush */ + H5VL_DATATYPE_REFRESH /* H5Trefresh */ +} H5VL_datatype_specific_t; + +/* Parameters for datatype 'specific' operations */ +typedef struct H5VL_datatype_specific_args_t { + H5VL_datatype_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_DATATYPE_FLUSH */ + struct { + hid_t type_id; /* Named datatype ID (IN) */ + } flush; + + /* H5VL_DATATYPE_REFRESH */ + struct { + hid_t type_id; /* Named datatype ID (IN) */ + } refresh; + } args; +} H5VL_datatype_specific_args_t; /* Typedef and values for native VOL connector named datatype optional VOL operations */ typedef int H5VL_datatype_optional_t; /* (No optional named datatype VOL operations currently) */ -/* types for file GET callback */ +/* Info for H5VL_FILE_GET_CONT_INFO */ +typedef struct H5VL_file_cont_info_t { + unsigned version; /* version information (keep first) */ + uint64_t feature_flags; /* Container feature flags */ + /* (none currently defined) */ + size_t token_size; /* Size of tokens */ + size_t blob_id_size; /* Size of blob IDs */ +} H5VL_file_cont_info_t; + +/* Values for file 'get' operation */ typedef enum H5VL_file_get_t { H5VL_FILE_GET_CONT_INFO, /* file get container info */ H5VL_FILE_GET_FAPL, /* file access property list */ @@ -114,59 +381,296 @@ typedef enum H5VL_file_get_t { H5VL_FILE_GET_OBJ_IDS /* object ids in file */ } H5VL_file_get_t; -/* types for file SPECIFIC callback */ +/* Parameters for file 'get_name' operation */ +typedef struct H5VL_file_get_name_args_t { + H5I_type_t type; /* ID type of object pointer */ + size_t buf_size; /* Size of file name buffer (IN) */ + char * buf; /* Buffer for file name (OUT) */ + size_t * file_name_len; /* Actual length of file name (OUT) */ +} H5VL_file_get_name_args_t; + +/* Parameters for file 'get_obj_ids' operation */ +typedef struct H5VL_file_get_obj_ids_args_t { + unsigned types; /* Type of objects to count */ + size_t max_objs; /* Size of array of object IDs */ + hid_t * oid_list; /* Array of object IDs (OUT) */ + size_t * count; /* # of objects (OUT) */ +} H5VL_file_get_obj_ids_args_t; + +/* Parameters for file 'get' operations */ +typedef struct H5VL_file_get_args_t { + H5VL_file_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_FILE_GET_CONT_INFO */ + struct { + H5VL_file_cont_info_t *info; /* Container info (OUT) */ + } get_cont_info; + + /* H5VL_FILE_GET_FAPL */ + struct { + hid_t fapl_id; /* File access property list (OUT) */ + } get_fapl; + + /* H5VL_FILE_GET_FCPL */ + struct { + hid_t fcpl_id; /* File creation property list (OUT) */ + } get_fcpl; + + /* H5VL_FILE_GET_FILENO */ + struct { + unsigned long *fileno; /* File "number" (OUT) */ + } get_fileno; + + /* H5VL_FILE_GET_INTENT */ + struct { + unsigned *flags; /* File open/create intent flags (OUT) */ + } get_intent; + + /* H5VL_FILE_GET_NAME */ + H5VL_file_get_name_args_t get_name; + + /* H5VL_FILE_GET_OBJ_COUNT */ + struct { + unsigned types; /* Type of objects to count */ + size_t * count; /* # of objects (OUT) */ + } get_obj_count; + + /* H5VL_FILE_GET_OBJ_IDS */ + H5VL_file_get_obj_ids_args_t get_obj_ids; + } args; +} H5VL_file_get_args_t; + +/* Values for file 'specific' operation */ typedef enum H5VL_file_specific_t { H5VL_FILE_FLUSH, /* Flush file */ H5VL_FILE_REOPEN, /* Reopen the file */ - H5VL_FILE_MOUNT, /* Mount a file */ - H5VL_FILE_UNMOUNT, /* Unmount a file */ H5VL_FILE_IS_ACCESSIBLE, /* Check if a file is accessible */ H5VL_FILE_DELETE, /* Delete a file */ - H5VL_FILE_IS_EQUAL, /* Check if two files are the same */ - H5VL_FILE_WAIT /* Wait for async operations to complete */ + H5VL_FILE_IS_EQUAL /* Check if two files are the same */ } H5VL_file_specific_t; +/* Parameters for file 'specific' operations */ +typedef struct H5VL_file_specific_args_t { + H5VL_file_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_FILE_FLUSH */ + struct { + H5I_type_t obj_type; /* Type of object to use */ + H5F_scope_t scope; /* Scope of flush operation */ + } flush; + + /* H5VL_FILE_REOPEN */ + struct { + void **file; /* File object for new file (OUT) */ + } reopen; + + /* H5VL_FILE_IS_ACCESSIBLE */ + struct { + const char *filename; /* Name of file to check */ + hid_t fapl_id; /* File access property list to use */ + hbool_t * accessible; /* Whether file is accessible with FAPL settings (OUT) */ + } is_accessible; + + /* H5VL_FILE_DELETE */ + struct { + const char *filename; /* Name of file to delete */ + hid_t fapl_id; /* File access property list to use */ + } del; + + /* H5VL_FILE_IS_EQUAL */ + struct { + void * obj2; /* Second file object to compare against */ + hbool_t *same_file; /* Whether files are the same (OUT) */ + } is_equal; + } args; +} H5VL_file_specific_args_t; + /* Typedef for VOL connector file optional VOL operations */ typedef int H5VL_file_optional_t; -/* types for group GET callback */ +/* Values for group 'get' operation */ typedef enum H5VL_group_get_t { H5VL_GROUP_GET_GCPL, /* group creation property list */ H5VL_GROUP_GET_INFO /* group info */ } H5VL_group_get_t; -/* types for group SPECFIC callback */ -typedef enum H5VL_group_specific_t { H5VL_GROUP_FLUSH, H5VL_GROUP_REFRESH } H5VL_group_specific_t; +/* Parameters for group 'get_info' operation */ +typedef struct H5VL_group_get_info_args_t { + H5VL_loc_params_t loc_params; /* Location parameters for object access */ + H5G_info_t * ginfo; /* Group info (OUT) */ +} H5VL_group_get_info_args_t; + +/* Parameters for group 'get' operations */ +typedef struct H5VL_group_get_args_t { + H5VL_group_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_GROUP_GET_GCPL */ + struct { + hid_t gcpl_id; /* Group creation property list (OUT) */ + } get_gcpl; + + /* H5VL_GROUP_GET_INFO */ + H5VL_group_get_info_args_t get_info; /* Group info */ + } args; +} H5VL_group_get_args_t; + +/* Values for group 'specific' operation */ +typedef enum H5VL_group_specific_t { + H5VL_GROUP_MOUNT, /* Mount a file on a group */ + H5VL_GROUP_UNMOUNT, /* Unmount a file on a group */ + H5VL_GROUP_FLUSH, /* H5Gflush */ + H5VL_GROUP_REFRESH /* H5Grefresh */ +} H5VL_group_specific_t; + +/* Parameters for group 'mount' operation */ +typedef struct H5VL_group_spec_mount_args_t { + const char *name; /* Name of location to mount child file */ + void * child_file; /* Pointer to child file object */ + hid_t fmpl_id; /* File mount property list to use */ +} H5VL_group_spec_mount_args_t; + +/* Parameters for group 'specific' operations */ +typedef struct H5VL_group_specific_args_t { + H5VL_group_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_GROUP_MOUNT */ + H5VL_group_spec_mount_args_t mount; + + /* H5VL_GROUP_UNMOUNT */ + struct { + const char *name; /* Name of location to unmount child file */ + } unmount; + + /* H5VL_GROUP_FLUSH */ + struct { + hid_t grp_id; /* Group ID (IN) */ + } flush; + + /* H5VL_GROUP_REFRESH */ + struct { + hid_t grp_id; /* Group ID (IN) */ + } refresh; + } args; +} H5VL_group_specific_args_t; /* Typedef for VOL connector group optional VOL operations */ typedef int H5VL_group_optional_t; -/* link create types for VOL */ -typedef enum H5VL_link_create_type_t { +/* Link create types for VOL */ +typedef enum H5VL_link_create_t { H5VL_LINK_CREATE_HARD, H5VL_LINK_CREATE_SOFT, H5VL_LINK_CREATE_UD -} H5VL_link_create_type_t; +} H5VL_link_create_t; -/* types for link GET callback */ +/* Parameters for link 'create' operations */ +typedef struct H5VL_link_create_args_t { + H5VL_link_create_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_LINK_CREATE_HARD */ + struct { + void * curr_obj; /* Current object */ + H5VL_loc_params_t curr_loc_params; /* Location parameters for current object */ + } hard; + + /* H5VL_LINK_CREATE_SOFT */ + struct { + const char *target; /* Target of soft link */ + } soft; + + /* H5VL_LINK_CREATE_UD */ + struct { + H5L_type_t type; /* Type of link to create */ + const void *buf; /* Buffer that contains link info */ + size_t buf_size; /* Size of link info buffer */ + } ud; + } args; +} H5VL_link_create_args_t; + +/* Values for link 'get' operation */ typedef enum H5VL_link_get_t { H5VL_LINK_GET_INFO, /* link info */ H5VL_LINK_GET_NAME, /* link name */ H5VL_LINK_GET_VAL /* link value */ } H5VL_link_get_t; -/* types for link SPECIFIC callback */ +/* Parameters for link 'get' operations */ +typedef struct H5VL_link_get_args_t { + H5VL_link_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_LINK_GET_INFO */ + struct { + H5L_info2_t *linfo; /* Pointer to link's info (OUT) */ + } get_info; + + /* H5VL_LINK_GET_NAME */ + struct { + size_t name_size; /* Size of link name buffer (IN) */ + char * name; /* Buffer for link name (OUT) */ + size_t *name_len; /* Actual length of link name (OUT) */ + } get_name; + + /* H5VL_LINK_GET_VAL */ + struct { + size_t buf_size; /* Size of link value buffer (IN) */ + void * buf; /* Buffer for link value (OUT) */ + } get_val; + } args; +} H5VL_link_get_args_t; + +/* Values for link 'specific' operation */ typedef enum H5VL_link_specific_t { H5VL_LINK_DELETE, /* H5Ldelete(_by_idx) */ H5VL_LINK_EXISTS, /* link existence */ H5VL_LINK_ITER /* H5Literate/visit(_by_name) */ } H5VL_link_specific_t; +/* Parameters for link 'iterate' operation */ +typedef struct H5VL_link_iterate_args_t { + hbool_t recursive; /* Whether iteration is recursive */ + H5_index_t idx_type; /* Type of index to iterate over */ + H5_iter_order_t order; /* Order of index iteration */ + hsize_t * idx_p; /* Start/stop iteration index (OUT) */ + H5L_iterate2_t op; /* Iteration callback function */ + void * op_data; /* Iteration callback context */ +} H5VL_link_iterate_args_t; + +/* Parameters for link 'specific' operations */ +typedef struct H5VL_link_specific_args_t { + H5VL_link_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_LINK_DELETE */ + /* No args */ + + /* H5VL_LINK_EXISTS */ + struct { + hbool_t *exists; /* Whether link exists (OUT) */ + } exists; + + /* H5VL_LINK_ITER */ + H5VL_link_iterate_args_t iterate; + } args; +} H5VL_link_specific_args_t; + /* Typedef and values for native VOL connector link optional VOL operations */ typedef int H5VL_link_optional_t; /* (No optional link VOL operations currently) */ -/* types for object GET callback */ +/* Values for object 'get' operation */ typedef enum H5VL_object_get_t { H5VL_OBJECT_GET_FILE, /* object file */ H5VL_OBJECT_GET_NAME, /* object name */ @@ -174,7 +678,38 @@ typedef enum H5VL_object_get_t { H5VL_OBJECT_GET_INFO /* H5Oget_info(_by_idx|name) */ } H5VL_object_get_t; -/* types for object SPECIFIC callback */ +/* Parameters for object 'get' operations */ +typedef struct H5VL_object_get_args_t { + H5VL_object_get_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_OBJECT_GET_FILE */ + struct { + void **file; /* File object (OUT) */ + } get_file; + + /* H5VL_OBJECT_GET_NAME */ + struct { + size_t buf_size; /* Size of name buffer (IN) */ + char * buf; /* Buffer for name (OUT) */ + size_t *name_len; /* Actual length of name (OUT) */ + } get_name; + + /* H5VL_OBJECT_GET_TYPE */ + struct { + H5O_type_t *obj_type; /* Type of object (OUT) */ + } get_type; + + /* H5VL_OBJECT_GET_INFO */ + struct { + unsigned fields; /* Flags for fields to retrieve */ + H5O_info2_t *oinfo; /* Pointer to object info (OUT) */ + } get_info; + } args; +} H5VL_object_get_args_t; + +/* Values for object 'specific' operation */ typedef enum H5VL_object_specific_t { H5VL_OBJECT_CHANGE_REF_COUNT, /* H5Oincr/decr_refcount */ H5VL_OBJECT_EXISTS, /* H5Oexists_by_name */ @@ -184,6 +719,51 @@ typedef enum H5VL_object_specific_t { H5VL_OBJECT_REFRESH /* H5{D|G|O|T}refresh */ } H5VL_object_specific_t; +/* Parameters for object 'visit' operation */ +typedef struct H5VL_object_visit_args_t { + H5_index_t idx_type; /* Type of index to iterate over */ + H5_iter_order_t order; /* Order of index iteration */ + unsigned fields; /* Flags for fields to provide in 'info' object for 'op' callback */ + H5O_iterate2_t op; /* Iteration callback function */ + void * op_data; /* Iteration callback context */ +} H5VL_object_visit_args_t; + +/* Parameters for object 'specific' operations */ +typedef struct H5VL_object_specific_args_t { + H5VL_object_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_OBJECT_CHANGE_REF_COUNT */ + struct { + int delta; /* Amount to modify object's refcount */ + } change_rc; + + /* H5VL_OBJECT_EXISTS */ + struct { + hbool_t *exists; /* Whether object exists (OUT) */ + } exists; + + /* H5VL_OBJECT_LOOKUP */ + struct { + H5O_token_t *token_ptr; /* Pointer to token for lookup (OUT) */ + } lookup; + + /* H5VL_OBJECT_VISIT */ + H5VL_object_visit_args_t visit; + + /* H5VL_OBJECT_FLUSH */ + struct { + hid_t obj_id; /* Object ID (IN) */ + } flush; + + /* H5VL_OBJECT_REFRESH */ + struct { + hid_t obj_id; /* Object ID (IN) */ + } refresh; + } args; +} H5VL_object_specific_args_t; + /* Typedef for VOL connector object optional VOL operations */ typedef int H5VL_object_optional_t; @@ -200,82 +780,64 @@ typedef enum H5VL_request_status_t { H5VL_REQUEST_STATUS_CANCELED /* Operation has not completed and was canceled */ } H5VL_request_status_t; -/* types for async request SPECIFIC callback */ +/* Values for async request 'specific' operation */ typedef enum H5VL_request_specific_t { - H5VL_REQUEST_WAITANY, /* Wait until any request completes */ - H5VL_REQUEST_WAITSOME, /* Wait until at least one requesst completes */ - H5VL_REQUEST_WAITALL, /* Wait until all requests complete */ - H5VL_REQUEST_GET_ERR_STACK /* Retrieve error stack for failed operation */ + H5VL_REQUEST_GET_ERR_STACK, /* Retrieve error stack for failed operation */ + H5VL_REQUEST_GET_EXEC_TIME /* Retrieve execution time for operation */ } H5VL_request_specific_t; +/* Parameters for request 'specific' operations */ +typedef struct H5VL_request_specific_args_t { + H5VL_request_specific_t op_type; /* Operation to perform */ + + /* Parameters for each operation */ + union { + /* H5VL_REQUEST_GET_ERR_STACK */ + struct { + hid_t err_stack_id; /* Error stack ID for operation (OUT) */ + } get_err_stack; + + /* H5VL_REQUEST_GET_EXEC_TIME */ + struct { + uint64_t *exec_ts; /* Timestamp for start of task execution (OUT) */ + uint64_t *exec_time; /* Duration of task execution (in ns) (OUT) */ + } get_exec_time; + } args; +} H5VL_request_specific_args_t; + /* Typedef and values for native VOL connector request optional VOL operations */ typedef int H5VL_request_optional_t; /* (No optional request VOL operations currently) */ -/* types for 'blob' SPECIFIC callback */ +/* Values for 'blob' 'specific' operation */ typedef enum H5VL_blob_specific_t { - H5VL_BLOB_DELETE, /* Delete a blob (by ID) */ - H5VL_BLOB_GETSIZE, /* Get size of blob */ - H5VL_BLOB_ISNULL, /* Check if a blob ID is "null" */ - H5VL_BLOB_SETNULL /* Set a blob ID to the connector's "null" blob ID value */ + H5VL_BLOB_DELETE, /* Delete a blob (by ID) */ + H5VL_BLOB_ISNULL, /* Check if a blob ID is "null" */ + H5VL_BLOB_SETNULL /* Set a blob ID to the connector's "null" blob ID value */ } H5VL_blob_specific_t; -/* Typedef and values for native VOL connector blob optional VOL operations */ -typedef int H5VL_blob_optional_t; -/* (No optional blob VOL operations currently) */ - -/* Types for different ways that objects are located in an HDF5 container */ -typedef enum H5VL_loc_type_t { - H5VL_OBJECT_BY_SELF, - H5VL_OBJECT_BY_NAME, - H5VL_OBJECT_BY_IDX, - H5VL_OBJECT_BY_TOKEN -} H5VL_loc_type_t; +/* Parameters for blob 'specific' operations */ +typedef struct H5VL_blob_specific_args_t { + H5VL_blob_specific_t op_type; /* Operation to perform */ -typedef struct H5VL_loc_by_name { - const char *name; - hid_t lapl_id; -} H5VL_loc_by_name_t; - -typedef struct H5VL_loc_by_idx { - const char * name; - H5_index_t idx_type; - H5_iter_order_t order; - hsize_t n; - hid_t lapl_id; -} H5VL_loc_by_idx_t; + /* Parameters for each operation */ + union { + /* H5VL_BLOB_DELETE */ + /* No args */ -typedef struct H5VL_loc_by_token { - H5O_token_t *token; -} H5VL_loc_by_token_t; + /* H5VL_BLOB_ISNULL */ + struct { + hbool_t *isnull; /* Whether blob ID is "null" (OUT) */ + } is_null; -/* Structure to hold parameters for object locations. - * Either: BY_SELF, BY_NAME, BY_IDX, BY_TOKEN - * - * Note: Leave loc_by_token as the first union member so we - * can perform the simplest initialization of the struct - * without raising warnings. - * - * Note: BY_SELF requires no union members. - */ -typedef struct H5VL_loc_params_t { - H5I_type_t obj_type; - H5VL_loc_type_t type; - union { - H5VL_loc_by_token_t loc_by_token; - H5VL_loc_by_name_t loc_by_name; - H5VL_loc_by_idx_t loc_by_idx; - } loc_data; -} H5VL_loc_params_t; + /* H5VL_BLOB_SETNULL */ + /* No args */ + } args; +} H5VL_blob_specific_args_t; -/* Info for H5VL_FILE_GET_CONT_INFO */ -typedef struct H5VL_file_cont_info_t { - unsigned version; /* version information (keep first) */ - uint64_t feature_flags; /* Container feature flags */ - /* (none currently defined) */ - size_t token_size; /* Size of tokens */ - size_t blob_id_size; /* Size of blob IDs */ -} H5VL_file_cont_info_t; +/* Typedef and values for native VOL connector blob optional VOL operations */ +typedef int H5VL_blob_optional_t; +/* (No optional blob VOL operations currently) */ /* VOL connector info fields & callbacks */ typedef struct H5VL_info_class_t { @@ -310,11 +872,10 @@ typedef struct H5VL_attr_class_t { hid_t dxpl_id, void **req); herr_t (*read)(void *attr, hid_t mem_type_id, void *buf, hid_t dxpl_id, void **req); herr_t (*write)(void *attr, hid_t mem_type_id, const void *buf, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); - herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); - herr_t (*optional)(void *obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req); + herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_specific_args_t *args, + hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); herr_t (*close)(void *attr, hid_t dxpl_id, void **req); } H5VL_attr_class_t; @@ -328,11 +889,9 @@ typedef struct H5VL_dataset_class_t { void *buf, void **req); herr_t (*write)(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf, void **req); - herr_t (*get)(void *obj, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); - herr_t (*specific)(void *obj, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); - herr_t (*optional)(void *obj, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **req); + herr_t (*specific)(void *obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); herr_t (*close)(void *dset, hid_t dxpl_id, void **req); } H5VL_dataset_class_t; @@ -342,11 +901,9 @@ typedef struct H5VL_datatype_class_t { hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, void **req); void *(*open)(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); - herr_t (*specific)(void *obj, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); - herr_t (*optional)(void *obj, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req); + herr_t (*specific)(void *obj, H5VL_datatype_specific_args_t *args, hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); herr_t (*close)(void *dt, hid_t dxpl_id, void **req); } H5VL_datatype_class_t; @@ -355,11 +912,9 @@ typedef struct H5VL_file_class_t { void *(*create)(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req); void *(*open)(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); - herr_t (*specific)(void *obj, H5VL_file_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); - herr_t (*optional)(void *obj, H5VL_file_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req); + herr_t (*specific)(void *obj, H5VL_file_specific_args_t *args, hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); herr_t (*close)(void *file, hid_t dxpl_id, void **req); } H5VL_file_class_t; @@ -369,30 +924,28 @@ typedef struct H5VL_group_class_t { hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req); void *(*open)(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); - herr_t (*specific)(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); - herr_t (*optional)(void *obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req); + herr_t (*specific)(void *obj, H5VL_group_specific_args_t *args, hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); herr_t (*close)(void *grp, hid_t dxpl_id, void **req); } H5VL_group_class_t; /* H5L routines */ typedef struct H5VL_link_class_t { - herr_t (*create)(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, - hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, va_list arguments); + herr_t (*create)(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); herr_t (*copy)(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); herr_t (*move)(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); - herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); - herr_t (*optional)(void *obj, H5VL_link_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t *args, hid_t dxpl_id, + void **req); + herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_args_t *args, + hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); } H5VL_link_class_t; /* H5O routines */ @@ -402,12 +955,12 @@ typedef struct H5VL_object_class_t { herr_t (*copy)(void *src_obj, const H5VL_loc_params_t *loc_params1, const char *src_name, void *dst_obj, const H5VL_loc_params_t *loc_params2, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); - herr_t (*get)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); - herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); - herr_t (*optional)(void *obj, H5VL_object_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + herr_t (*get)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_args_t *args, hid_t dxpl_id, + void **req); + herr_t (*specific)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_specific_args_t *args, + hid_t dxpl_id, void **req); + herr_t (*optional)(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req); } H5VL_object_class_t; /* Asynchronous request 'notify' callback */ @@ -427,6 +980,7 @@ struct H5VL_class_t; /* Container/connector introspection routines */ typedef struct H5VL_introspect_class_t { herr_t (*get_conn_cls)(void *obj, H5VL_get_conn_lvl_t lvl, const struct H5VL_class_t **conn_cls); + herr_t (*get_cap_flags)(const void *info, unsigned *cap_flags); herr_t (*opt_query)(void *obj, H5VL_subclass_t cls, int opt_type, uint64_t *flags); } H5VL_introspect_class_t; @@ -435,8 +989,8 @@ typedef struct H5VL_request_class_t { herr_t (*wait)(void *req, uint64_t timeout, H5VL_request_status_t *status); herr_t (*notify)(void *req, H5VL_request_notify_t cb, void *ctx); herr_t (*cancel)(void *req, H5VL_request_status_t *status); - herr_t (*specific)(void *req, H5VL_request_specific_t specific_type, va_list arguments); - herr_t (*optional)(void *req, H5VL_request_optional_t opt_type, va_list arguments); + herr_t (*specific)(void *req, H5VL_request_specific_args_t *args); + herr_t (*optional)(void *req, H5VL_optional_args_t *args); herr_t (*free)(void *req); } H5VL_request_class_t; @@ -444,8 +998,8 @@ typedef struct H5VL_request_class_t { typedef struct H5VL_blob_class_t { herr_t (*put)(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); herr_t (*get)(void *obj, const void *blob_id, void *buf, size_t size, void *ctx); - herr_t (*specific)(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); - herr_t (*optional)(void *obj, void *blob_id, H5VL_blob_optional_t opt_type, va_list arguments); + herr_t (*specific)(void *obj, void *blob_id, H5VL_blob_specific_args_t *args); + herr_t (*optional)(void *obj, void *blob_id, H5VL_optional_args_t *args); } H5VL_blob_class_t; /* Object token routines */ @@ -490,8 +1044,8 @@ typedef struct H5VL_class_t { H5VL_token_class_t token_cls; /**< VOL connector object token class callbacks */ /* Catch-all */ - herr_t (*optional)(void *obj, int op_type, hid_t dxpl_id, void **req, - va_list arguments); /**< Optional callback */ + herr_t (*optional)(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); /**< Optional callback */ } H5VL_class_t; //! <!-- [H5VL_class_t_snip] --> @@ -557,6 +1111,53 @@ H5_DLL hid_t H5VLpeek_connector_id_by_name(const char *name); */ H5_DLL hid_t H5VLpeek_connector_id_by_value(H5VL_class_value_t value); +/* User-defined optional operations */ +H5_DLL herr_t H5VLregister_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val); +H5_DLL herr_t H5VLfind_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val); +H5_DLL herr_t H5VLunregister_opt_operation(H5VL_subclass_t subcls, const char *op_name); +H5_DLL herr_t H5VLattr_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t attr_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLdataset_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t dset_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLdatatype_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t type_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLfile_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t file_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLgroup_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t group_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLlink_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *name, hid_t lapl_id, H5VL_optional_args_t *args, + hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLobject_optional_op(const char *app_file, const char *app_func, unsigned app_line, + hid_t loc_id, const char *name, hid_t lapl_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +H5_DLL herr_t H5VLrequest_optional_op(void *req, hid_t connector_id, H5VL_optional_args_t *args); + +/* API Wrappers for "optional_op" routines */ +/* (Must be defined _after_ the function prototype) */ +/* (And must only defined when included in application code, not the library) */ +#ifndef H5VL_MODULE +/* Inject application compile-time macros into function calls */ +#define H5VLattr_optional_op(...) H5VLattr_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLdataset_optional_op(...) H5VLdataset_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLdatatype_optional_op(...) H5VLdatatype_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLfile_optional_op(...) H5VLfile_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLgroup_optional_op(...) H5VLgroup_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLlink_optional_op(...) H5VLlink_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) +#define H5VLobject_optional_op(...) H5VLobject_optional_op(__FILE__, __func__, __LINE__, __VA_ARGS__) + +/* Define "wrapper" versions of function calls, to allow compile-time values to + * be passed in by language wrapper or library layer on top of HDF5. + */ +#define H5VLattr_optional_op_wrap H5_NO_EXPAND(H5VLattr_optional_op) +#define H5VLdataset_optional_op_wrap H5_NO_EXPAND(H5VLdataset_optional_op) +#define H5VLdatatype_optional_op_wrap H5_NO_EXPAND(H5VLdatatype_optional_op) +#define H5VLfile_optional_op_wrap H5_NO_EXPAND(H5VLfile_optional_op) +#define H5VLgroup_optional_op_wrap H5_NO_EXPAND(H5VLgroup_optional_op) +#define H5VLlink_optional_op_wrap H5_NO_EXPAND(H5VLlink_optional_op) +#define H5VLobject_optional_op_wrap H5_NO_EXPAND(H5VLobject_optional_op) +#endif /* H5VL_MODULE */ + #ifdef __cplusplus } #endif diff --git a/src/H5VLconnector_passthru.h b/src/H5VLconnector_passthru.h index 720740f..17029f0 100644 --- a/src/H5VLconnector_passthru.h +++ b/src/H5VLconnector_passthru.h @@ -58,8 +58,9 @@ extern "C" { H5_DLL herr_t H5VLcmp_connector_cls(int *cmp, hid_t connector_id1, hid_t connector_id2); H5_DLL hid_t H5VLwrap_register(void *obj, H5I_type_t type); H5_DLL herr_t H5VLretrieve_lib_state(void **state); +H5_DLL herr_t H5VLstart_lib_state(void); H5_DLL herr_t H5VLrestore_lib_state(const void *state); -H5_DLL herr_t H5VLreset_lib_state(void); +H5_DLL herr_t H5VLfinish_lib_state(void); H5_DLL herr_t H5VLfree_lib_state(void *state); /* Pass-through callbacks */ @@ -92,13 +93,12 @@ H5_DLL herr_t H5VLattr_read(void *attr, hid_t connector_id, hid_t dtype_id, void void **req); H5_DLL herr_t H5VLattr_write(void *attr, hid_t connector_id, hid_t dtype_id, const void *buf, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); +H5_DLL herr_t H5VLattr_get(void *obj, hid_t connector_id, H5VL_attr_get_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLattr_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VLattr_optional(void *obj, hid_t connector_id, H5VL_attr_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLattr_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLattr_close(void *attr, hid_t connector_id, hid_t dxpl_id, void **req); /* Public wrappers for dataset callbacks */ @@ -111,12 +111,12 @@ H5_DLL herr_t H5VLdataset_read(void *dset, hid_t connector_id, hid_t mem_type_id hid_t file_space_id, hid_t plist_id, void *buf, void **req); H5_DLL herr_t H5VLdataset_write(void *dset, hid_t connector_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf, void **req); -H5_DLL herr_t H5VLdataset_get(void *dset, hid_t connector_id, H5VL_dataset_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -H5_DLL herr_t H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_dataset_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +H5_DLL herr_t H5VLdataset_get(void *dset, hid_t connector_id, H5VL_dataset_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VLdataset_specific(void *obj, hid_t connector_id, H5VL_dataset_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLdataset_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLdataset_close(void *dset, hid_t connector_id, hid_t dxpl_id, void **req); /* Public wrappers for named datatype callbacks */ @@ -125,24 +125,24 @@ H5_DLL void * H5VLdatatype_commit(void *obj, const H5VL_loc_params_t *loc_params hid_t dxpl_id, void **req); H5_DLL void * H5VLdatatype_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VLdatatype_get(void *dt, hid_t connector_id, H5VL_datatype_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -H5_DLL herr_t H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_datatype_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); +H5_DLL herr_t H5VLdatatype_get(void *dt, hid_t connector_id, H5VL_datatype_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VLdatatype_specific(void *obj, hid_t connector_id, H5VL_datatype_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLdatatype_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLdatatype_close(void *dt, hid_t connector_id, hid_t dxpl_id, void **req); /* Public wrappers for file callbacks */ H5_DLL void * H5VLfile_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req); H5_DLL void * H5VLfile_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VLfile_get(void *file, hid_t connector_id, H5VL_file_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -H5_DLL herr_t H5VLfile_optional(void *obj, hid_t connector_id, H5VL_file_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +H5_DLL herr_t H5VLfile_get(void *file, hid_t connector_id, H5VL_file_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VLfile_specific(void *obj, hid_t connector_id, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VLfile_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLfile_close(void *file, hid_t connector_id, hid_t dxpl_id, void **req); /* Public wrappers for group callbacks */ @@ -151,18 +151,17 @@ H5_DLL void * H5VLgroup_create(void *obj, const H5VL_loc_params_t *loc_params, h void **req); H5_DLL void * H5VLgroup_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -H5_DLL herr_t H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +H5_DLL herr_t H5VLgroup_get(void *obj, hid_t connector_id, H5VL_group_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VLgroup_specific(void *obj, hid_t connector_id, H5VL_group_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLgroup_optional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VLgroup_close(void *grp, hid_t connector_id, hid_t dxpl_id, void **req); /* Public wrappers for link callbacks */ -H5_DLL herr_t H5VLlink_create(H5VL_link_create_type_t create_type, void *obj, - const H5VL_loc_params_t *loc_params, hid_t connector_id, hid_t lcpl_id, - hid_t lapl_id, hid_t dxpl_id, void **req, va_list arguments); +H5_DLL herr_t H5VLlink_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VLlink_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); @@ -170,12 +169,11 @@ H5_DLL herr_t H5VLlink_move(void *src_obj, const H5VL_loc_params_t *loc_params1, const H5VL_loc_params_t *loc_params2, hid_t connector_id, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VLlink_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VLlink_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VLlink_optional(void *obj, hid_t connector_id, H5VL_link_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLlink_optional(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Public wrappers for object callbacks */ H5_DLL void * H5VLobject_open(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, @@ -184,16 +182,16 @@ H5_DLL herr_t H5VLobject_copy(void *src_obj, const H5VL_loc_params_t *loc_params void *dst_obj, const H5VL_loc_params_t *loc_params2, const char *dst_name, hid_t connector_id, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VLobject_get(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments); + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VLobject_specific(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VLobject_optional(void *obj, hid_t connector_id, H5VL_object_optional_t opt_type, - hid_t dxpl_id, void **req, va_list arguments); + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VLobject_optional(void *obj, const H5VL_loc_params_t *loc_params, hid_t connector_id, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Public wrappers for connector/container introspection callbacks */ H5_DLL herr_t H5VLintrospect_get_conn_cls(void *obj, hid_t connector_id, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); +H5_DLL herr_t H5VLintrospect_get_cap_flags(const void *info, hid_t connector_id, unsigned *cap_flags); H5_DLL herr_t H5VLintrospect_opt_query(void *obj, hid_t connector_id, H5VL_subclass_t subcls, int opt_type, uint64_t *flags); @@ -202,10 +200,8 @@ H5_DLL herr_t H5VLrequest_wait(void *req, hid_t connector_id, uint64_t timeout, H5VL_request_status_t *status); H5_DLL herr_t H5VLrequest_notify(void *req, hid_t connector_id, H5VL_request_notify_t cb, void *ctx); H5_DLL herr_t H5VLrequest_cancel(void *req, hid_t connector_id, H5VL_request_status_t *status); -H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_t specific_type, - va_list arguments); -H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, H5VL_request_optional_t opt_type, - va_list arguments); +H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_specific_args_t *args); +H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, H5VL_optional_args_t *args); H5_DLL herr_t H5VLrequest_free(void *req, hid_t connector_id); /* Public wrappers for blob callbacks */ @@ -214,9 +210,8 @@ H5_DLL herr_t H5VLblob_put(void *obj, hid_t connector_id, const void *buf, size_ H5_DLL herr_t H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf, size_t size, void *ctx); H5_DLL herr_t H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, - H5VL_blob_specific_t specific_type, va_list arguments); -H5_DLL herr_t H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_optional_t opt_type, - va_list arguments); + H5VL_blob_specific_args_t *args); +H5_DLL herr_t H5VLblob_optional(void *obj, hid_t connector_id, void *blob_id, H5VL_optional_args_t *args); /* Public wrappers for token callbacks */ H5_DLL herr_t H5VLtoken_cmp(void *obj, hid_t connector_id, const H5O_token_t *token1, @@ -227,8 +222,8 @@ H5_DLL herr_t H5VLtoken_from_str(void *obj, H5I_type_t obj_type, hid_t connector H5O_token_t *token); /* Public wrappers for generic 'optional' callback */ -H5_DLL herr_t H5VLoptional(void *obj, hid_t connector_id, int op_type, hid_t dxpl_id, void **req, - va_list arguments); +H5_DLL herr_t H5VLoptional(void *obj, hid_t connector_id, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); #ifdef __cplusplus } diff --git a/src/H5VLdyn_ops.c b/src/H5VLdyn_ops.c new file mode 100644 index 0000000..0992452 --- /dev/null +++ b/src/H5VLdyn_ops.c @@ -0,0 +1,334 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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: The Virtual Object Layer as described in documentation. + * The pupose is to provide an abstraction on how to access the + * underlying HDF5 container, whether in a local file with + * a specific file format, or remotely on other machines, etc... + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5VLmodule.h" /* This source code file is part of the H5VL module */ + +/***********/ +/* Headers */ +/***********/ + +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5SLprivate.h" /* Skip lists */ +#include "H5VLpkg.h" /* Virtual Object Layer */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Dynamic operation info */ +typedef struct H5VL_dyn_op_t { + char *op_name; /* Name of operation */ + int op_val; /* Value of operation */ +} H5VL_dyn_op_t; + +/********************/ +/* Local Prototypes */ +/********************/ +static void H5VL__release_dyn_op(H5VL_dyn_op_t *dyn_op); + +/*********************/ +/* Package Variables */ +/*********************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + +/* The current optional operation values */ +static int H5VL_opt_vals_g[H5VL_SUBCLS_TOKEN + 1] = { + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_NONE */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_INFO */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_WRAP */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_ATTR */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_DATASET */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_DATATYPE */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_FILE */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_GROUP */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_LINK */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_OBJECT */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_REQUEST */ + H5VL_RESERVED_NATIVE_OPTIONAL, /* H5VL_SUBCLS_BLOB */ + H5VL_RESERVED_NATIVE_OPTIONAL /* H5VL_SUBCLS_TOKEN */ +}; + +/* The current optional operations' info */ +static H5SL_t *H5VL_opt_ops_g[H5VL_SUBCLS_TOKEN + 1] = { + NULL, /* H5VL_SUBCLS_NONE */ + NULL, /* H5VL_SUBCLS_INFO */ + NULL, /* H5VL_SUBCLS_WRAP */ + NULL, /* H5VL_SUBCLS_ATTR */ + NULL, /* H5VL_SUBCLS_DATASET */ + NULL, /* H5VL_SUBCLS_DATATYPE */ + NULL, /* H5VL_SUBCLS_FILE */ + NULL, /* H5VL_SUBCLS_GROUP */ + NULL, /* H5VL_SUBCLS_LINK */ + NULL, /* H5VL_SUBCLS_OBJECT */ + NULL, /* H5VL_SUBCLS_REQUEST */ + NULL, /* H5VL_SUBCLS_BLOB */ + NULL /* H5VL_SUBCLS_TOKEN */ +}; + +/* Declare a free list to manage the H5VL_class_t struct */ +H5FL_DEFINE_STATIC(H5VL_dyn_op_t); + +/*--------------------------------------------------------------------------- + * Function: H5VL__release_dyn_op + * + * Purpose: Release a dynamic operation info node + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +static void +H5VL__release_dyn_op(H5VL_dyn_op_t *dyn_op) +{ + FUNC_ENTER_STATIC_NOERR + + H5MM_xfree(dyn_op->op_name); + H5FL_FREE(H5VL_dyn_op_t, dyn_op); + + FUNC_LEAVE_NOAPI_VOID +} /* H5VL__release_dyn_op() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__term_opt_operation_cb + * + * Purpose: Callback for releasing a dynamically registered operation info + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +static herr_t +H5VL__term_opt_operation_cb(void *_item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op_data) +{ + H5VL_dyn_op_t *item = (H5VL_dyn_op_t *)_item; /* Item to release */ + + FUNC_ENTER_STATIC_NOERR + + /* Release the dynamically registered operation info */ + H5VL__release_dyn_op(item); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5VL__term_opt_operation_cb() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__term_opt_operation + * + * Purpose: Terminate the dynamically registered optional operations, + * releasing all operations. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__term_opt_operation(void) +{ + size_t subcls; /* Index over the elements of operation array */ + + FUNC_ENTER_PACKAGE_NOERR + + /* Iterate over the VOL subclasses */ + for (subcls = 0; subcls < NELMTS(H5VL_opt_vals_g); subcls++) + if (H5VL_opt_ops_g[subcls]) + H5SL_destroy(H5VL_opt_ops_g[subcls], H5VL__term_opt_operation_cb, NULL); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5VL__term_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__register_opt_operation + * + * Purpose: Register a new optional operation for a VOL object subclass. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__register_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val) +{ + H5VL_dyn_op_t *new_op; /* Info about new operation */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(op_val); + HDassert(op_name && *op_name); + + /* Check for duplicate operation */ + if (H5VL_opt_ops_g[subcls]) { + if (NULL != H5SL_search(H5VL_opt_ops_g[subcls], op_name)) + HGOTO_ERROR(H5E_VOL, H5E_EXISTS, FAIL, "operation name already exists") + } /* end if */ + else { + /* Create skip list for operation of this subclass */ + if (NULL == (H5VL_opt_ops_g[subcls] = H5SL_create(H5SL_TYPE_STR, NULL))) + HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "can't create skip list for operations") + } /* end else */ + + /* Register new operation */ + if (NULL == (new_op = H5FL_CALLOC(H5VL_dyn_op_t))) + HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate memory for dynamic operation info") + if (NULL == (new_op->op_name = H5MM_strdup(op_name))) + HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, FAIL, "can't allocate name for dynamic operation info") + new_op->op_val = H5VL_opt_vals_g[subcls]++; + + /* Insert into subclass's skip list */ + if (H5SL_insert(H5VL_opt_ops_g[subcls], new_op, new_op->op_name) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, FAIL, "can't insert operation info into skip list") + + /* Return the next operation value to the caller */ + *op_val = new_op->op_val; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5VL__register_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__num_opt_operation + * + * Purpose: Returns the # of currently registered optional operations + * + * Return: # of registered optional operations / <can't fail> + * + *--------------------------------------------------------------------------- + */ +size_t +H5VL__num_opt_operation(void) +{ + size_t subcls; /* Index over the elements of operation array */ + size_t ret_value = 0; /* Return value */ + + FUNC_ENTER_PACKAGE_NOERR + + /* Iterate over the VOL subclasses */ + for (subcls = 0; subcls < NELMTS(H5VL_opt_vals_g); subcls++) + if (H5VL_opt_ops_g[subcls]) + ret_value += H5SL_count(H5VL_opt_ops_g[subcls]); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5VL__num_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__find_opt_operation + * + * Purpose: Look up a optional operation for a VOL object subclass, by name. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__find_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(op_val); + HDassert(op_name && *op_name); + + /* Check for dynamic operations in the VOL subclass */ + if (H5VL_opt_ops_g[subcls]) { + H5VL_dyn_op_t *dyn_op; /* Info about operation */ + + /* Search for dynamic operation with correct name */ + if (NULL == (dyn_op = H5SL_search(H5VL_opt_ops_g[subcls], op_name))) + HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered") + + /* Set operation value for user */ + *op_val = dyn_op->op_val; + } /* end if */ + else + HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5VL__find_opt_operation() */ + +/*--------------------------------------------------------------------------- + * Function: H5VL__unregister_opt_operation + * + * Purpose: Unregister a optional operation for a VOL object subclass, by name. + * + * Return: Success: Non-negative + * Failure: Negative + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__unregister_opt_operation(H5VL_subclass_t subcls, const char *op_name) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(op_name && *op_name); + + /* Check for dynamic operations in the VOL subclass */ + if (H5VL_opt_ops_g[subcls]) { + H5VL_dyn_op_t *dyn_op; /* Info about operation */ + + /* Search for dynamic operation with correct name */ + if (NULL == (dyn_op = H5SL_remove(H5VL_opt_ops_g[subcls], op_name))) + HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered") + + /* Release the info for the operation */ + H5VL__release_dyn_op(dyn_op); + + /* Close the skip list, if no more operations in it */ + if (0 == H5SL_count(H5VL_opt_ops_g[subcls])) { + if (H5SL_close(H5VL_opt_ops_g[subcls]) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "can't close dyn op skip list") + H5VL_opt_ops_g[subcls] = NULL; + } /* end if */ + } /* end if */ + else + HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "operation name isn't registered") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5VL__unregister_opt_operation() */ diff --git a/src/H5VLint.c b/src/H5VLint.c index 500e075..70c8112 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -88,7 +88,6 @@ typedef struct { /********************/ static herr_t H5VL__free_cls(H5VL_class_t *cls, void **request); static int H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data); -static herr_t H5VL__set_def_conn(void); static void * H5VL__wrap_obj(void *obj, H5I_type_t obj_type); static H5VL_object_t *H5VL__new_vol_obj(H5I_type_t type, void *object, H5VL_t *vol_connector, hbool_t wrap_obj); @@ -194,6 +193,10 @@ H5VL_init_phase2(void) if (H5M_init() < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize map interface") + /* Sanity check default VOL connector */ + HDassert(H5VL_def_conn_s.connector_id == (-1)); + HDassert(H5VL_def_conn_s.connector_info == NULL); + /* Set up the default VOL connector in the default FAPL */ if (H5VL__set_def_conn() < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "unable to set default VOL connector") @@ -261,15 +264,22 @@ H5VL_term_package(void) n++; } /* end if */ else { - /* Destroy the VOL connector ID group */ - n += (H5I_dec_type_ref(H5I_VOL) > 0); - - /* Mark interface as closed */ - if (0 == n) - H5_PKG_INIT_VAR = FALSE; - } /* end else */ - } /* end else */ - } /* end if */ + if (H5VL__num_opt_operation() > 0) { + /* Unregister all dynamically registered optional operations */ + (void)H5VL__term_opt_operation(); + n++; + } /* end if */ + else { + /* Destroy the VOL connector ID group */ + n += (H5I_dec_type_ref(H5I_VOL) > 0); + + /* Mark interface as closed */ + if (0 == n) + H5_PKG_INIT_VAR = FALSE; + } /* end else */ + } /* end else */ + } /* end else */ + } /* end if */ FUNC_LEAVE_NOAPI(n) } /* end H5VL_term_package() */ @@ -365,7 +375,7 @@ H5VL__get_connector_cb(void *obj, hid_t id, void *_op_data) * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5VL__set_def_conn(void) { H5P_genplist_t *def_fapl; /* Default file access property list */ @@ -376,11 +386,16 @@ H5VL__set_def_conn(void) void * vol_info = NULL; /* VOL connector info */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC + FUNC_ENTER_PACKAGE - /* Sanity check */ - HDassert(H5VL_def_conn_s.connector_id == (-1)); - HDassert(H5VL_def_conn_s.connector_info == NULL); + /* Reset default VOL connector, if it's set already */ + /* (Can happen during testing -QAK) */ + if (H5VL_def_conn_s.connector_id > 0) { + /* Release the default VOL connector */ + (void)H5VL_conn_free(&H5VL_def_conn_s); + H5VL_def_conn_s.connector_id = -1; + H5VL_def_conn_s.connector_info = NULL; + } /* end if */ /* Check for environment variable set */ env_var = HDgetenv("HDF5_VOL_CONNECTOR"); @@ -760,51 +775,47 @@ done: } /* end H5VL_register_using_existing_id() */ /*------------------------------------------------------------------------- - * Function: H5VL_register_using_vol_id + * Function: H5VL_new_connector * - * Purpose: Utility function to create a user ID for an object created - * or opened through the VOL. Uses the VOL connector's ID to - * get the connector information instead of it being passed in. + * Purpose: Utility function to create a connector for a connector ID. * - * Return: Success: A valid HDF5 ID - * Failure: H5I_INVALID_HID + * Return: Success: Pointer to a new connector object + * Failure: NULL * *------------------------------------------------------------------------- */ -hid_t -H5VL_register_using_vol_id(H5I_type_t type, void *obj, hid_t connector_id, hbool_t app_ref) +H5VL_t * +H5VL_new_connector(hid_t connector_id) { - H5VL_class_t *cls = NULL; /* VOL connector class */ - H5VL_t * connector = NULL; /* VOL connector struct */ - hbool_t conn_id_incr = FALSE; /* Whether the VOL connector ID has been incremented */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5VL_class_t *cls = NULL; /* VOL connector class */ + H5VL_t * connector = NULL; /* New VOL connector struct */ + hbool_t conn_id_incr = FALSE; /* Whether the VOL connector ID has been incremented */ + H5VL_t * ret_value = NULL; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_NOAPI(NULL) /* Get the VOL class object from the connector's ID */ if (NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) - HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL connector ID") + HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, NULL, "not a VOL connector ID") /* Setup VOL info struct */ if (NULL == (connector = H5FL_CALLOC(H5VL_t))) - HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, H5I_INVALID_HID, "can't allocate VOL info struct") + HGOTO_ERROR(H5E_VOL, H5E_CANTALLOC, NULL, "can't allocate VOL connector struct") connector->cls = cls; connector->id = connector_id; if (H5I_inc_ref(connector->id, FALSE) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTINC, H5I_INVALID_HID, "unable to increment ref count on VOL connector") + HGOTO_ERROR(H5E_VOL, H5E_CANTINC, NULL, "unable to increment ref count on VOL connector") conn_id_incr = TRUE; - /* Get an ID for the VOL object */ - if ((ret_value = H5VL_register(type, obj, connector, app_ref)) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") + /* Set return value */ + ret_value = connector; done: /* Clean up on error */ - if (ret_value < 0) { + if (NULL == ret_value) { /* Decrement VOL connector ID ref count on error */ if (conn_id_incr && H5I_dec_ref(connector_id) < 0) - HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, - "unable to decrement ref count on VOL connector") + HDONE_ERROR(H5E_VOL, H5E_CANTDEC, NULL, "unable to decrement ref count on VOL connector") /* Free VOL connector struct */ if (NULL != connector) @@ -812,6 +823,45 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_new_connector() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_register_using_vol_id + * + * Purpose: Utility function to create a user ID for an object created + * or opened through the VOL. Uses the VOL connector's ID to + * get the connector information instead of it being passed in. + * + * Return: Success: A valid HDF5 ID + * Failure: H5I_INVALID_HID + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_register_using_vol_id(H5I_type_t type, void *obj, hid_t connector_id, hbool_t app_ref) +{ + H5VL_t *connector = NULL; /* VOL connector struct */ + hid_t ret_value = H5I_INVALID_HID; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Create new VOL connector object, using the connector ID */ + if (NULL == (connector = H5VL_new_connector(connector_id))) + HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, H5I_INVALID_HID, "can't create VOL connector object") + + /* Get an ID for the VOL object */ + if ((ret_value = H5VL_register(type, obj, connector, app_ref)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register object handle") + +done: + /* Clean up on error */ + if (H5I_INVALID_HID == ret_value) + /* Release newly created connector */ + if (connector && H5VL_conn_dec_rc(connector) < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTDEC, H5I_INVALID_HID, + "unable to decrement ref count on VOL connector") + + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_register_using_vol_id() */ /*------------------------------------------------------------------------- @@ -1125,15 +1175,20 @@ H5VL_file_is_same(const H5VL_object_t *vol_obj1, const H5VL_object_t *vol_obj2, if (cmp_value) *same_file = FALSE; else { - void *obj2; /* Terminal object for second file */ + void * obj2; /* Terminal object for second file */ + H5VL_file_specific_args_t vol_cb_args; /* Arguments to VOL callback */ /* Get unwrapped (terminal) object for vol_obj2 */ if (NULL == (obj2 = H5VL_object_data(vol_obj2))) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get unwrapped object") - /* Make callback */ - if (H5VL_file_specific(vol_obj1, H5VL_FILE_IS_EQUAL, H5P_DATASET_XFER_DEFAULT, NULL, obj2, - same_file) < 0) + /* Set up VOL callback arguments */ + vol_cb_args.op_type = H5VL_FILE_IS_EQUAL; + vol_cb_args.args.is_equal.obj2 = obj2; + vol_cb_args.args.is_equal.same_file = same_file; + + /* Make 'are files equal' callback */ + if (H5VL_file_specific(vol_obj1, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "file specific failed") } /* end else */ @@ -2047,6 +2102,36 @@ done: } /* end H5VL_retrieve_lib_state() */ /*------------------------------------------------------------------------- + * Function: H5VL_start_lib_state + * + * Purpose: Opens a new internal state for the HDF5 library. + * + * Note: Currently just pushes a new API context state, but could be + * expanded in the future. + * + * Return: SUCCEED / FAIL + * + * Programmer: Quincey Koziol + * Friday, February 5, 2021 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_start_lib_state(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Push a new API context on the stack */ + if (H5CX_push() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't push API context") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_start_lib_state() */ + +/*------------------------------------------------------------------------- * Function: H5VL_restore_lib_state * * Purpose: Restore the state of the library. @@ -2071,10 +2156,6 @@ H5VL_restore_lib_state(const void *state) /* Sanity checks */ HDassert(state); - /* Push a new API context on the stack */ - if (H5CX_push() < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't push API context") - /* Restore the API context state */ if (H5CX_restore_state((const H5CX_state_t *)state) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set API context state") @@ -2084,16 +2165,16 @@ done: } /* end H5VL_restore_lib_state() */ /*------------------------------------------------------------------------- - * Function: H5VL_reset_lib_state + * Function: H5VL_finish_lib_state * - * Purpose: Reset the state of the library, undoing affects of - * H5VL_restore_lib_state. + * Purpose: Closes the state of the library, undoing affects of + * H5VL_start_lib_state. * * Note: Currently just resets the API context state, but could be * expanded in the future. * * Note: This routine must be called as a "pair" with - * H5VL_restore_lib_state. It can be called before / after / + * H5VL_start_lib_state. It can be called before / after / * independently of H5VL_free_lib_state. * * Return: SUCCEED / FAIL @@ -2104,7 +2185,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_reset_lib_state(void) +H5VL_finish_lib_state(void) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2116,7 +2197,7 @@ H5VL_reset_lib_state(void) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL_reset_lib_state() */ +} /* end H5VL_finish_lib_state() */ /*------------------------------------------------------------------------- * Function: H5VL_free_lib_state @@ -2484,6 +2565,33 @@ done: } /* end H5VL_check_plugin_load() */ /*------------------------------------------------------------------------- + * Function: H5VL__is_default_conn + * + * Purpose: Check if the default connector will be used for a container. + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +void +H5VL__is_default_conn(hid_t fapl_id, hid_t connector_id, hbool_t *is_default) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity checks */ + HDassert(is_default); + + /* Determine if the default VOL connector will be used, based on non-default + * values in the FAPL, connector ID, or the HDF5_VOL_CONNECTOR environment + * variable being set. + */ + *is_default = (H5VL_def_conn_s.connector_id == H5_DEFAULT_VOL) && + ((H5P_FILE_ACCESS_DEFAULT == fapl_id) || connector_id == H5_DEFAULT_VOL); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5VL__is_default_conn() */ + +/*------------------------------------------------------------------------- * Function: H5VL_setup_args * * Purpose: Set up arguments to access an object @@ -2506,7 +2614,7 @@ H5VL_setup_args(hid_t loc_id, H5I_type_t id_type, H5VL_object_t **vol_obj) if (NULL == (*vol_obj = (H5VL_object_t *)H5I_object_verify(loc_id, id_type))) HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not the correct type of ID") - /* Set up collective metadata (if appropriate */ + /* Set up collective metadata (if appropriate) */ if (H5CX_set_loc(loc_id) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set collective metadata read") @@ -2631,8 +2739,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL_setup_name_args(hid_t loc_id, const char *name, const H5P_libclass_t *libclass, hbool_t is_collective, - hid_t acspl_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params) +H5VL_setup_name_args(hid_t loc_id, const char *name, hbool_t is_collective, hid_t lapl_id, + H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2649,7 +2757,7 @@ H5VL_setup_name_args(hid_t loc_id, const char *name, const H5P_libclass_t *libcl HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string") /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&acspl_id, libclass, loc_id, is_collective) < 0) + if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, is_collective) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set access property list info") /* Get the location object */ @@ -2659,7 +2767,7 @@ H5VL_setup_name_args(hid_t loc_id, const char *name, const H5P_libclass_t *libcl /* Set up location parameters */ loc_params->type = H5VL_OBJECT_BY_NAME; loc_params->loc_data.loc_by_name.name = name; - loc_params->loc_data.loc_by_name.lapl_id = acspl_id; + loc_params->loc_data.loc_by_name.lapl_id = lapl_id; loc_params->obj_type = H5I_get_type(loc_id); done: @@ -2677,8 +2785,8 @@ done: */ herr_t H5VL_setup_idx_args(hid_t loc_id, const char *name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, - const H5P_libclass_t *libclass, hbool_t is_collective, hid_t acspl_id, - H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params) + hbool_t is_collective, hid_t lapl_id, H5VL_object_t **vol_obj, + H5VL_loc_params_t *loc_params) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2699,7 +2807,7 @@ H5VL_setup_idx_args(hid_t loc_id, const char *name, H5_index_t idx_type, H5_iter HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified") /* Verify access property list and set up collective metadata if appropriate */ - if (H5CX_set_apl(&acspl_id, libclass, loc_id, is_collective) < 0) + if (H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, is_collective) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set access property list info") /* Get the location object */ @@ -2712,7 +2820,7 @@ H5VL_setup_idx_args(hid_t loc_id, const char *name, H5_index_t idx_type, H5_iter loc_params->loc_data.loc_by_idx.idx_type = idx_type; loc_params->loc_data.loc_by_idx.order = order; loc_params->loc_data.loc_by_idx.n = n; - loc_params->loc_data.loc_by_idx.lapl_id = acspl_id; + loc_params->loc_data.loc_by_idx.lapl_id = lapl_id; loc_params->obj_type = H5I_get_type(loc_id); done: @@ -2752,3 +2860,45 @@ H5VL_setup_token_args(hid_t loc_id, H5O_token_t *obj_token, H5VL_object_t **vol_ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_setup_token_args() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_get_cap_flags + * + * Purpose: Query capability flags for connector property. + * + * Note: VOL connector set with HDF5_VOL_CONNECTOR overrides the + * property passed in. + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_get_cap_flags(const H5VL_connector_prop_t *connector_prop, unsigned *cap_flags) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(connector_prop); + + /* Copy the connector ID & info, if there is one */ + if (connector_prop->connector_id > 0) { + H5VL_class_t *connector; /* Pointer to connector */ + + /* Retrieve the connector for the ID */ + if (NULL == (connector = (H5VL_class_t *)H5I_object(connector_prop->connector_id))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Query the connector's capability flags */ + if (H5VL_introspect_get_cap_flags(connector_prop->connector_info, connector, cap_flags) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't query connector's capability flags") + } /* end if */ + else + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "connector ID not set?") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_get_cap_flags() */ diff --git a/src/H5VLmodule.h b/src/H5VLmodule.h index 009c0e5..8fcb961 100644 --- a/src/H5VLmodule.h +++ b/src/H5VLmodule.h @@ -27,14 +27,12 @@ #define H5_MY_PKG_ERR H5E_VOL #define H5_MY_PKG_INIT YES -/** - * \defgroup H5VL H5VL - * \brief Virtual Object Layer Interface - * \todo Describe concisely what the functions in this module are about. +/**\defgroup H5VL H5VL + * + * \todo Describe the VOL plugin life cycle. * * \defgroup ASYNC Asynchronous Functions * \brief Asynchronous Functions - * \todo Describe concisely what the functions in this module are about. * * \defgroup H5VLDEF Definitions * \ingroup H5VL diff --git a/src/H5VLnative.c b/src/H5VLnative.c index b70d489..18b5b9c 100644 --- a/src/H5VLnative.c +++ b/src/H5VLnative.c @@ -47,13 +47,13 @@ static herr_t H5VL__native_term(void); /* Native VOL connector class struct */ static const H5VL_class_t H5VL_native_cls_g = { - H5VL_VERSION, /* VOL class struct version */ - H5VL_NATIVE_VALUE, /* value */ - H5VL_NATIVE_NAME, /* name */ - H5VL_NATIVE_VERSION, /* connector version */ - 0, /* capability flags */ - NULL, /* initialize */ - H5VL__native_term, /* terminate */ + H5VL_VERSION, /* VOL class struct version */ + H5VL_NATIVE_VALUE, /* value */ + H5VL_NATIVE_NAME, /* name */ + H5VL_NATIVE_VERSION, /* connector version */ + H5VL_CAP_FLAG_NATIVE_FILES, /* capability flags */ + NULL, /* initialize */ + H5VL__native_term, /* terminate */ { /* info_cls */ (size_t)0, /* info size */ @@ -139,8 +139,9 @@ static const H5VL_class_t H5VL_native_cls_g = { }, { /* introspect_cls */ - H5VL__native_introspect_get_conn_cls, /* get_conn_cls */ - H5VL__native_introspect_opt_query, /* opt_query */ + H5VL__native_introspect_get_conn_cls, /* get_conn_cls */ + H5VL__native_introspect_get_cap_flags, /* get_cap_flags */ + H5VL__native_introspect_opt_query, /* opt_query */ }, { /* request_cls */ @@ -244,6 +245,32 @@ H5VL__native_introspect_get_conn_cls(void H5_ATTR_UNUSED *obj, H5VL_get_conn_lvl FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5VL__native_introspect_get_conn_cls() */ +/*--------------------------------------------------------------------------- + * Function: H5VL__native_introspect_get_cap_flags + * + * Purpose: Query the capability flags for this connector. + * + * Note: This routine is in this file so that it can return the field + * from the staticly declared class struct. + * + * Returns: SUCCEED (Can't fail) + * + *--------------------------------------------------------------------------- + */ +herr_t +H5VL__native_introspect_get_cap_flags(const void H5_ATTR_UNUSED *info, unsigned *cap_flags) +{ + FUNC_ENTER_PACKAGE_NOERR + + /* Sanity check */ + HDassert(cap_flags); + + /* Set the flags from the connector's field */ + *cap_flags = H5VL_native_cls_g.cap_flags; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5VL__native_introspect_get_cap_flags() */ + /*------------------------------------------------------------------------- * Function: H5VL_native_get_file_addr_len * diff --git a/src/H5VLnative.h b/src/H5VLnative.h index 425d833..00ee930 100644 --- a/src/H5VLnative.h +++ b/src/H5VLnative.h @@ -18,6 +18,7 @@ #define H5VLnative_H /* Public headers needed by this file */ +#include "H5Apublic.h" /* Attributes */ #include "H5VLpublic.h" /* Virtual Object Layer */ /*****************/ @@ -43,24 +44,137 @@ * must be updated. */ +#ifndef H5_NO_DEPRECATED_SYMBOLS +/* Parameters for attribute 'iterate old' operation */ +typedef struct H5VL_native_attr_iterate_old_t { + hid_t loc_id; + unsigned * attr_num; + H5A_operator1_t op; + void * op_data; +} H5VL_native_attr_iterate_old_t; + +/* Parameters for native connector's attribute 'optional' operations */ +typedef union H5VL_native_attr_optional_args_t { + /* H5VL_NATIVE_ATTR_ITERATE_OLD */ + H5VL_native_attr_iterate_old_t iterate_old; +} H5VL_native_attr_optional_args_t; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + /* Values for native VOL connector dataset optional VOL operations */ /* NOTE: If new values are added here, the H5VL__native_introspect_opt_query * routine must be updated. */ -#define H5VL_NATIVE_DATASET_FORMAT_CONVERT 0 /* H5Dformat_convert (internal) */ -#define H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE 1 /* H5Dget_chunk_index_type */ -#define H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE 2 /* H5Dget_chunk_storage_size */ -#define H5VL_NATIVE_DATASET_GET_NUM_CHUNKS 3 /* H5Dget_num_chunks */ -#define H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX 4 /* H5Dget_chunk_info */ -#define H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD 5 /* H5Dget_chunk_info_by_coord */ -#define H5VL_NATIVE_DATASET_CHUNK_READ 6 /* H5Dchunk_read */ -#define H5VL_NATIVE_DATASET_CHUNK_WRITE 7 /* H5Dchunk_write */ -#define H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE 8 /* H5Dvlen_get_buf_size */ -#define H5VL_NATIVE_DATASET_GET_OFFSET 9 /* H5Dget_offset */ +#define H5VL_NATIVE_DATASET_FORMAT_CONVERT 0 /* H5Dformat_convert (internal) */ +#define H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE 1 /* H5Dget_chunk_index_type */ +#define H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE 2 /* H5Dget_chunk_storage_size */ +#define H5VL_NATIVE_DATASET_GET_NUM_CHUNKS 3 /* H5Dget_num_chunks */ +#define H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX 4 /* H5Dget_chunk_info */ +#define H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD 5 /* H5Dget_chunk_info_by_coord */ +#define H5VL_NATIVE_DATASET_CHUNK_READ 6 /* H5Dchunk_read */ +#define H5VL_NATIVE_DATASET_CHUNK_WRITE 7 /* H5Dchunk_write */ +#define H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE 8 /* H5Dvlen_get_buf_size */ +#define H5VL_NATIVE_DATASET_GET_OFFSET 9 /* H5Dget_offset */ +#define H5VL_NATIVE_DATASET_CHUNK_ITER 10 /* H5Dchunk_iter */ /* NOTE: If values over 1023 are added, the H5VL_RESERVED_NATIVE_OPTIONAL macro * must be updated. */ +/* Parameters for native connector's dataset 'chunk read' operation */ +typedef struct H5VL_native_dataset_chunk_read_t { + const hsize_t *offset; + uint32_t filters; + void * buf; +} H5VL_native_dataset_chunk_read_t; + +/* Parameters for native connector's dataset 'chunk write' operation */ +typedef struct H5VL_native_dataset_chunk_write_t { + const hsize_t *offset; + uint32_t filters; + uint32_t size; + const void * buf; +} H5VL_native_dataset_chunk_write_t; + +/* Parameters for native connector's dataset 'get vlen buf size' operation */ +typedef struct H5VL_native_dataset_get_vlen_buf_size_t { + hid_t type_id; + hid_t space_id; + hsize_t *size; /* Size of variable-length data buffer (OUT) */ +} H5VL_native_dataset_get_vlen_buf_size_t; + +/* Parameters for native connector's dataset 'get chunk storage size' operation */ +typedef struct H5VL_native_dataset_get_chunk_storage_size_t { + const hsize_t *offset; /* Offset of chunk */ + hsize_t * size; /* Size of chunk (OUT) */ +} H5VL_native_dataset_get_chunk_storage_size_t; + +/* Parameters for native connector's dataset 'get num chunks' operation */ +typedef struct H5VL_native_dataset_get_num_chunks_t { + hid_t space_id; /* Space selection */ + hsize_t *nchunks; /* # of chunk for space selection (OUT) */ +} H5VL_native_dataset_get_num_chunks_t; + +/* Parameters for native connector's dataset 'get chunk info by idx' operation */ +typedef struct H5VL_native_dataset_get_chunk_info_by_idx_t { + hid_t space_id; /* Space selection */ + hsize_t chk_index; /* Chunk index within space */ + hsize_t * offset; /* Chunk coordinates (OUT) */ + unsigned *filter_mask; /* Filter mask for chunk (OUT) */ + haddr_t * addr; /* Address of chunk in file (OUT) */ + hsize_t * size; /* Size of chunk in file (OUT) */ +} H5VL_native_dataset_get_chunk_info_by_idx_t; + +/* Parameters for native connector's dataset 'get chunk info by coord' operation */ +typedef struct H5VL_native_dataset_get_chunk_info_by_coord_t { + const hsize_t *offset; /* Chunk coordinates */ + unsigned * filter_mask; /* Filter mask for chunk (OUT) */ + haddr_t * addr; /* Address of chunk in file (OUT) */ + hsize_t * size; /* Size of chunk in file (OUT) */ +} H5VL_native_dataset_get_chunk_info_by_coord_t; + +/* Parameters for native connector's dataset 'optional' operations */ +typedef union H5VL_native_dataset_optional_args_t { + /* H5VL_NATIVE_DATASET_FORMAT_CONVERT */ + /* No args */ + + /* H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE */ + struct { + H5D_chunk_index_t *idx_type; /* Type of chunk index (OUT) */ + } get_chunk_idx_type; + + /* H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE */ + H5VL_native_dataset_get_chunk_storage_size_t get_chunk_storage_size; + + /* H5VL_NATIVE_DATASET_GET_NUM_CHUNKS */ + H5VL_native_dataset_get_num_chunks_t get_num_chunks; + + /* H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX */ + H5VL_native_dataset_get_chunk_info_by_idx_t get_chunk_info_by_idx; + + /* H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD */ + H5VL_native_dataset_get_chunk_info_by_coord_t get_chunk_info_by_coord; + + /* H5VL_NATIVE_DATASET_CHUNK_READ */ + H5VL_native_dataset_chunk_read_t chunk_read; + + /* H5VL_NATIVE_DATASET_CHUNK_WRITE */ + H5VL_native_dataset_chunk_write_t chunk_write; + + /* H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE */ + H5VL_native_dataset_get_vlen_buf_size_t get_vlen_buf_size; + + /* H5VL_NATIVE_DATASET_GET_OFFSET */ + struct { + haddr_t *offset; /* Contiguous dataset's offset in the file (OUT) */ + } get_offset; + + /* H5VL_NATIVE_DATASET_CHUNK_ITER */ + struct { + H5D_chunk_iter_op_t op; /* Chunk iteration callback */ + void * op_data; /* Context to pass to iteration callback */ + } chunk_iter; + +} H5VL_native_dataset_optional_args_t; + /* Values for native VOL connector file optional VOL operations */ /* NOTE: If new values are added here, the H5VL__native_introspect_opt_query * routine must be updated. @@ -103,6 +217,194 @@ * must be updated. */ +/* Parameters for native connector's file 'get file image' operation */ +typedef struct H5VL_native_file_get_file_image_t { + size_t buf_size; /* Size of file image buffer */ + void * buf; /* Buffer for file image (OUT) */ + size_t *image_len; /* Size of file image (OUT) */ +} H5VL_native_file_get_file_image_t; + +/* Parameters for native connector's file 'get free sections' operation */ +typedef struct H5VL_native_file_get_free_sections_t { + H5F_mem_t type; /* Type of file memory to query */ + H5F_sect_info_t *sect_info; /* Array of sections (OUT) */ + size_t nsects; /* Size of section array */ + size_t * sect_count; /* Actual # of sections of type (OUT) */ +} H5VL_native_file_get_free_sections_t; + +/* Parameters for native connector's file 'get freespace' operation */ +typedef struct H5VL_native_file_get_freespace_t { + hsize_t *size; /* Size of free space (OUT) */ +} H5VL_native_file_get_freespace_t; + +/* Parameters for native connector's file 'get info' operation */ +typedef struct H5VL_native_file_get_info_t { + H5I_type_t type; /* Type of object */ + H5F_info2_t *finfo; /* Pointer to file info (OUT) */ +} H5VL_native_file_get_info_t; + +/* Parameters for native connector's file 'get metadata cache size' operation */ +typedef struct H5VL_native_file_get_mdc_size_t { + size_t * max_size; /* Maximum amount of cached data (OUT) */ + size_t * min_clean_size; /* Minimum amount of cached data to keep clean (OUT) */ + size_t * cur_size; /* Current amount of cached data (OUT) */ + uint32_t *cur_num_entries; /* Current # of cached entries (OUT) */ +} H5VL_native_file_get_mdc_size_t; + +/* Parameters for native connector's file 'get VFD handle' operation */ +typedef struct H5VL_native_file_get_vfd_handle_t { + hid_t fapl_id; + void **file_handle; /* File handle from VFD (OUT) */ +} H5VL_native_file_get_vfd_handle_t; + +/* Parameters for native connector's file 'get MDC logging status' operation */ +typedef struct H5VL_native_file_get_mdc_logging_status_t { + hbool_t *is_enabled; /* Whether logging is enabled (OUT) */ + hbool_t *is_currently_logging; /* Whether currently logging (OUT) */ +} H5VL_native_file_get_mdc_logging_status_t; + +/* Parameters for native connector's file 'get page buffering stats' operation */ +typedef struct H5VL_native_file_get_page_buffering_stats_t { + unsigned *accesses; /* Metadata/raw data page access counts (OUT) */ + unsigned *hits; /* Metadata/raw data page hit counts (OUT) */ + unsigned *misses; /* Metadata/raw data page miss counts (OUT) */ + unsigned *evictions; /* Metadata/raw data page eviction counts (OUT) */ + unsigned *bypasses; /* Metadata/raw data page bypass counts (OUT) */ +} H5VL_native_file_get_page_buffering_stats_t; + +/* Parameters for native connector's file 'get MDC image info' operation */ +typedef struct H5VL_native_file_get_mdc_image_info_t { + haddr_t *addr; /* Address of image (OUT) */ + hsize_t *len; /* Length of image (OUT) */ +} H5VL_native_file_get_mdc_image_info_t; + +/* Parameters for native connector's file 'set libver bounds' operation */ +typedef struct H5VL_native_file_set_libver_bounds_t { + H5F_libver_t low; /* Lowest version possible */ + H5F_libver_t high; /* Highest version possible */ +} H5VL_native_file_set_libver_bounds_t; + +/* Parameters for native connector's file 'optional' operations */ +typedef union H5VL_native_file_optional_args_t { + /* H5VL_NATIVE_FILE_CLEAR_ELINK_CACHE */ + /* No args */ + + /* H5VL_NATIVE_FILE_GET_FILE_IMAGE */ + H5VL_native_file_get_file_image_t get_file_image; + + /* H5VL_NATIVE_FILE_GET_FREE_SECTIONS */ + H5VL_native_file_get_free_sections_t get_free_sections; + + /* H5VL_NATIVE_FILE_GET_FREE_SPACE */ + H5VL_native_file_get_freespace_t get_freespace; + + /* H5VL_NATIVE_FILE_GET_INFO */ + H5VL_native_file_get_info_t get_info; + + /* H5VL_NATIVE_FILE_GET_MDC_CONF */ + struct { + H5AC_cache_config_t *config; /* Pointer to MDC config (OUT) */ + } get_mdc_config; + + /* H5VL_NATIVE_FILE_GET_MDC_HR */ + struct { + double *hit_rate; /* Metadata cache hit rate (OUT) */ + } get_mdc_hit_rate; + + /* H5VL_NATIVE_FILE_GET_MDC_SIZE */ + H5VL_native_file_get_mdc_size_t get_mdc_size; + + /* H5VL_NATIVE_FILE_GET_SIZE */ + struct { + hsize_t *size; /* Size of file (OUT) */ + } get_size; + + /* H5VL_NATIVE_FILE_GET_VFD_HANDLE */ + H5VL_native_file_get_vfd_handle_t get_vfd_handle; + + /* H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE */ + /* No args */ + + /* H5VL_NATIVE_FILE_SET_MDC_CONFIG */ + struct { + const H5AC_cache_config_t *config; /* Pointer to new MDC config */ + } set_mdc_config; + + /* H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO */ + struct { + H5F_retry_info_t *info; /* Pointer to metadata read retry info (OUT) */ + } get_metadata_read_retry_info; + + /* H5VL_NATIVE_FILE_START_SWMR_WRITE */ + /* No args */ + + /* H5VL_NATIVE_FILE_START_MDC_LOGGING */ + /* No args */ + + /* H5VL_NATIVE_FILE_STOP_MDC_LOGGING */ + /* No args */ + + /* H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS */ + H5VL_native_file_get_mdc_logging_status_t get_mdc_logging_status; + + /* H5VL_NATIVE_FILE_FORMAT_CONVERT */ + /* No args */ + + /* H5VL_NATIVE_FILE_RESET_PAGE_BUFFERING_STATS */ + /* No args */ + + /* H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS */ + H5VL_native_file_get_page_buffering_stats_t get_page_buffering_stats; + + /* H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO */ + H5VL_native_file_get_mdc_image_info_t get_mdc_image_info; + + /* H5VL_NATIVE_FILE_GET_EOA */ + struct { + haddr_t *eoa; /* End of allocated file address space (OUT) */ + } get_eoa; + + /* H5VL_NATIVE_FILE_INCR_FILESIZE */ + struct { + hsize_t increment; /* Amount to increment file size */ + } increment_filesize; + + /* H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS */ + H5VL_native_file_set_libver_bounds_t set_libver_bounds; + + /* H5VL_NATIVE_FILE_GET_MIN_DSET_OHDR_FLAG */ + struct { + hbool_t *minimize; /* Flag whether dataset object headers are minimal (OUT) */ + } get_min_dset_ohdr_flag; + + /* H5VL_NATIVE_FILE_SET_MIN_DSET_OHDR_FLAG */ + struct { + hbool_t minimize; /* Flag whether dataset object headers should be minimal */ + } set_min_dset_ohdr_flag; + +#ifdef H5_HAVE_PARALLEL + /* H5VL_NATIVE_FILE_GET_MPI_ATOMICITY */ + struct { + hbool_t *flag; /* Flag whether MPI atomicity is set for files (OUT) */ + } get_mpi_atomicity; + + /* H5VL_NATIVE_FILE_SET_MPI_ATOMICITY */ + struct { + hbool_t flag; /* Flag whether to set MPI atomicity for files */ + } set_mpi_atomicity; +#endif /* H5_HAVE_PARALLEL */ + + /* H5VL_NATIVE_FILE_POST_OPEN */ + /* No args */ + + /* H5VL_NATIVE_FILE_VFD_SWMR_DISABLE_EOT */ + + /* H5VL_NATIVE_FILE_VFD_SWMR_ENABLE_EOT */ + + /* H5VL_NATIVE_FILE_VFD_SWMR_END_TICK */ + +} H5VL_native_file_optional_args_t; + /* Values for native VOL connector group optional VOL operations */ /* NOTE: If new values are added here, the H5VL__native_introspect_opt_query * routine must be updated. @@ -115,6 +417,33 @@ * must be updated. */ +#ifndef H5_NO_DEPRECATED_SYMBOLS +/* Parameters for group 'iterate old' operation */ +typedef struct H5VL_native_group_iterate_old_t { + H5VL_loc_params_t loc_params; /* Location parameters for iteration */ + hsize_t idx; /* Index of link to begin iteration at */ + hsize_t * last_obj; /* Index of last link looked at (OUT) */ + H5G_iterate_t op; /* Group (link) operator callback */ + void * op_data; /* Context to pass to iterator callback */ +} H5VL_native_group_iterate_old_t; + +/* Parameters for group 'get objinfo' operation */ +typedef struct H5VL_native_group_get_objinfo_t { + H5VL_loc_params_t loc_params; /* Location parameters for iteration */ + hbool_t follow_link; /* Whether to follow links for query */ + H5G_stat_t * statbuf; /* Pointer to object info struct (OUT) */ +} H5VL_native_group_get_objinfo_t; + +/* Parameters for native connector's group 'optional' operations */ +typedef union H5VL_native_group_optional_args_t { + /* H5VL_NATIVE_GROUP_ITERATE_OLD */ + H5VL_native_group_iterate_old_t iterate_old; + + /* H5VL_NATIVE_GROUP_GET_OBJINFO */ + H5VL_native_group_get_objinfo_t get_objinfo; +} H5VL_native_group_optional_args_t; +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + /* Values for native VOL connector object optional VOL operations */ /* NOTE: If new values are added here, the H5VL__native_introspect_opt_query * routine must be updated. @@ -129,6 +458,44 @@ * must be updated. */ +/* Parameters for native connector's object 'get comment' operation */ +typedef struct H5VL_native_object_get_comment_t { + size_t buf_size; /* Size of comment buffer */ + void * buf; /* Buffer for comment (OUT) */ + size_t *comment_len; /* Actual size of comment (OUT) */ +} H5VL_native_object_get_comment_t; + +/* Parameters for object 'get native info' operation */ +typedef struct H5VL_native_object_get_native_info_t { + unsigned fields; /* Fields to retrieve */ + H5O_native_info_t *ninfo; /* Native info (OUT) */ +} H5VL_native_object_get_native_info_t; + +/* Parameters for native connector's object 'optional' operations */ +typedef union H5VL_native_object_optional_args_t { + /* H5VL_NATIVE_OBJECT_GET_COMMENT */ + H5VL_native_object_get_comment_t get_comment; + + /* H5VL_NATIVE_OBJECT_SET_COMMENT */ + struct { + const char *comment; /* Comment string to set for the object (IN) */ + } set_comment; + + /* H5VL_NATIVE_OBJECT_DISABLE_MDC_FLUSHES */ + /* No args */ + + /* H5VL_NATIVE_OBJECT_ENABLE_MDC_FLUSHES */ + /* No args */ + + /* H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED */ + struct { + hbool_t *flag; /* Flag whether metadata cache flushes are disabled for this object (OUT) */ + } are_mdc_flushes_disabled; + + /* H5VL_NATIVE_OBJECT_GET_NATIVE_INFO */ + H5VL_native_object_get_native_info_t get_native_info; +} H5VL_native_object_optional_args_t; + /*******************/ /* Public Typedefs */ /*******************/ diff --git a/src/H5VLnative_attr.c b/src/H5VLnative_attr.c index f5e5f29..834ae40 100644 --- a/src/H5VLnative_attr.c +++ b/src/H5VLnative_attr.c @@ -245,40 +245,37 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (get_type) { + switch (args->op_type) { /* H5Aget_space */ case H5VL_ATTR_GET_SPACE: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - H5A_t *attr = (H5A_t *)obj; + H5A_t *attr = (H5A_t *)obj; - if ((*ret_id = H5A_get_space(attr)) < 0) + if ((args->args.get_space.space_id = H5A_get_space(attr)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get space ID of attribute") break; } /* H5Aget_type */ case H5VL_ATTR_GET_TYPE: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - H5A_t *attr = (H5A_t *)obj; + H5A_t *attr = (H5A_t *)obj; - if ((*ret_id = H5A__get_type(attr)) < 0) + if ((args->args.get_type.type_id = H5A__get_type(attr)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of attribute") break; } /* H5Aget_create_plist */ case H5VL_ATTR_GET_ACPL: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - H5A_t *attr = (H5A_t *)obj; + H5A_t *attr = (H5A_t *)obj; - if ((*ret_id = H5A__get_create_plist(attr)) < 0) + if ((args->args.get_acpl.acpl_id = H5A__get_create_plist(attr)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for attr") break; @@ -286,40 +283,37 @@ H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t H5_ATTR_UNUSED /* H5Aget_name */ case H5VL_ATTR_GET_NAME: { - const H5VL_loc_params_t *loc_params = HDva_arg(arguments, const H5VL_loc_params_t *); - size_t buf_size = HDva_arg(arguments, size_t); - char * buf = HDva_arg(arguments, char *); - ssize_t * ret_val = HDva_arg(arguments, ssize_t *); - H5A_t * attr = NULL; + H5VL_attr_get_name_args_t *get_name_args = &args->args.get_name; - if (H5VL_OBJECT_BY_SELF == loc_params->type) { - attr = (H5A_t *)obj; - /* Call private function in turn */ - if (0 > (*ret_val = H5A__get_name(attr, buf_size, buf))) + if (H5VL_OBJECT_BY_SELF == get_name_args->loc_params.type) { + if (H5A__get_name((H5A_t *)obj, get_name_args->buf_size, get_name_args->buf, + get_name_args->attr_name_len) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get attribute name") } - else if (H5VL_OBJECT_BY_IDX == loc_params->type) { + else if (H5VL_OBJECT_BY_IDX == get_name_args->loc_params.type) { H5G_loc_t loc; + H5A_t * attr; /* check arguments */ - if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + if (H5G_loc_real(obj, get_name_args->loc_params.obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Open the attribute on the object header */ - if (NULL == (attr = H5A__open_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n))) + if (NULL == (attr = H5A__open_by_idx(&loc, get_name_args->loc_params.loc_data.loc_by_idx.name, + get_name_args->loc_params.loc_data.loc_by_idx.idx_type, + get_name_args->loc_params.loc_data.loc_by_idx.order, + get_name_args->loc_params.loc_data.loc_by_idx.n))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") /* Get the length of the name */ - *ret_val = (ssize_t)HDstrlen(attr->shared->name); + *get_name_args->attr_name_len = HDstrlen(attr->shared->name); /* Copy the name into the user's buffer, if given */ - if (buf) { - HDstrncpy(buf, attr->shared->name, MIN((size_t)(*ret_val + 1), buf_size)); - if ((size_t)(*ret_val) >= buf_size) - buf[buf_size - 1] = '\0'; + if (get_name_args->buf) { + HDstrncpy(get_name_args->buf, attr->shared->name, + MIN((*get_name_args->attr_name_len + 1), get_name_args->buf_size)); + if (*get_name_args->attr_name_len >= get_name_args->buf_size) + get_name_args->buf[get_name_args->buf_size - 1] = '\0'; } /* end if */ /* Release resources */ @@ -334,52 +328,51 @@ H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t H5_ATTR_UNUSED /* H5Aget_info */ case H5VL_ATTR_GET_INFO: { - const H5VL_loc_params_t *loc_params = HDva_arg(arguments, const H5VL_loc_params_t *); - H5A_info_t * ainfo = HDva_arg(arguments, H5A_info_t *); - H5A_t * attr = NULL; + H5VL_attr_get_info_args_t *get_info_args = &args->args.get_info; + H5A_t * attr = NULL; - if (H5VL_OBJECT_BY_SELF == loc_params->type) { + if (H5VL_OBJECT_BY_SELF == get_info_args->loc_params.type) { attr = (H5A_t *)obj; - if (H5A__get_info(attr, ainfo) < 0) + if (H5A__get_info(attr, get_info_args->ainfo) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get attribute info") } - else if (H5VL_OBJECT_BY_NAME == loc_params->type) { - char * attr_name = HDva_arg(arguments, char *); + else if (H5VL_OBJECT_BY_NAME == get_info_args->loc_params.type) { H5G_loc_t loc; /* check arguments */ - if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + if (H5G_loc_real(obj, get_info_args->loc_params.obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Open the attribute on the object header */ if (NULL == - (attr = H5A__open_by_name(&loc, loc_params->loc_data.loc_by_name.name, attr_name))) + (attr = H5A__open_by_name(&loc, get_info_args->loc_params.loc_data.loc_by_name.name, + get_info_args->attr_name))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") /* Get the attribute information */ - if (H5A__get_info(attr, ainfo) < 0) + if (H5A__get_info(attr, get_info_args->ainfo) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") /* Release resources */ if (attr && H5A__close(attr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") } - else if (H5VL_OBJECT_BY_IDX == loc_params->type) { + else if (H5VL_OBJECT_BY_IDX == get_info_args->loc_params.type) { H5G_loc_t loc; /* check arguments */ - if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + if (H5G_loc_real(obj, get_info_args->loc_params.obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Open the attribute on the object header */ - if (NULL == (attr = H5A__open_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n))) + if (NULL == (attr = H5A__open_by_idx(&loc, get_info_args->loc_params.loc_data.loc_by_idx.name, + get_info_args->loc_params.loc_data.loc_by_idx.idx_type, + get_info_args->loc_params.loc_data.loc_by_idx.order, + get_info_args->loc_params.loc_data.loc_by_idx.n))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") /* Get the attribute information */ - if (H5A__get_info(attr, ainfo) < 0) + if (H5A__get_info(attr, get_info_args->ainfo) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") /* Release resources */ @@ -393,11 +386,10 @@ H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t H5_ATTR_UNUSED } case H5VL_ATTR_GET_STORAGE_SIZE: { - hsize_t *ret = HDva_arg(arguments, hsize_t *); - H5A_t * attr = (H5A_t *)obj; + H5A_t *attr = (H5A_t *)obj; - /* Set return value */ - *ret = attr->shared->data_size; + /* Set storage size */ + *args->args.get_storage_size.data_size = attr->shared->data_size; break; } @@ -419,8 +411,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_specific_t specific_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_specific_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { H5G_loc_t loc; herr_t ret_value = SUCCEED; /* Return value */ @@ -431,48 +423,51 @@ H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - switch (specific_type) { + switch (args->op_type) { + /* H5Adelete/delete_by_name */ case H5VL_ATTR_DELETE: { - char *attr_name = HDva_arg(arguments, char *); - if (H5VL_OBJECT_BY_SELF == loc_params->type) { - /* H5Adelete */ /* Delete the attribute from the location */ - if (H5O__attr_remove(loc.oloc, attr_name) < 0) + if (H5O__attr_remove(loc.oloc, args->args.del.name) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") } /* end if */ else if (H5VL_OBJECT_BY_NAME == loc_params->type) { - /* H5Adelete_by_name */ /* Delete the attribute */ - if (H5A__delete_by_name(&loc, loc_params->loc_data.loc_by_name.name, attr_name) < 0) + if (H5A__delete_by_name(&loc, loc_params->loc_data.loc_by_name.name, args->args.del.name) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") } /* end else-if */ - else if (H5VL_OBJECT_BY_IDX == loc_params->type) { - /* H5Adelete_by_idx */ + else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown attribute delete location") + break; + } + + /* H5Adelete_by_idx */ + case H5VL_ATTR_DELETE_BY_IDX: { + H5VL_attr_delete_by_idx_args_t *del_by_idx_args = + &args->args.delete_by_idx; /* Arguments to delete_by_idx operation */ + + if (H5VL_OBJECT_BY_NAME == loc_params->type) { /* Delete the attribute from the location */ - if (H5A__delete_by_idx( - &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n) < 0) + if (H5A__delete_by_idx(&loc, loc_params->loc_data.loc_by_name.name, del_by_idx_args->idx_type, + del_by_idx_args->order, del_by_idx_args->n) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") - } /* end else-if */ + } /* end if */ else - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown attribute remove parameters") + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown attribute delete_by_idx location") break; } + /* H5Aexists/exists_by_name */ case H5VL_ATTR_EXISTS: { - const char *attr_name = HDva_arg(arguments, const char *); - hbool_t * attr_exists = HDva_arg(arguments, hbool_t *); - - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Aexists */ + if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* Check if the attribute exists */ - if (H5O__attr_exists(loc.oloc, attr_name, attr_exists) < 0) + if (H5O__attr_exists(loc.oloc, args->args.exists.name, args->args.exists.exists) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") - } /* end if */ - else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Aexists_by_name */ + } /* end if */ + else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* Check if the attribute exists */ - if (H5A__exists_by_name(loc, loc_params->loc_data.loc_by_name.name, attr_name, attr_exists) < - 0) + if (H5A__exists_by_name(loc, loc_params->loc_data.loc_by_name.name, args->args.exists.name, + args->args.exists.exists) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") } /* end else-if */ else @@ -480,42 +475,38 @@ H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ break; } + /* H5Aiterate/iterate_by_name */ case H5VL_ATTR_ITER: { - H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */ - H5_iter_order_t order = (H5_iter_order_t)HDva_arg(arguments, int); /* enum work-around */ - hsize_t * idx = HDva_arg(arguments, hsize_t *); - H5A_operator2_t op = HDva_arg(arguments, H5A_operator2_t); - void * op_data = HDva_arg(arguments, void *); - - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Aiterate2 */ - /* Iterate over attributes */ - if ((ret_value = H5A__iterate(&loc, ".", idx_type, order, idx, op, op_data)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "error iterating over attributes") - } /* end if */ - else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Aiterate_by_name */ - /* Iterate over attributes by name */ - if ((ret_value = H5A__iterate(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, - idx, op, op_data)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_BADITER, FAIL, "attribute iteration failed"); - } /* end else-if */ + H5VL_attr_iterate_args_t *iter_args = &args->args.iterate; /* Arguments to iterate operation */ + static const char * self_name = "."; /* Name for 'self' location */ + const char * loc_name; /* Location name */ + + /* Set correct name, for type of location */ + if (loc_params->type == H5VL_OBJECT_BY_SELF) /* H5Aiterate2 */ + loc_name = self_name; + else if (loc_params->type == H5VL_OBJECT_BY_NAME) /* H5Aiterate_by_name */ + loc_name = loc_params->loc_data.loc_by_name.name; else - HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown parameters") + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unsupported location type") + + /* Iterate over attributes */ + if ((ret_value = H5A__iterate(&loc, loc_name, iter_args->idx_type, iter_args->order, + iter_args->idx, iter_args->op, iter_args->op_data)) < 0) + HERROR(H5E_ATTR, H5E_BADITER, "attribute iteration failed"); break; } /* H5Arename/rename_by_name */ case H5VL_ATTR_RENAME: { - const char *old_name = HDva_arg(arguments, const char *); - const char *new_name = HDva_arg(arguments, const char *); - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Arename */ /* Call attribute rename routine */ - if (H5O__attr_rename(loc.oloc, old_name, new_name) < 0) + if (H5O__attr_rename(loc.oloc, args->args.rename.old_name, args->args.rename.new_name) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Arename_by_name */ /* Call attribute rename routine */ - if (H5A__rename_by_name(loc, loc_params->loc_data.loc_by_name.name, old_name, new_name) < 0) + if (H5A__rename_by_name(loc, loc_params->loc_data.loc_by_name.name, + args->args.rename.old_name, args->args.rename.new_name) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") } /* end else-if */ else @@ -541,24 +532,24 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_attr_optional(void H5_ATTR_UNUSED *obj, H5VL_attr_optional_t opt_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, - va_list H5_ATTR_DEPRECATED_USED arguments) +H5VL__native_attr_optional(void H5_ATTR_UNUSED *obj, H5VL_optional_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { - herr_t ret_value = SUCCEED; /* Return value */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + H5VL_native_attr_optional_args_t *opt_args = args->args; /* Pointer to native operation's arguments */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (opt_type) { + switch (args->op_type) { #ifndef H5_NO_DEPRECATED_SYMBOLS case H5VL_NATIVE_ATTR_ITERATE_OLD: { - hid_t loc_id = HDva_arg(arguments, hid_t); - unsigned * attr_num = HDva_arg(arguments, unsigned *); - H5A_operator1_t op = HDva_arg(arguments, H5A_operator1_t); - void * op_data = HDva_arg(arguments, void *); + H5VL_native_attr_iterate_old_t *iter_args = &opt_args->iterate_old; /* Call the actual iteration routine */ - if ((ret_value = H5A__iterate_old(loc_id, attr_num, op, op_data)) < 0) + if ((ret_value = H5A__iterate_old(iter_args->loc_id, iter_args->attr_num, iter_args->op, + iter_args->op_data)) < 0) HERROR(H5E_VOL, H5E_BADITER, "error iterating over attributes"); break; diff --git a/src/H5VLnative_blob.c b/src/H5VLnative_blob.c index 170a5bc..1107227 100644 --- a/src/H5VLnative_blob.c +++ b/src/H5VLnative_blob.c @@ -145,7 +145,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments) +H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_args_t *args) { H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */ herr_t ret_value = SUCCEED; /* Return value */ @@ -156,44 +156,24 @@ H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specif HDassert(f); HDassert(blob_id); - switch (specific_type) { - case H5VL_BLOB_GETSIZE: { - const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ - size_t * size = HDva_arg(arguments, size_t *); - H5HG_t hobjid; /* blob's heap ID */ - - /* Get heap information */ - H5F_addr_decode(f, &id, &(hobjid.addr)); - UINT32DECODE(id, hobjid.idx); - - /* Get heap object's size */ - if (hobjid.addr > 0) { - if (H5HG_get_obj_size(f, &hobjid, size) < 0) - HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "unable to remove heap object") - } /* end if */ - else - *size = 0; /* Return '0' size for 'nil' blob ID */ - - break; - } - + switch (args->op_type) { case H5VL_BLOB_ISNULL: { - const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ - hbool_t * isnull = HDva_arg(arguments, hbool_t *); - haddr_t addr; /* Sequence's heap address */ + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ + haddr_t addr; /* Sequence's heap address */ /* Get the heap address */ H5F_addr_decode(f, &id, &addr); /* Check if heap address is 'nil' */ - *isnull = (addr == 0 ? TRUE : FALSE); + *args->args.is_null.isnull = (addr == 0 ? TRUE : FALSE); break; } case H5VL_BLOB_SETNULL: { uint8_t *id = (uint8_t *)blob_id; /* Pointer to the blob ID */ - /* Encode the "nil" heap pointer information */ + + /* Encode the 'nil' heap pointer information */ H5F_addr_encode(f, &id, (haddr_t)0); UINT32ENCODE(id, 0); diff --git a/src/H5VLnative_dataset.c b/src/H5VLnative_dataset.c index 3a7f105..1375344 100644 --- a/src/H5VLnative_dataset.c +++ b/src/H5VLnative_dataset.c @@ -369,31 +369,26 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_dataset_get(void *obj, H5VL_dataset_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_dataset_get(void *obj, H5VL_dataset_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5D_t *dset = (H5D_t *)obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (get_type) { + switch (args->op_type) { /* H5Dget_space */ case H5VL_DATASET_GET_SPACE: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - - if ((*ret_id = H5D__get_space(dset)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get space ID of dataset") + if ((args->args.get_space.space_id = H5D__get_space(dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get space ID of dataset") break; } /* H5Dget_space_status */ case H5VL_DATASET_GET_SPACE_STATUS: { - H5D_space_status_t *allocation = HDva_arg(arguments, H5D_space_status_t *); - - /* Read data space address and return */ - if (H5D__get_space_status(dset, allocation) < 0) + if (H5D__get_space_status(dset, args->args.get_space_status.status) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get space status") break; @@ -401,40 +396,31 @@ H5VL__native_dataset_get(void *obj, H5VL_dataset_get_t get_type, hid_t H5_ATTR_U /* H5Dget_type */ case H5VL_DATASET_GET_TYPE: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - - if ((*ret_id = H5D__get_type(dset)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of dataset") + if ((args->args.get_type.type_id = H5D__get_type(dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get datatype ID of dataset") break; } /* H5Dget_create_plist */ case H5VL_DATASET_GET_DCPL: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - - if ((*ret_id = H5D_get_create_plist(dset)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for dataset") + if ((args->args.get_dcpl.dcpl_id = H5D_get_create_plist(dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get creation property list for dataset") break; } /* H5Dget_access_plist */ case H5VL_DATASET_GET_DAPL: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - - if ((*ret_id = H5D_get_access_plist(dset)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get access property list for dataset") + if ((args->args.get_dapl.dapl_id = H5D_get_access_plist(dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get access property list for dataset") break; } /* H5Dget_storage_size */ case H5VL_DATASET_GET_STORAGE_SIZE: { - hsize_t *ret = HDva_arg(arguments, hsize_t *); - - /* Set return value */ - if (H5D__get_storage_size(dset, ret) < 0) + if (H5D__get_storage_size(dset, args->args.get_storage_size.storage_size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get size of dataset's storage") break; } @@ -457,69 +443,38 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_dataset_specific(void *obj, H5VL_dataset_specific_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5D_t *dset = (H5D_t *)obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (specific_type) { - /* H5Dspecific_space */ - case H5VL_DATASET_SET_EXTENT: { /* H5Dset_extent (H5Dextend - deprecated) */ - const hsize_t *size = HDva_arg(arguments, const hsize_t *); - - if (H5D__set_extent(dset, size) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extent of dataset") + switch (args->op_type) { + /* H5Dset_extent (H5Dextend - deprecated) */ + case H5VL_DATASET_SET_EXTENT: { + if (H5D__set_extent(dset, args->args.set_extent.size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set extent of dataset") break; } - case H5VL_DATASET_FLUSH: { /* H5Dflush */ - hid_t dset_id = HDva_arg(arguments, hid_t); - - /* Flush the dataset */ - if (H5D__flush(dset, dset_id) < 0) + /* H5Dflush */ + case H5VL_DATASET_FLUSH: { + if (H5D__flush(dset, args->args.flush.dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush dataset") break; } - case H5VL_DATASET_REFRESH: { /* H5Drefresh */ - hid_t dset_id = HDva_arg(arguments, hid_t); - - /* Refresh the dataset */ - if ((H5D__refresh(dset_id, dset)) < 0) + /* H5Drefresh */ + case H5VL_DATASET_REFRESH: { + if (H5D__refresh(dset, args->args.refresh.dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to refresh dataset") break; } - case H5VL_DATASET_WAIT: { /* H5Dwait */ - /* The native VOL connector doesn't support asynchronous - * operations, so this is a no-op. - */ - break; - } - - case H5VL_DATASET_CHUNK_ITER: { /* H5Dchunk_iter */ - H5D_chunk_iter_op_t cb = HDva_arg(arguments, H5D_chunk_iter_op_t); - void * op_data = HDva_arg(arguments, void *); - - HDassert(dset->shared); - - /* Make sure the dataset is chunked */ - if (H5D_CHUNKED != dset->shared->layout.type) { - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") - } - - /* Call private function */ - if (H5D__chunk_iter(dset, cb, op_data) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't iterate over chunks") - - break; - } - default: HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") } /* end switch */ @@ -538,11 +493,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, hid_t dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_dataset_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void H5_ATTR_UNUSED **req) { - H5D_t *dset = (H5D_t *)obj; /* Dataset */ - herr_t ret_value = SUCCEED; /* Return value */ + H5D_t * dset = (H5D_t *)obj; /* Dataset */ + H5VL_native_dataset_optional_args_t *opt_args = args->args; /* Pointer to native operation's arguments */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE @@ -552,13 +507,14 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, /* Set DXPL for operation */ H5CX_set_dxpl(dxpl_id); - switch (optional_type) { - case H5VL_NATIVE_DATASET_FORMAT_CONVERT: { /* H5Dformat_convert */ + switch (args->op_type) { + /* H5Dformat_convert */ + case H5VL_NATIVE_DATASET_FORMAT_CONVERT: { switch (dset->shared->layout.type) { case H5D_CHUNKED: /* Convert the chunk indexing type to version 1 B-tree if not */ if (dset->shared->layout.u.chunk.idx_type != H5D_CHUNK_IDX_BTREE) - if ((H5D__format_convert(dset)) < 0) + if (H5D__format_convert(dset) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to downgrade chunk indexing type for dataset") break; @@ -567,7 +523,7 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, case H5D_COMPACT: /* Downgrade the layout version to 3 if greater than 3 */ if (dset->shared->layout.version > H5O_LAYOUT_VERSION_DEFAULT) - if ((H5D__format_convert(dset)) < 0) + if (H5D__format_convert(dset) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTLOAD, FAIL, "unable to downgrade layout version for dataset") break; @@ -587,47 +543,46 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, break; } - case H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE: { /* H5Dget_chunk_index_type */ - H5D_chunk_index_t *idx_type = HDva_arg(arguments, H5D_chunk_index_t *); - + /* H5Dget_chunk_index_type */ + case H5VL_NATIVE_DATASET_GET_CHUNK_INDEX_TYPE: { /* Make sure the dataset is chunked */ if (H5D_CHUNKED != dset->shared->layout.type) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") /* Get the chunk indexing type */ - *idx_type = dset->shared->layout.u.chunk.idx_type; + *opt_args->get_chunk_idx_type.idx_type = dset->shared->layout.u.chunk.idx_type; break; } - case H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE: { /* H5Dget_chunk_storage_size */ - hsize_t *offset = HDva_arg(arguments, hsize_t *); - hsize_t *chunk_nbytes = HDva_arg(arguments, hsize_t *); + /* H5Dget_chunk_storage_size */ + case H5VL_NATIVE_DATASET_GET_CHUNK_STORAGE_SIZE: { + H5VL_native_dataset_get_chunk_storage_size_t *gcss_args = &opt_args->get_chunk_storage_size; /* Make sure the dataset is chunked */ if (H5D_CHUNKED != dset->shared->layout.type) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") /* Call private function */ - if (H5D__get_chunk_storage_size(dset, offset, chunk_nbytes) < 0) + if (H5D__get_chunk_storage_size(dset, gcss_args->offset, gcss_args->size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get storage size of chunk") break; } - case H5VL_NATIVE_DATASET_GET_NUM_CHUNKS: { /* H5Dget_num_chunks */ - const H5S_t *space = NULL; - hid_t space_id = HDva_arg(arguments, hid_t); - hsize_t * nchunks = HDva_arg(arguments, hsize_t *); + /* H5Dget_num_chunks */ + case H5VL_NATIVE_DATASET_GET_NUM_CHUNKS: { + H5VL_native_dataset_get_num_chunks_t *gnc_args = &opt_args->get_num_chunks; + const H5S_t * space = NULL; HDassert(dset->shared); HDassert(dset->shared->space); /* When default dataspace is given, use the dataset's dataspace */ - if (space_id == H5S_ALL) + if (gnc_args->space_id == H5S_ALL) space = dset->shared->space; else /* otherwise, use the given space ID */ - if (NULL == (space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + if (NULL == (space = (const H5S_t *)H5I_object_verify(gnc_args->space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid dataspace ID") /* Make sure the dataset is chunked */ @@ -635,29 +590,25 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") /* Call private function */ - if (H5D__get_num_chunks(dset, space, nchunks) < 0) + if (H5D__get_num_chunks(dset, space, gnc_args->nchunks) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get number of chunks") break; } - case H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX: { /* H5Dget_chunk_info */ - const H5S_t *space = NULL; - hid_t space_id = HDva_arg(arguments, hid_t); - hsize_t chk_index = HDva_arg(arguments, hsize_t); - hsize_t * offset = HDva_arg(arguments, hsize_t *); - unsigned * filter_mask = HDva_arg(arguments, unsigned *); - haddr_t * addr = HDva_arg(arguments, haddr_t *); - hsize_t * size = HDva_arg(arguments, hsize_t *); + /* H5Dget_chunk_info */ + case H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_IDX: { + H5VL_native_dataset_get_chunk_info_by_idx_t *gcibi_args = &opt_args->get_chunk_info_by_idx; + const H5S_t * space; HDassert(dset->shared); HDassert(dset->shared->space); /* When default dataspace is given, use the dataset's dataspace */ - if (space_id == H5S_ALL) + if (gcibi_args->space_id == H5S_ALL) space = dset->shared->space; else /* otherwise, use the given space ID */ - if (NULL == (space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + if (NULL == (space = (const H5S_t *)H5I_object_verify(gcibi_args->space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid dataspace ID") /* Make sure the dataset is chunked */ @@ -665,16 +616,16 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") /* Call private function */ - if (H5D__get_chunk_info(dset, space, chk_index, offset, filter_mask, addr, size) < 0) + if (H5D__get_chunk_info(dset, space, gcibi_args->chk_index, gcibi_args->offset, + gcibi_args->filter_mask, gcibi_args->addr, gcibi_args->size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info by index") + break; } - case H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD: { /* H5Dget_chunk_info_by_coord */ - hsize_t * offset = HDva_arg(arguments, hsize_t *); - unsigned *filter_mask = HDva_arg(arguments, unsigned *); - haddr_t * addr = HDva_arg(arguments, haddr_t *); - hsize_t * size = HDva_arg(arguments, hsize_t *); + /* H5Dget_chunk_info_by_coord */ + case H5VL_NATIVE_DATASET_GET_CHUNK_INFO_BY_COORD: { + H5VL_native_dataset_get_chunk_info_by_coord_t *gcibc_args = &opt_args->get_chunk_info_by_coord; HDassert(dset->shared); @@ -683,17 +634,17 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") /* Call private function */ - if (H5D__get_chunk_info_by_coord(dset, offset, filter_mask, addr, size) < 0) + if (H5D__get_chunk_info_by_coord(dset, gcibc_args->offset, gcibc_args->filter_mask, + gcibc_args->addr, gcibc_args->size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info by its logical coordinates") break; } - case H5VL_NATIVE_DATASET_CHUNK_READ: { /* H5Dread_chunk */ - const hsize_t *offset = HDva_arg(arguments, hsize_t *); - uint32_t * filters = HDva_arg(arguments, uint32_t *); - void * buf = HDva_arg(arguments, void *); - hsize_t offset_copy[H5O_LAYOUT_NDIMS]; /* Internal copy of chunk offset */ + /* H5Dread_chunk */ + case H5VL_NATIVE_DATASET_CHUNK_READ: { + H5VL_native_dataset_chunk_read_t *chunk_read_args = &opt_args->chunk_read; + hsize_t offset_copy[H5O_LAYOUT_NDIMS]; /* Internal copy of chunk offset */ /* Check arguments */ if (NULL == dset->oloc.file) @@ -704,22 +655,21 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, /* Copy the user's offset array so we can be sure it's terminated properly. * (we don't want to mess with the user's buffer). */ - if (H5D__get_offset_copy(dset, offset, offset_copy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "failure to copy offset array") + if (H5D__chunk_get_offset_copy(dset, chunk_read_args->offset, offset_copy) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "failure to copy offset array") /* Read the raw chunk */ - if (H5D__chunk_direct_read(dset, offset_copy, filters, buf) < 0) + if (H5D__chunk_direct_read(dset, offset_copy, &chunk_read_args->filters, chunk_read_args->buf) < + 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read unprocessed chunk data") break; } - case H5VL_NATIVE_DATASET_CHUNK_WRITE: { /* H5Dwrite_chunk */ - uint32_t filters = HDva_arg(arguments, uint32_t); - const hsize_t *offset = HDva_arg(arguments, const hsize_t *); - uint32_t data_size_32 = HDva_arg(arguments, uint32_t); - const void * buf = HDva_arg(arguments, const void *); - hsize_t offset_copy[H5O_LAYOUT_NDIMS]; /* Internal copy of chunk offset */ + /* H5Dwrite_chunk */ + case H5VL_NATIVE_DATASET_CHUNK_WRITE: { + H5VL_native_dataset_chunk_write_t *chunk_write_args = &opt_args->chunk_write; + hsize_t offset_copy[H5O_LAYOUT_NDIMS]; /* Internal copy of chunk offset */ /* Check arguments */ if (NULL == dset->oloc.file) @@ -730,34 +680,48 @@ H5VL__native_dataset_optional(void *obj, H5VL_dataset_optional_t optional_type, /* Copy the user's offset array so we can be sure it's terminated properly. * (we don't want to mess with the user's buffer). */ - if (H5D__get_offset_copy(dset, offset, offset_copy) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "failure to copy offset array") + if (H5D__chunk_get_offset_copy(dset, chunk_write_args->offset, offset_copy) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "failure to copy offset array") /* Write chunk */ - if (H5D__chunk_direct_write(dset, filters, offset_copy, data_size_32, buf) < 0) + if (H5D__chunk_direct_write(dset, chunk_write_args->filters, offset_copy, chunk_write_args->size, + chunk_write_args->buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write unprocessed chunk data") break; } - case H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE: { /* H5Dvlen_get_buf_size */ - hid_t type_id = HDva_arg(arguments, hid_t); - hid_t space_id = HDva_arg(arguments, hid_t); - hsize_t *size = HDva_arg(arguments, hsize_t *); + /* H5Dvlen_get_buf_size */ + case H5VL_NATIVE_DATASET_GET_VLEN_BUF_SIZE: { + H5VL_native_dataset_get_vlen_buf_size_t *gvbs_args = &opt_args->get_vlen_buf_size; - if (H5D__vlen_get_buf_size(dset, type_id, space_id, size) < 0) + if (H5D__vlen_get_buf_size(dset, gvbs_args->type_id, gvbs_args->space_id, gvbs_args->size) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get size of vlen buf needed") break; } /* H5Dget_offset */ case H5VL_NATIVE_DATASET_GET_OFFSET: { - haddr_t *ret = HDva_arg(arguments, haddr_t *); + /* Get offset */ + *opt_args->get_offset.offset = H5D__get_offset(dset); + + break; + } + + /* H5Dchunk_iter */ + case H5VL_NATIVE_DATASET_CHUNK_ITER: { + /* Sanity check */ + HDassert(dset->shared); + + /* Make sure the dataset is chunked */ + if (H5D_CHUNKED != dset->shared->layout.type) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset") + + /* Call private function */ + if ((ret_value = H5D__chunk_iter(dset, opt_args->chunk_iter.op, opt_args->chunk_iter.op_data)) < + 0) + HERROR(H5E_DATASET, H5E_BADITER, "chunk iteration failed"); - /* Set return value */ - *ret = H5D__get_offset(dset); - if (!H5F_addr_defined(*ret)) - *ret = HADDR_UNDEF; break; } diff --git a/src/H5VLnative_datatype.c b/src/H5VLnative_datatype.c index 84b13c3..bf6f37c 100644 --- a/src/H5VLnative_datatype.c +++ b/src/H5VLnative_datatype.c @@ -175,32 +175,34 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_datatype_get(void *obj, H5VL_datatype_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_datatype_get(void *obj, H5VL_datatype_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5T_t *dt = (H5T_t *)obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (get_type) { - case H5VL_DATATYPE_GET_BINARY: { - ssize_t *nalloc = HDva_arg(arguments, ssize_t *); - void * buf = HDva_arg(arguments, void *); - size_t size = HDva_arg(arguments, size_t); + switch (args->op_type) { + /* H5T_construct_datatype (library private routine) */ + case H5VL_DATATYPE_GET_BINARY_SIZE: { + if (H5T_encode(dt, NULL, args->args.get_binary_size.size) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't determine serialized length of datatype") + + break; + } - if (H5T_encode(dt, (unsigned char *)buf, &size) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't determine serialized length of datatype") + /* H5T_construct_datatype (library private routine) */ + case H5VL_DATATYPE_GET_BINARY: { + if (H5T_encode(dt, args->args.get_binary.buf, &args->args.get_binary.buf_size) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSERIALIZE, FAIL, "can't serialize datatype") - *nalloc = (ssize_t)size; break; } /* H5Tget_create_plist */ case H5VL_DATATYPE_GET_TCPL: { - hid_t *ret_id = HDva_arg(arguments, hid_t *); - - if (H5I_INVALID_HID == (*ret_id = H5T__get_create_plist(dt))) + if (H5I_INVALID_HID == (args->args.get_tcpl.tcpl_id = H5T__get_create_plist(dt))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get object creation info"); break; @@ -224,30 +226,26 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_datatype_specific(void *obj, H5VL_datatype_specific_t specific_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_datatype_specific(void *obj, H5VL_datatype_specific_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5T_t *dt = (H5T_t *)obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (specific_type) { + switch (args->op_type) { + /* H5VL_DATATYPE_FLUSH */ case H5VL_DATATYPE_FLUSH: { - hid_t type_id = HDva_arg(arguments, hid_t); - - /* To flush metadata and invoke flush callback if there is */ - if (H5O_flush_common(&dt->oloc, type_id) < 0) + if (H5O_flush_common(&dt->oloc, args->args.flush.type_id) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFLUSH, FAIL, "unable to flush datatype") break; } + /* H5VL_DATATYPE_REFRESH */ case H5VL_DATATYPE_REFRESH: { - hid_t type_id = HDva_arg(arguments, hid_t); - - /* Call private function to refresh datatype object */ - if ((H5O_refresh_metadata(type_id, dt->oloc)) < 0) + if ((H5O_refresh_metadata(&dt->oloc, args->args.refresh.type_id)) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL, "unable to refresh datatype") break; diff --git a/src/H5VLnative_file.c b/src/H5VLnative_file.c index 3bcaaba..4653bea 100644 --- a/src/H5VLnative_file.c +++ b/src/H5VLnative_file.c @@ -147,21 +147,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_file_get(void *obj, H5VL_file_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5F_t *f = NULL; /* File struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (get_type) { + switch (args->op_type) { /* "get container info" */ case H5VL_FILE_GET_CONT_INFO: { - H5VL_file_cont_info_t *info = HDva_arg(arguments, H5VL_file_cont_info_t *); - - /* Retrieve the file's container info */ - if (H5F__get_cont_info((H5F_t *)obj, info) < 0) + if (H5F__get_cont_info((H5F_t *)obj, args->args.get_cont_info.info) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file container info") break; @@ -169,31 +166,22 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED /* H5Fget_access_plist */ case H5VL_FILE_GET_FAPL: { - H5P_genplist_t *new_plist; /* New property list */ - hid_t * plist_id = HDva_arg(arguments, hid_t *); - - f = (H5F_t *)obj; - - /* Retrieve the file's access property list */ - if ((*plist_id = H5F_get_access_plist(f, TRUE)) < 0) + if ((args->args.get_fapl.fapl_id = H5F_get_access_plist((H5F_t *)obj, TRUE)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file access property list") - if (NULL == (new_plist = (H5P_genplist_t *)H5I_object(*plist_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") break; } /* H5Fget_create_plist */ case H5VL_FILE_GET_FCPL: { H5P_genplist_t *plist; /* Property list */ - hid_t * plist_id = HDva_arg(arguments, hid_t *); f = (H5F_t *)obj; if (NULL == (plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") /* Create the property list object to return */ - if ((*plist_id = H5P_copy_plist(plist, TRUE)) < 0) + if ((args->args.get_fcpl.fcpl_id = H5P_copy_plist(plist, TRUE)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy file creation properties") break; @@ -201,8 +189,6 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED /* H5Fget_intent */ case H5VL_FILE_GET_INTENT: { - unsigned *intent_flags = HDva_arg(arguments, unsigned *); - f = (H5F_t *)obj; /* HDF5 uses some flags internally that users don't know about. @@ -210,18 +196,18 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED * or H5F_ACC_RDONLY and any SWMR flags. */ if (H5F_INTENT(f) & H5F_ACC_RDWR) { - *intent_flags = H5F_ACC_RDWR; + *args->args.get_intent.flags = H5F_ACC_RDWR; /* Check for SWMR write access on the file */ if (H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) - *intent_flags |= H5F_ACC_SWMR_WRITE; + *args->args.get_intent.flags |= H5F_ACC_SWMR_WRITE; } /* end if */ else { - *intent_flags = H5F_ACC_RDONLY; + *args->args.get_intent.flags = H5F_ACC_RDONLY; /* Check for SWMR read access on the file */ if (H5F_INTENT(f) & H5F_ACC_SWMR_READ) - *intent_flags |= H5F_ACC_SWMR_READ; + *args->args.get_intent.flags |= H5F_ACC_SWMR_READ; } /* end else */ break; @@ -229,71 +215,52 @@ H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED /* H5Fget_fileno */ case H5VL_FILE_GET_FILENO: { - unsigned long *fno = HDva_arg(arguments, unsigned long *); - unsigned long my_fileno = 0; + unsigned long fileno = 0; - f = (H5F_t *)obj; - H5F_GET_FILENO(f, my_fileno); - *fno = my_fileno; /* sigh */ + H5F_GET_FILENO((H5F_t *)obj, fileno); + *args->args.get_fileno.fileno = fileno; break; } /* H5Fget_name */ case H5VL_FILE_GET_NAME: { - H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ - size_t size = HDva_arg(arguments, size_t); - char * name = HDva_arg(arguments, char *); - ssize_t * ret = HDva_arg(arguments, ssize_t *); - size_t len; + H5VL_file_get_name_args_t *file_args = &args->args.get_name; - if (H5VL_native_get_file_struct(obj, type, &f) < 0) + if (H5VL_native_get_file_struct(obj, file_args->type, &f) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - len = HDstrlen(H5F_OPEN_NAME(f)); + /* Get length of file name */ + *file_args->file_name_len = HDstrlen(H5F_OPEN_NAME(f)); - if (name) { - HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1, size)); - if (len >= size) - name[size - 1] = '\0'; + /* Populate buffer with name, if given */ + if (file_args->buf) { + HDstrncpy(file_args->buf, H5F_OPEN_NAME(f), + MIN(*file_args->file_name_len + 1, file_args->buf_size)); + if (*file_args->file_name_len >= file_args->buf_size) + file_args->buf[file_args->buf_size - 1] = '\0'; } /* end if */ - /* Set the return value for the API call */ - *ret = (ssize_t)len; break; } /* H5Fget_obj_count */ case H5VL_FILE_GET_OBJ_COUNT: { - unsigned types = HDva_arg(arguments, unsigned); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - size_t obj_count = 0; /* Number of opened objects */ - - f = (H5F_t *)obj; - /* Perform the query */ - if (H5F_get_obj_count(f, types, TRUE, &obj_count) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_count failed") + if (H5F_get_obj_count((H5F_t *)obj, args->args.get_obj_count.types, TRUE, + args->args.get_obj_count.count) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve object count") - /* Set the return value */ - *ret = (ssize_t)obj_count; break; } /* H5Fget_obj_ids */ case H5VL_FILE_GET_OBJ_IDS: { - unsigned types = HDva_arg(arguments, unsigned); - size_t max_objs = HDva_arg(arguments, size_t); - hid_t * oid_list = HDva_arg(arguments, hid_t *); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - size_t obj_count = 0; /* Number of opened objects */ + H5VL_file_get_obj_ids_args_t *file_args = &args->args.get_obj_ids; - f = (H5F_t *)obj; - /* Perform the query */ - if (H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_count) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_ids failed") + if (H5F_get_obj_ids((H5F_t *)obj, file_args->types, file_args->max_objs, file_args->oid_list, + TRUE, file_args->count) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve object IDs") - /* Set the return value */ - *ret = (ssize_t)obj_count; break; } @@ -315,22 +282,20 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_file_specific(void *obj, H5VL_file_specific_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (specific_type) { + switch (args->op_type) { /* H5Fflush */ case H5VL_FILE_FLUSH: { - H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ - H5F_scope_t scope = (H5F_scope_t)HDva_arg(arguments, int); /* enum work-around */ - H5F_t * f = NULL; /* File to flush */ + H5F_t *f = NULL; /* File to flush */ /* Get the file for the object */ - if (H5VL_native_get_file_struct(obj, type, &f) < 0) + if (H5VL_native_get_file_struct(obj, args->args.flush.obj_type, &f) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Nothing to do if the file is read only. This determination is @@ -341,7 +306,7 @@ H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, hid_t */ if (H5F_ACC_RDWR & H5F_INTENT(f)) { /* Flush other files, depending on scope */ - if (H5F_SCOPE_GLOBAL == scope) { + if (H5F_SCOPE_GLOBAL == args->args.flush.scope) { /* Call the flush routine for mounted file hierarchies */ if (H5F_flush_mounts(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush mounted file hierarchy") @@ -353,98 +318,55 @@ H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, hid_t "unable to flush file's cached information") } /* end else */ } /* end if */ + break; } /* H5Freopen */ case H5VL_FILE_REOPEN: { - void **ret = HDva_arg(arguments, void **); - H5F_t *new_file = NULL; + H5F_t *new_file; /* Reopen the file through the VOL connector */ if (NULL == (new_file = H5F__reopen((H5F_t *)obj))) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") new_file->id_exists = TRUE; - *ret = (void *)new_file; - break; - } - - /* H5Fmount */ - case H5VL_FILE_MOUNT: { - H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ - const char *name = HDva_arg(arguments, const char *); - H5F_t * child = HDva_arg(arguments, H5F_t *); - hid_t fmpl_id = HDva_arg(arguments, hid_t); - H5G_loc_t loc; - - if (H5G_loc_real(obj, type, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - - /* Do the mount */ - if (H5F__mount(&loc, name, child, fmpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file") - - break; - } - - /* H5Funmount */ - case H5VL_FILE_UNMOUNT: { - H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ - const char *name = HDva_arg(arguments, const char *); - H5G_loc_t loc; - - if (H5G_loc_real(obj, type, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - - /* Unmount */ - if (H5F__unmount(&loc, name) < 0) - HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to unmount file") + /* Set 'out' value */ + *args->args.reopen.file = new_file; break; } /* H5Fis_accessible */ case H5VL_FILE_IS_ACCESSIBLE: { - hid_t fapl_id = HDva_arg(arguments, hid_t); - const char *name = HDva_arg(arguments, const char *); - htri_t * result = HDva_arg(arguments, htri_t *); + htri_t result; + + if ((result = H5F__is_hdf5(args->args.is_accessible.filename, args->args.is_accessible.fapl_id)) < + 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "error in HDF5 file check") + + /* Set 'out' value */ + *args->args.is_accessible.accessible = (hbool_t)result; - /* Call private routine */ - if ((*result = H5F__is_hdf5(name, fapl_id)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "error in HDF5 file check") break; } /* H5Fdelete */ case H5VL_FILE_DELETE: { - hid_t fapl_id = HDva_arg(arguments, hid_t); - const char *name = HDva_arg(arguments, const char *); - herr_t * ret = HDva_arg(arguments, herr_t *); + if (H5F__delete(args->args.del.filename, args->args.del.fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "error in HDF5 file deletion") - /* Call private routine */ - if ((*ret = H5F_delete(name, fapl_id)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "error in HDF5 file check") break; } /* Check if two files are the same */ case H5VL_FILE_IS_EQUAL: { - H5F_t * file2 = (H5F_t *)HDva_arg(arguments, void *); - hbool_t *is_equal = HDva_arg(arguments, hbool_t *); - - if (!obj || !file2) - *is_equal = FALSE; + if (!obj || !args->args.is_equal.obj2) + *args->args.is_equal.same_file = FALSE; else - *is_equal = (((H5F_t *)obj)->shared == file2->shared); - break; - } + *args->args.is_equal.same_file = + (((H5F_t *)obj)->shared == ((H5F_t *)args->args.is_equal.obj2)->shared); - /* H5Fwait */ - case H5VL_FILE_WAIT: { - /* The native VOL connector doesn't support asynchronous - * operations, so this is a no-op. - */ break; } @@ -466,85 +388,78 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_file_optional(void *obj, H5VL_optional_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { - H5F_t *f = NULL; /* File */ - herr_t ret_value = SUCCEED; /* Return value */ + H5F_t * f = (H5F_t *)obj; /* File */ + H5VL_native_file_optional_args_t *opt_args = args->args; /* Pointer to native operation's arguments */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - f = (H5F_t *)obj; - switch (optional_type) { + switch (args->op_type) { /* H5Fget_filesize */ case H5VL_NATIVE_FILE_GET_SIZE: { - haddr_t max_eof_eoa; /* Maximum of the EOA & EOF */ - haddr_t base_addr; /* Base address for the file */ - hsize_t *size = HDva_arg(arguments, hsize_t *); + haddr_t max_eof_eoa; /* Maximum of the EOA & EOF */ + haddr_t base_addr; /* Base address for the file */ - /* Go get the actual file size */ + /* Get the actual file size & base address */ if (H5F__get_max_eof_eoa(f, &max_eof_eoa) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ") - base_addr = H5FD_get_base_addr(f->shared->lf); - if (size) - *size = (hsize_t)(max_eof_eoa + - base_addr); /* Convert relative base address for file to absolute address */ + /* Convert relative base address for file to absolute address */ + *opt_args->get_size.size = (hsize_t)(max_eof_eoa + base_addr); break; } /* H5Fget_file_image */ case H5VL_NATIVE_FILE_GET_FILE_IMAGE: { - void * buf_ptr = HDva_arg(arguments, void *); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - size_t buf_len = HDva_arg(arguments, size_t); + H5VL_native_file_get_file_image_t *gfi_args = &opt_args->get_file_image; - /* Do the actual work */ - if ((*ret = H5F__get_file_image(f, buf_ptr, buf_len)) < 0) + /* Get file image */ + if (H5F__get_file_image(f, gfi_args->buf, gfi_args->buf_size, gfi_args->image_len) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "get file image failed") + break; } /* H5Fget_freespace */ case H5VL_NATIVE_FILE_GET_FREE_SPACE: { - hsize_t tot_space; /* Amount of free space in the file */ - hssize_t *ret = HDva_arg(arguments, hssize_t *); + H5VL_native_file_get_freespace_t *gfs_args = &opt_args->get_freespace; - /* Go get the actual amount of free space in the file */ - if (H5MF_get_freespace(f, &tot_space, NULL) < 0) + /* Get the actual amount of free space in the file */ + if (H5MF_get_freespace(f, gfs_args->size, NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") - *ret = (hssize_t)tot_space; + break; } /* H5Fget_free_sections */ case H5VL_NATIVE_FILE_GET_FREE_SECTIONS: { - H5F_sect_info_t *sect_info = HDva_arg(arguments, H5F_sect_info_t *); - ssize_t * ret = HDva_arg(arguments, ssize_t *); - H5F_mem_t type = (H5F_mem_t)HDva_arg(arguments, int); /* enum work-around */ - size_t nsects = HDva_arg(arguments, size_t); + H5VL_native_file_get_free_sections_t *gfs_args = &opt_args->get_free_sections; /* Go get the free-space section information in the file */ - if ((*ret = H5MF_get_free_sections(f, type, nsects, sect_info)) < 0) + if (H5MF_get_free_sections(f, gfs_args->type, gfs_args->nsects, gfs_args->sect_info, + gfs_args->sect_count) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") + break; } /* H5Fget_info1/2 */ case H5VL_NATIVE_FILE_GET_INFO: { - H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ - H5F_info2_t *finfo = HDva_arg(arguments, H5F_info2_t *); + H5VL_native_file_get_info_t *gfi_args = &opt_args->get_info; /* Get the file struct. This call is careful to not return the file pointer * for the top file in a mount hierarchy. */ - if (H5VL_native_get_file_struct(obj, type, &f) < 0) + if (H5VL_native_get_file_struct(obj, gfi_args->type, &f) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get a file struct") /* Get the file info */ - if (H5F__get_info(f, finfo) < 0) + if (H5F__get_info(f, gfi_args->finfo) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve file info") break; @@ -552,50 +467,42 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_mdc_config */ case H5VL_NATIVE_FILE_GET_MDC_CONF: { - H5AC_cache_config_t *config_ptr = HDva_arg(arguments, H5AC_cache_config_t *); + /* Get the metadata cache configuration */ + if (H5AC_get_cache_auto_resize_config(f->shared->cache, opt_args->get_mdc_config.config) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get metadata cache configuration") - /* Go get the resize configuration */ - if (H5AC_get_cache_auto_resize_config(f->shared->cache, config_ptr) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_auto_resize_config() failed.") break; } /* H5Fget_mdc_hit_rate */ case H5VL_NATIVE_FILE_GET_MDC_HR: { - double *hit_rate_ptr = HDva_arg(arguments, double *); + /* Get the current hit rate */ + if (H5AC_get_cache_hit_rate(f->shared->cache, opt_args->get_mdc_hit_rate.hit_rate) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get metadata cache hit rate") - /* Go get the current hit rate */ - if (H5AC_get_cache_hit_rate(f->shared->cache, hit_rate_ptr) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_hit_rate() failed.") break; } /* H5Fget_mdc_size */ case H5VL_NATIVE_FILE_GET_MDC_SIZE: { - size_t * max_size_ptr = HDva_arg(arguments, size_t *); - size_t * min_clean_size_ptr = HDva_arg(arguments, size_t *); - size_t * cur_size_ptr = HDva_arg(arguments, size_t *); - int * cur_num_entries_ptr = HDva_arg(arguments, int *); - uint32_t cur_num_entries; + H5VL_native_file_get_mdc_size_t *gms_args = &opt_args->get_mdc_size; - /* Go get the size data */ - if (H5AC_get_cache_size(f->shared->cache, max_size_ptr, min_clean_size_ptr, cur_size_ptr, - &cur_num_entries) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_size() failed.") + /* Get the size data */ + if (H5AC_get_cache_size(f->shared->cache, gms_args->max_size, gms_args->min_clean_size, + gms_args->cur_size, gms_args->cur_num_entries) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get metadata cache size") - if (cur_num_entries_ptr != NULL) - *cur_num_entries_ptr = (int)cur_num_entries; break; } /* H5Fget_vfd_handle */ case H5VL_NATIVE_FILE_GET_VFD_HANDLE: { - void **file_handle = HDva_arg(arguments, void **); - hid_t fapl_id = HDva_arg(arguments, hid_t); + H5VL_native_file_get_vfd_handle_t *gvh_args = &opt_args->get_vfd_handle; /* Retrieve the VFD handle for the file */ - if (H5F_get_vfd_handle(f, fapl_id, file_handle) < 0) + if (H5F_get_vfd_handle(f, gvh_args->fapl_id, gvh_args->file_handle) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve VFD handle") + break; } @@ -605,6 +512,7 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t if (f->shared->efc) if (H5F__efc_release(f->shared->efc) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") + break; } @@ -612,26 +520,24 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t case H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE: { /* Reset the hit rate statistic */ if (H5AC_reset_cache_hit_rate_stats(f->shared->cache) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't reset cache hit rate") + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't reset cache hit rate") + break; } /* H5Fset_mdc_config */ case H5VL_NATIVE_FILE_SET_MDC_CONFIG: { - H5AC_cache_config_t *config_ptr = HDva_arg(arguments, H5AC_cache_config_t *); + /* Set the metadata cache configuration */ + if (H5AC_set_cache_auto_resize_config(f->shared->cache, opt_args->set_mdc_config.config) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set metadata cache configuration") - /* set the resize configuration */ - if (H5AC_set_cache_auto_resize_config(f->shared->cache, config_ptr) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "H5AC_set_cache_auto_resize_config() failed") break; } /* H5Fget_metadata_read_retry_info */ case H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO: { - H5F_retry_info_t *info = HDva_arg(arguments, H5F_retry_info_t *); - - if (H5F_get_metadata_read_retry_info(f, info) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't get metadata read retry info") + if (H5F_get_metadata_read_retry_info(f, opt_args->get_metadata_read_retry_info.info) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get metadata read retry info") break; } @@ -639,7 +545,7 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fstart_swmr_write */ case H5VL_NATIVE_FILE_START_SWMR_WRITE: { if (H5F__start_swmr_write(f) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't start SWMR write") + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't start SWMR write") break; } @@ -664,11 +570,11 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_mdc_logging_status */ case H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS: { - hbool_t *is_enabled = HDva_arg(arguments, hbool_t *); - hbool_t *is_currently_logging = HDva_arg(arguments, hbool_t *); + H5VL_native_file_get_mdc_logging_status_t *gmls_args = &opt_args->get_mdc_logging_status; /* Call mdc logging function */ - if (H5C_get_logging_status(f->shared->cache, is_enabled, is_currently_logging) < 0) + if (H5C_get_logging_status(f->shared->cache, gmls_args->is_enabled, + gmls_args->is_currently_logging) < 0) HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to get logging status") break; @@ -698,18 +604,15 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_page_buffering_stats */ case H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS: { - unsigned *accesses = HDva_arg(arguments, unsigned *); - unsigned *hits = HDva_arg(arguments, unsigned *); - unsigned *misses = HDva_arg(arguments, unsigned *); - unsigned *evictions = HDva_arg(arguments, unsigned *); - unsigned *bypasses = HDva_arg(arguments, unsigned *); + H5VL_native_file_get_page_buffering_stats_t *gpbs_args = &opt_args->get_page_buffering_stats; /* Sanity check */ if (NULL == f->shared->page_buf) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "page buffering not enabled on file") /* Get the statistics */ - if (H5PB_get_stats(f->shared->page_buf, accesses, hits, misses, evictions, bypasses) < 0) + if (H5PB_get_stats(f->shared->page_buf, gpbs_args->accesses, gpbs_args->hits, gpbs_args->misses, + gpbs_args->evictions, gpbs_args->bypasses) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stats for page buffering") break; @@ -717,11 +620,10 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_mdc_image_info */ case H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO: { - haddr_t *image_addr = HDva_arg(arguments, haddr_t *); - hsize_t *image_len = HDva_arg(arguments, hsize_t *); + H5VL_native_file_get_mdc_image_info_t *gmii_args = &opt_args->get_mdc_image_info; /* Go get the address and size of the cache image */ - if (H5AC_get_mdc_image_info(f->shared->cache, image_addr, image_len) < 0) + if (H5AC_get_mdc_image_info(f->shared->cache, gmii_args->addr, gmii_args->len) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve cache image info") break; @@ -729,11 +631,7 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_eoa */ case H5VL_NATIVE_FILE_GET_EOA: { - haddr_t *eoa = HDva_arg(arguments, haddr_t *); - haddr_t rel_eoa; /* Relative address of EOA */ - - /* Sanity check */ - HDassert(eoa); + haddr_t rel_eoa; /* Relative address of EOA */ /* This routine will work only for drivers with this feature enabled.*/ /* We might introduce a new feature flag in the future */ @@ -747,14 +645,13 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* Set return value */ /* (Note compensating for base address subtraction in internal routine) */ - *eoa = rel_eoa + H5F_get_base_addr(f); + *opt_args->get_eoa.eoa = rel_eoa + H5F_get_base_addr(f); break; } /* H5Fincrement_filesize */ case H5VL_NATIVE_FILE_INCR_FILESIZE: { - hsize_t increment = HDva_arg(arguments, hsize_t); haddr_t max_eof_eoa; /* Maximum of the relative EOA & EOF */ /* This public routine will work only for drivers with this feature enabled.*/ @@ -768,7 +665,7 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ") /* Set EOA to the maximum value + increment */ - if (H5F__set_eoa(f, H5FD_MEM_DEFAULT, max_eof_eoa + increment) < 0) + if (H5F__set_eoa(f, H5FD_MEM_DEFAULT, max_eof_eoa + opt_args->increment_filesize.increment) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "driver set_eoa request failed") break; @@ -776,11 +673,10 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fset_latest_format, H5Fset_libver_bounds */ case H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS: { - H5F_libver_t low = (H5F_libver_t)HDva_arg(arguments, int); /* enum work-around */ - H5F_libver_t high = (H5F_libver_t)HDva_arg(arguments, int); /* enum work-around */ + H5VL_native_file_set_libver_bounds_t *slb_args = &opt_args->set_libver_bounds; /* Call internal set_libver_bounds function */ - if (H5F__set_libver_bounds(f, low, high) < 0) + if (H5F__set_libver_bounds(f, slb_args->low, slb_args->high) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set low/high bounds") break; @@ -788,34 +684,34 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* H5Fget_dset_no_attrs_hint */ case H5VL_NATIVE_FILE_GET_MIN_DSET_OHDR_FLAG: { - hbool_t *minimize = HDva_arg(arguments, hbool_t *); - *minimize = H5F_GET_MIN_DSET_OHDR(f); + *opt_args->get_min_dset_ohdr_flag.minimize = H5F_GET_MIN_DSET_OHDR(f); + break; } /* H5Fset_dset_no_attrs_hint */ case H5VL_NATIVE_FILE_SET_MIN_DSET_OHDR_FLAG: { - int minimize = HDva_arg(arguments, int); - if (H5F_set_min_dset_ohdr(f, (hbool_t)minimize) < 0) + if (H5F_set_min_dset_ohdr(f, opt_args->set_min_dset_ohdr_flag.minimize) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set file's dataset object header minimization flag") + break; } #ifdef H5_HAVE_PARALLEL /* H5Fget_mpi_atomicity */ case H5VL_NATIVE_FILE_GET_MPI_ATOMICITY: { - hbool_t *flag = (hbool_t *)HDva_arg(arguments, hbool_t *); - if (H5F_get_mpi_atomicity(f, flag) < 0) + if (H5F__get_mpi_atomicity(f, opt_args->get_mpi_atomicity.flag) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "cannot get MPI atomicity"); + break; } /* H5Fset_mpi_atomicity */ case H5VL_NATIVE_FILE_SET_MPI_ATOMICITY: { - hbool_t flag = (hbool_t)HDva_arg(arguments, int); - if (H5F_set_mpi_atomicity(f, flag) < 0) + if (H5F__set_mpi_atomicity(f, opt_args->set_mpi_atomicity.flag) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set MPI atomicity"); + break; } #endif /* H5_HAVE_PARALLEL */ @@ -823,31 +719,28 @@ H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t /* Finalize H5Fopen */ case H5VL_NATIVE_FILE_POST_OPEN: { /* Call package routine */ - if (H5F__post_open((H5F_t *)obj) < 0) + if (H5F__post_open(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't finish opening file") break; } /* H5Fvfd_swmr_disable_end_of_tick() */ case H5VL_NATIVE_FILE_VFD_SWMR_DISABLE_EOT: { - /* Call package routine */ - if (H5F__vfd_swmr_disable_end_of_tick((H5F_t *)obj) < 0) + if (H5F__vfd_swmr_disable_end_of_tick(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't disable EOT for VFD SWMR") break; } /* H5Fvfd_swmr_enable_end_of_tick() */ case H5VL_NATIVE_FILE_VFD_SWMR_ENABLE_EOT: { - /* Call package routine */ - if (H5F__vfd_swmr_enable_end_of_tick((H5F_t *)obj) < 0) + if (H5F__vfd_swmr_enable_end_of_tick(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't enable EOT for VFD SWMR") break; } /* H5Fvfd_swmr_end_tick() */ case H5VL_NATIVE_FILE_VFD_SWMR_END_TICK: { - /* Call package routine */ - if (H5F__vfd_swmr_end_tick((H5F_t *)obj) < 0) + if (H5F__vfd_swmr_end_tick(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't trigger EOT processing for VFD SWMR") break; } @@ -898,7 +791,7 @@ H5VL__native_file_close(void *file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_U HGOTO_ERROR(H5E_ID, H5E_CANTGET, FAIL, "can't get ID ref count") if (nref == 1) if (H5F__flush(f) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush cache") } /* end if */ /* Close the file */ diff --git a/src/H5VLnative_group.c b/src/H5VLnative_group.c index 53f8459..54f8337 100644 --- a/src/H5VLnative_group.c +++ b/src/H5VLnative_group.c @@ -169,55 +169,54 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_group_get(void *obj, H5VL_group_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_group_get(void *obj, H5VL_group_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (get_type) { + switch (args->op_type) { /* H5Gget_create_plist */ case H5VL_GROUP_GET_GCPL: { - hid_t *new_gcpl_id = HDva_arg(arguments, hid_t *); - H5G_t *grp = (H5G_t *)obj; + if ((args->args.get_gcpl.gcpl_id = H5G_get_create_plist((H5G_t *)obj)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get creation property list for group") - if ((*new_gcpl_id = H5G_get_create_plist(grp)) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for group") break; } /* H5Gget_info */ case H5VL_GROUP_GET_INFO: { - const H5VL_loc_params_t *loc_params = HDva_arg(arguments, const H5VL_loc_params_t *); - H5G_info_t * group_info = HDva_arg(arguments, H5G_info_t *); - H5G_loc_t loc; + H5VL_group_get_info_args_t *get_info_args = &args->args.get_info; + H5G_loc_t loc; - if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) + if (H5G_loc_real(obj, get_info_args->loc_params.obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - if (loc_params->type == H5VL_OBJECT_BY_SELF) { + if (get_info_args->loc_params.type == H5VL_OBJECT_BY_SELF) { /* H5Gget_info */ /* Retrieve the group's information */ - if (H5G__obj_info(loc.oloc, group_info) < 0) + if (H5G__obj_info(loc.oloc, get_info_args->ginfo) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") } /* end if */ - else if (loc_params->type == H5VL_OBJECT_BY_NAME) { + else if (get_info_args->loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Gget_info_by_name */ /* Retrieve the group's information */ - if (H5G__get_info_by_name(&loc, loc_params->loc_data.loc_by_name.name, group_info) < 0) + if (H5G__get_info_by_name(&loc, get_info_args->loc_params.loc_data.loc_by_name.name, + get_info_args->ginfo) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") } /* end else-if */ - else if (loc_params->type == H5VL_OBJECT_BY_IDX) { + else if (get_info_args->loc_params.type == H5VL_OBJECT_BY_IDX) { /* H5Gget_info_by_idx */ /* Retrieve the group's information */ - if (H5G__get_info_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n, group_info) < 0) + if (H5G__get_info_by_idx(&loc, get_info_args->loc_params.loc_data.loc_by_idx.name, + get_info_args->loc_params.loc_data.loc_by_idx.idx_type, + get_info_args->loc_params.loc_data.loc_by_idx.order, + get_info_args->loc_params.loc_data.loc_by_idx.n, + get_info_args->ginfo) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") } /* end else-if */ else @@ -243,30 +242,53 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_group_specific(void *obj, H5VL_group_specific_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5G_t *grp = (H5G_t *)obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (specific_type) { - case H5VL_GROUP_FLUSH: { - hid_t group_id = HDva_arg(arguments, hid_t); + switch (args->op_type) { + /* H5Fmount */ + case H5VL_GROUP_MOUNT: { + H5G_loc_t loc; + + if (H5G_loc_real(grp, H5I_GROUP, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group object") + + if (H5F_mount(&loc, args->args.mount.name, args->args.mount.child_file, + args->args.mount.fmpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file") + + break; + } + + /* H5Funmount */ + case H5VL_GROUP_UNMOUNT: { + H5G_loc_t loc; + + if (H5G_loc_real(grp, H5I_GROUP, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group object") + + if (H5F_unmount(&loc, args->args.unmount.name) < 0) + HGOTO_ERROR(H5E_FILE, H5E_UNMOUNT, FAIL, "unable to unmount file") - /* Flush object's metadata to file */ - if (H5O_flush_common(&grp->oloc, group_id) < 0) + break; + } + + /* H5Gflush */ + case H5VL_GROUP_FLUSH: { + if (H5O_flush_common(&grp->oloc, args->args.flush.grp_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTFLUSH, FAIL, "unable to flush group") break; } + /* H5Grefresh */ case H5VL_GROUP_REFRESH: { - hid_t group_id = HDva_arg(arguments, hid_t); - - /* Call private function to refresh group object */ - if ((H5O_refresh_metadata(group_id, grp->oloc)) < 0) + if ((H5O_refresh_metadata(&grp->oloc, args->args.refresh.grp_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to refresh group") break; @@ -290,50 +312,53 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_group_optional(void H5_ATTR_UNUSED *obj, H5VL_group_optional_t optional_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, - va_list H5_ATTR_DEPRECATED_USED arguments) +H5VL__native_group_optional(void H5_ATTR_UNUSED *obj, H5VL_optional_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { - herr_t ret_value = SUCCEED; /* Return value */ +#ifndef H5_NO_DEPRECATED_SYMBOLS + H5VL_native_group_optional_args_t *opt_args = args->args; /* Pointer to native operation's arguments */ +#endif /* H5_NO_DEPRECATED_SYMBOLS */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (optional_type) { + switch (args->op_type) { #ifndef H5_NO_DEPRECATED_SYMBOLS /* H5Giterate (deprecated) */ case H5VL_NATIVE_GROUP_ITERATE_OLD: { - const H5VL_loc_params_t * loc_params = HDva_arg(arguments, const H5VL_loc_params_t *); - hsize_t idx = HDva_arg(arguments, hsize_t); - hsize_t * last_obj = HDva_arg(arguments, hsize_t *); - const H5G_link_iterate_t *lnk_op = HDva_arg(arguments, const H5G_link_iterate_t *); - void * op_data = HDva_arg(arguments, void *); - H5G_loc_t grp_loc; + H5VL_native_group_iterate_old_t *iter_args = &opt_args->iterate_old; + H5G_link_iterate_t lnk_op; /* Link operator */ + H5G_loc_t grp_loc; /* Get the location struct for the object */ - if (H5G_loc_real(obj, loc_params->obj_type, &grp_loc) < 0) + if (H5G_loc_real(obj, iter_args->loc_params.obj_type, &grp_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + /* Set up link iteration callback struct */ + lnk_op.op_type = H5G_LINK_OP_OLD; + lnk_op.op_func.op_old = iter_args->op; + /* Call the actual iteration routine */ - if ((ret_value = H5G_iterate(&grp_loc, loc_params->loc_data.loc_by_name.name, H5_INDEX_NAME, - H5_ITER_INC, idx, last_obj, lnk_op, op_data)) < 0) - HERROR(H5E_VOL, H5E_BADITER, "error iterating over group's links"); + if ((ret_value = H5G_iterate(&grp_loc, iter_args->loc_params.loc_data.loc_by_name.name, + H5_INDEX_NAME, H5_ITER_INC, iter_args->idx, iter_args->last_obj, + &lnk_op, iter_args->op_data)) < 0) + HERROR(H5E_SYM, H5E_BADITER, "error iterating over group's links"); break; } /* H5Gget_objinfo (deprecated) */ case H5VL_NATIVE_GROUP_GET_OBJINFO: { - const H5VL_loc_params_t *loc_params = HDva_arg(arguments, const H5VL_loc_params_t *); - hbool_t follow_link = (hbool_t)HDva_arg(arguments, unsigned); - H5G_stat_t * statbuf = HDva_arg(arguments, H5G_stat_t *); - H5G_loc_t grp_loc; + H5VL_native_group_get_objinfo_t *goi_args = &opt_args->get_objinfo; + H5G_loc_t grp_loc; /* Get the location struct for the object */ - if (H5G_loc_real(obj, loc_params->obj_type, &grp_loc) < 0) + if (H5G_loc_real(obj, goi_args->loc_params.obj_type, &grp_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Call the actual group objinfo routine */ - if (H5G__get_objinfo(&grp_loc, loc_params->loc_data.loc_by_name.name, follow_link, statbuf) < 0) + if (H5G__get_objinfo(&grp_loc, goi_args->loc_params.loc_data.loc_by_name.name, + goi_args->follow_link, goi_args->statbuf) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "cannot stat object") break; diff --git a/src/H5VLnative_introspect.c b/src/H5VLnative_introspect.c index 45efcf8..fa11bea 100644 --- a/src/H5VLnative_introspect.c +++ b/src/H5VLnative_introspect.c @@ -52,8 +52,9 @@ /* Local Variables */ /*******************/ -/* Note: H5VL__native_introspect_get_conn_cls is in src/H5VLnative.c so that - * it can return the address of the staticly declared class struct. +/* Note: H5VL__native_introspect_get_conn_cls and H5VL__native_introspect_get_cap_flags + * are in src/H5VLnative.c so that they can work with the staticly declared + * class struct. */ /*--------------------------------------------------------------------------- diff --git a/src/H5VLnative_link.c b/src/H5VLnative_link.c index eaba18f..042c778 100644 --- a/src/H5VLnative_link.c +++ b/src/H5VLnative_link.c @@ -68,20 +68,20 @@ *------------------------------------------------------------------------- */ herr_t -H5VL__native_link_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, +H5VL__native_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t H5_ATTR_UNUSED lapl_id, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) + void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (create_type) { + switch (args->op_type) { case H5VL_LINK_CREATE_HARD: { H5G_loc_t cur_loc; H5G_loc_t link_loc; - void * cur_obj = HDva_arg(arguments, void *); - H5VL_loc_params_t *cur_params = HDva_arg(arguments, H5VL_loc_params_t *); + void * cur_obj = args->args.hard.curr_obj; + H5VL_loc_params_t *cur_params = &args->args.hard.curr_loc_params; if (NULL != cur_obj && H5G_loc_real(cur_obj, cur_params->obj_type, &cur_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") @@ -104,46 +104,40 @@ H5VL__native_link_create(H5VL_link_create_type_t create_type, void *obj, const H "source and destination should be in the same file.") /* Create the link */ - if ((ret_value = - H5L__create_hard(cur_loc_p, cur_params->loc_data.loc_by_name.name, link_loc_p, - loc_params->loc_data.loc_by_name.name, lcpl_id)) < 0) + if (H5L__create_hard(cur_loc_p, cur_params->loc_data.loc_by_name.name, link_loc_p, + loc_params->loc_data.loc_by_name.name, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") } /* end if */ else { /* H5Olink */ /* Link to the object */ if (H5L_link(&link_loc, loc_params->loc_data.loc_by_name.name, &cur_loc, lcpl_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create link") + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") } /* end else */ + break; } case H5VL_LINK_CREATE_SOFT: { - char * target_name = HDva_arg(arguments, char *); H5G_loc_t link_loc; /* Group location for new link */ if (H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if (H5L__create_soft(args->args.soft.target, &link_loc, loc_params->loc_data.loc_by_name.name, + lcpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create link") - /* Create the link */ - if ((ret_value = H5L__create_soft(target_name, &link_loc, loc_params->loc_data.loc_by_name.name, - lcpl_id)) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") break; } case H5VL_LINK_CREATE_UD: { - H5G_loc_t link_loc; /* Group location for new link */ - H5L_type_t link_type = (H5L_type_t)HDva_arg(arguments, int); - void * udata = HDva_arg(arguments, void *); - size_t udata_size = HDva_arg(arguments, size_t); + H5G_loc_t link_loc; /* Group location for new link */ if (H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - - /* Create link */ - if (H5L__create_ud(&link_loc, loc_params->loc_data.loc_by_name.name, udata, udata_size, link_type, - lcpl_id) < 0) + if (H5L__create_ud(&link_loc, loc_params->loc_data.loc_by_name.name, args->args.ud.buf, + args->args.ud.buf_size, args->args.ud.type, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + break; } @@ -249,8 +243,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { H5G_loc_t loc; herr_t ret_value = SUCCEED; /* Return value */ @@ -260,20 +254,19 @@ H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_ if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - switch (get_type) { + switch (args->op_type) { /* H5Lget_info/H5Lget_info_by_idx */ case H5VL_LINK_GET_INFO: { - H5L_info2_t *linfo2 = HDva_arg(arguments, H5L_info2_t *); - /* Get the link information */ - if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Lget_info */ - if (H5L_get_info(&loc, loc_params->loc_data.loc_by_name.name, linfo2) < 0) + if (loc_params->type == H5VL_OBJECT_BY_NAME) { + if (H5L_get_info(&loc, loc_params->loc_data.loc_by_name.name, args->args.get_info.linfo) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") - } /* end if */ - else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Lget_info_by_idx */ - if (H5L__get_info_by_idx( - &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, linfo2) < 0) + } /* end if */ + else if (loc_params->type == H5VL_OBJECT_BY_IDX) { + if (H5L__get_info_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, + loc_params->loc_data.loc_by_idx.n, args->args.get_info.linfo) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") } /* end else-if */ else @@ -284,15 +277,11 @@ H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_ /* H5Lget_name_by_idx */ case H5VL_LINK_GET_NAME: { - char * name = HDva_arg(arguments, char *); - size_t size = HDva_arg(arguments, size_t); - ssize_t *ret = HDva_arg(arguments, ssize_t *); - - /* Get the link name */ - if ((*ret = H5L__get_name_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n, name, size)) < 0) + if (H5L__get_name_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, + loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, + args->args.get_name.name, args->args.get_name.name_size, + args->args.get_name.name_len) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info") break; @@ -300,20 +289,17 @@ H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_ /* H5Lget_val/H5Lget_val_by_idx */ case H5VL_LINK_GET_VAL: { - void * buf = HDva_arg(arguments, void *); - size_t size = HDva_arg(arguments, size_t); - /* Get the link information */ - if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Lget_val */ - if (H5L__get_val(&loc, loc_params->loc_data.loc_by_name.name, buf, size) < 0) + if (loc_params->type == H5VL_OBJECT_BY_NAME) { + if (H5L__get_val(&loc, loc_params->loc_data.loc_by_name.name, args->args.get_val.buf, + args->args.get_val.buf_size) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link value") } - else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Lget_val_by_idx */ - - if (H5L__get_val_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, - loc_params->loc_data.loc_by_idx.idx_type, - loc_params->loc_data.loc_by_idx.order, - loc_params->loc_data.loc_by_idx.n, buf, size) < 0) + else if (loc_params->type == H5VL_OBJECT_BY_IDX) { + if (H5L__get_val_by_idx( + &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, + loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, + args->args.get_val.buf, args->args.get_val.buf_size) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link val") } else @@ -340,35 +326,28 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_t specific_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE - switch (specific_type) { + switch (args->op_type) { case H5VL_LINK_EXISTS: { - hbool_t * exists = HDva_arg(arguments, hbool_t *); H5G_loc_t loc; if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - - /* Check for the existence of the link */ - if (H5L__exists(&loc, loc_params->loc_data.loc_by_name.name, exists) < 0) + if (H5L__exists(&loc, loc_params->loc_data.loc_by_name.name, args->args.exists.exists) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to specific link info") + break; } case H5VL_LINK_ITER: { - H5G_loc_t loc; - hbool_t recursive = (hbool_t)HDva_arg(arguments, unsigned); - H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */ - H5_iter_order_t order = (H5_iter_order_t)HDva_arg(arguments, int); /* enum work-around */ - hsize_t * idx_p = HDva_arg(arguments, hsize_t *); - H5L_iterate2_t op = HDva_arg(arguments, H5L_iterate2_t); - void * op_data = HDva_arg(arguments, void *); + H5VL_link_iterate_args_t *iter_args = &args->args.iterate; + H5G_loc_t loc; /* Get the location */ if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) @@ -376,28 +355,32 @@ H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ /* Visit or iterate over the links */ if (loc_params->type == H5VL_OBJECT_BY_SELF) { - if (recursive) { + if (iter_args->recursive) { /* H5Lvisit */ - if ((ret_value = H5G_visit(&loc, ".", idx_type, order, op, op_data)) < 0) + if ((ret_value = H5G_visit(&loc, ".", iter_args->idx_type, iter_args->order, + iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") } /* end if */ else { /* H5Literate */ - if ((ret_value = H5L_iterate(&loc, ".", idx_type, order, idx_p, op, op_data)) < 0) + if ((ret_value = H5L_iterate(&loc, ".", iter_args->idx_type, iter_args->order, + iter_args->idx_p, iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "error iterating over links") } /* end else */ } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { - if (recursive) { + if (iter_args->recursive) { /* H5Lvisit_by_name */ - if ((ret_value = H5G_visit(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, - op, op_data)) < 0) + if ((ret_value = + H5G_visit(&loc, loc_params->loc_data.loc_by_name.name, iter_args->idx_type, + iter_args->order, iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed") } /* end if */ else { /* H5Literate_by_name */ - if ((ret_value = H5L_iterate(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, - idx_p, op, op_data)) < 0) + if ((ret_value = H5L_iterate(&loc, loc_params->loc_data.loc_by_name.name, + iter_args->idx_type, iter_args->order, iter_args->idx_p, + iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "error iterating over links") } /* end else */ } /* end else-if */ diff --git a/src/H5VLnative_object.c b/src/H5VLnative_object.c index 95d4fff..d237617 100644 --- a/src/H5VLnative_object.c +++ b/src/H5VLnative_object.c @@ -169,8 +169,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, - hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ H5G_loc_t loc; /* Location of group */ @@ -180,14 +180,12 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - switch (get_type) { + switch (args->op_type) { /* Object file */ case H5VL_OBJECT_GET_FILE: { - void **ret = HDva_arg(arguments, void **); - if (loc_params->type == H5VL_OBJECT_BY_SELF) { - *ret = (void *)loc.oloc->file; + *args->args.get_file.file = (void *)loc.oloc->file; /* TODO we currently need to set id_exists to TRUE because * the upper layer will create an ID from the returned @@ -197,18 +195,16 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj } else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get_file parameters") + break; } /* Object name */ case H5VL_OBJECT_GET_NAME: { - ssize_t *ret = HDva_arg(arguments, ssize_t *); - char * name = HDva_arg(arguments, char *); - size_t size = HDva_arg(arguments, size_t); - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* Retrieve object's name */ - if ((*ret = H5G_get_name(&loc, name, size, NULL)) < 0) + if (H5G_get_name(&loc, args->args.get_name.buf, args->args.get_name.buf_size, + args->args.get_name.name_len, NULL) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve object name") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_TOKEN) { @@ -225,18 +221,18 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj "can't deserialize object token into address") /* Retrieve object's name */ - if ((*ret = H5G_get_name_by_addr(loc.oloc->file, &obj_oloc, name, size)) < 0) + if (H5G_get_name_by_addr(loc.oloc->file, &obj_oloc, args->args.get_name.buf, + args->args.get_name.buf_size, args->args.get_name.name_len) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine object name") } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get_name parameters") + break; } /* Object type */ case H5VL_OBJECT_GET_TYPE: { - H5O_type_t *obj_type = HDva_arg(arguments, H5O_type_t *); - if (loc_params->type == H5VL_OBJECT_BY_TOKEN) { H5O_loc_t obj_oloc; /* Object location */ unsigned rc; /* Reference count of object */ @@ -253,35 +249,30 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj /* Get the # of links for object, and its type */ /* (To check to make certain that this object hasn't been deleted) */ - if (H5O_get_rc_and_type(&obj_oloc, &rc, obj_type) < 0 || 0 == rc) + if (H5O_get_rc_and_type(&obj_oloc, &rc, args->args.get_type.obj_type) < 0 || 0 == rc) HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object") } else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get_type parameters") + break; } /* H5Oget_info(_name|_by_idx)3 */ case H5VL_OBJECT_GET_INFO: { - H5O_info2_t *oinfo = HDva_arg(arguments, H5O_info2_t *); - unsigned fields = HDva_arg(arguments, unsigned); - - /* Use the original H5Oget_info code to get the data */ - - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oget_info */ - /* Retrieve the object's information */ - if (H5G_loc_info(&loc, ".", oinfo, fields) < 0) + if (loc_params->type == H5VL_OBJECT_BY_SELF) { + if (H5G_loc_info(&loc, ".", args->args.get_info.oinfo, args->args.get_info.fields) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") - } /* end if */ - else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oget_info_by_name */ - /* Retrieve the object's information */ - if (H5G_loc_info(&loc, loc_params->loc_data.loc_by_name.name, oinfo, fields) < 0) + } /* end if */ + else if (loc_params->type == H5VL_OBJECT_BY_NAME) { + if (H5G_loc_info(&loc, loc_params->loc_data.loc_by_name.name, args->args.get_info.oinfo, + args->args.get_info.fields) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") - } /* end else-if */ - else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Oget_info_by_idx */ - H5G_loc_t obj_loc; /* Location used to open group */ - H5G_name_t obj_path; /* Opened object group hier. path */ - H5O_loc_t obj_oloc; /* Opened object object location */ + } /* end else-if */ + else if (loc_params->type == H5VL_OBJECT_BY_IDX) { + H5G_loc_t obj_loc; /* Location used to open group */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ /* Set up opened group location to fill in */ obj_loc.oloc = &obj_oloc; @@ -296,7 +287,7 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "group not found") /* Retrieve the object's information */ - if (H5O_get_info(obj_loc.oloc, oinfo, fields) < 0) { + if (H5O_get_info(obj_loc.oloc, args->args.get_info.oinfo, args->args.get_info.fields) < 0) { H5G_loc_free(&obj_loc); HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object info") } /* end if */ @@ -307,6 +298,7 @@ H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_obj } /* end else-if */ else HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, FAIL, "unknown get info parameters") + break; } @@ -329,8 +321,8 @@ done: */ herr_t H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) + H5VL_object_specific_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) { H5G_loc_t loc; herr_t ret_value = SUCCEED; /* Return value */ @@ -340,13 +332,10 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - switch (specific_type) { + switch (args->op_type) { /* H5Oincr_refcount / H5Odecr_refcount */ case H5VL_OBJECT_CHANGE_REF_COUNT: { - int update_ref = HDva_arg(arguments, int); - H5O_loc_t *oloc = loc.oloc; - - if (H5O_link(oloc, update_ref) < 0) + if (H5O_link(loc.oloc, args->args.change_rc.delta) < 0) HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "modifying object link count failed") break; @@ -354,25 +343,20 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, /* H5Oexists_by_name */ case H5VL_OBJECT_EXISTS: { - htri_t *ret = HDva_arg(arguments, htri_t *); - if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* Check if the object exists */ - if ((*ret = H5G_loc_exists(&loc, loc_params->loc_data.loc_by_name.name)) < 0) + if (H5G_loc_exists(&loc, loc_params->loc_data.loc_by_name.name, args->args.exists.exists) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine if '%s' exists", loc_params->loc_data.loc_by_name.name) } /* end if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown object exists parameters") + break; } /* Lookup object */ case H5VL_OBJECT_LOOKUP: { - H5O_token_t *token = HDva_arg(arguments, H5O_token_t *); - - HDassert(token); - if (loc_params->type == H5VL_OBJECT_BY_NAME) { H5G_loc_t obj_loc; /* Group hier. location of object */ H5G_name_t obj_path; /* Object group hier. path */ @@ -388,7 +372,8 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") /* Encode token */ - if (H5VL_native_addr_to_token(loc.oloc->file, H5I_FILE, obj_loc.oloc->addr, token) < 0) + if (H5VL_native_addr_to_token(loc.oloc->file, H5I_FILE, obj_loc.oloc->addr, + args->args.lookup.token_ptr) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token") @@ -401,46 +386,39 @@ H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, break; } + /* H5Ovisit/H5Ovisit_by_name */ case H5VL_OBJECT_VISIT: { - H5_index_t idx_type = (H5_index_t)HDva_arg(arguments, int); /* enum work-around */ - H5_iter_order_t order = (H5_iter_order_t)HDva_arg(arguments, int); /* enum work-around */ - H5O_iterate2_t op = HDva_arg(arguments, H5O_iterate2_t); - void * op_data = HDva_arg(arguments, void *); - unsigned fields = HDva_arg(arguments, unsigned); + H5VL_object_visit_args_t *visit_args = &args->args.visit; /* Call internal object visitation routine */ if (loc_params->type == H5VL_OBJECT_BY_SELF) { - /* H5Ovisit */ - if ((ret_value = H5O__visit(&loc, ".", idx_type, order, op, op_data, fields)) < 0) + if ((ret_value = H5O__visit(&loc, ".", visit_args->idx_type, visit_args->order, + visit_args->op, visit_args->op_data, visit_args->fields)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { - /* H5Ovisit_by_name */ - if ((ret_value = H5O__visit(&loc, loc_params->loc_data.loc_by_name.name, idx_type, order, op, - op_data, fields)) < 0) + if ((ret_value = H5O__visit(&loc, loc_params->loc_data.loc_by_name.name, visit_args->idx_type, + visit_args->order, visit_args->op, visit_args->op_data, + visit_args->fields)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown object visit params"); + break; } case H5VL_OBJECT_FLUSH: { - hid_t oid = HDva_arg(arguments, hid_t); - /* Flush the object's metadata */ - if (H5O_flush(loc.oloc, oid) < 0) + if (H5O_flush(loc.oloc, args->args.flush.obj_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object") break; } case H5VL_OBJECT_REFRESH: { - hid_t oid = HDva_arg(arguments, hid_t); - H5O_loc_t *oloc = loc.oloc; - /* Refresh the metadata */ - if (H5O_refresh_metadata(oid, *oloc) < 0) + if (H5O_refresh_metadata(loc.oloc, args->args.refresh.obj_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") break; @@ -464,64 +442,59 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, hid_t H5_ATTR_UNUSED dxpl_id, - void H5_ATTR_UNUSED **req, va_list arguments) +H5VL__native_object_optional(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { - H5VL_loc_params_t *loc_params = HDva_arg(arguments, H5VL_loc_params_t *); - H5G_loc_t loc; /* Location of group */ - herr_t ret_value = SUCCEED; /* Return value */ + H5G_loc_t loc; /* Location of group */ + H5VL_native_object_optional_args_t *opt_args = args->args; /* Pointer to native operation's arguments */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - switch (optional_type) { + switch (args->op_type) { /* H5Oget_comment / H5Oget_comment_by_name */ case H5VL_NATIVE_OBJECT_GET_COMMENT: { - char * comment = HDva_arg(arguments, char *); - size_t bufsize = HDva_arg(arguments, size_t); - ssize_t *ret = HDva_arg(arguments, ssize_t *); + H5VL_native_object_get_comment_t *gc_args = &opt_args->get_comment; /* Retrieve the object's comment */ if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oget_comment */ - if ((*ret = H5G_loc_get_comment(&loc, ".", comment /*out*/, bufsize)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + if (H5G_loc_get_comment(&loc, ".", gc_args->buf, gc_args->buf_size, gc_args->comment_len) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get comment for object") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oget_comment_by_name */ - if ((*ret = H5G_loc_get_comment(&loc, loc_params->loc_data.loc_by_name.name, comment /*out*/, - bufsize)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") + if (H5G_loc_get_comment(&loc, loc_params->loc_data.loc_by_name.name, gc_args->buf, + gc_args->buf_size, gc_args->comment_len) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get comment for object") } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown set_coment parameters") + break; } /* H5Oset_comment */ case H5VL_NATIVE_OBJECT_SET_COMMENT: { - const char *comment = HDva_arg(arguments, char *); - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oset_comment */ - /* (Re)set the object's comment */ - if (H5G_loc_set_comment(&loc, ".", comment) < 0) + if (H5G_loc_set_comment(&loc, ".", opt_args->set_comment.comment) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oset_comment_by_name */ - /* (Re)set the object's comment */ - if (H5G_loc_set_comment(&loc, loc_params->loc_data.loc_by_name.name, comment) < 0) + if (H5G_loc_set_comment(&loc, loc_params->loc_data.loc_by_name.name, + opt_args->set_comment.comment) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") } /* end else-if */ else HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown set_coment parameters") + break; } /* H5Odisable_mdc_flushes */ case H5VL_NATIVE_OBJECT_DISABLE_MDC_FLUSHES: { - H5O_loc_t *oloc = loc.oloc; - - if (H5O_disable_mdc_flushes(oloc) < 0) + if (H5O__disable_mdc_flushes(loc.oloc) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCORK, FAIL, "unable to cork the metadata cache"); break; @@ -529,9 +502,7 @@ H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, hi /* H5Oenable_mdc_flushes */ case H5VL_NATIVE_OBJECT_ENABLE_MDC_FLUSHES: { - H5O_loc_t *oloc = loc.oloc; - - if (H5O_enable_mdc_flushes(oloc) < 0) + if (H5O__enable_mdc_flushes(loc.oloc) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTUNCORK, FAIL, "unable to uncork the metadata cache"); break; @@ -539,10 +510,7 @@ H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, hi /* H5Oare_mdc_flushes_disabled */ case H5VL_NATIVE_OBJECT_ARE_MDC_FLUSHES_DISABLED: { - H5O_loc_t *oloc = loc.oloc; - hbool_t * are_disabled = (hbool_t *)HDva_arg(arguments, hbool_t *); - - if (H5O_are_mdc_flushes_disabled(oloc, are_disabled) < 0) + if (H5O__are_mdc_flushes_disabled(loc.oloc, opt_args->are_mdc_flushes_disabled.flag) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine metadata cache cork status"); break; @@ -550,19 +518,16 @@ H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, hi /* H5Oget_native_info(_name|_by_idx) */ case H5VL_NATIVE_OBJECT_GET_NATIVE_INFO: { - H5O_native_info_t *native_info = HDva_arg(arguments, H5O_native_info_t *); - unsigned fields = HDva_arg(arguments, unsigned); + H5VL_native_object_get_native_info_t *gni_args = &opt_args->get_native_info; /* Use the original H5Oget_info code to get the data */ - - if (loc_params->type == H5VL_OBJECT_BY_SELF) { /* H5Oget_info */ - /* Retrieve the object's information */ - if (H5G_loc_native_info(&loc, ".", native_info, fields) < 0) + if (loc_params->type == H5VL_OBJECT_BY_SELF) { + if (H5G_loc_native_info(&loc, ".", gni_args->ninfo, gni_args->fields) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Oget_info_by_name */ - /* Retrieve the object's information */ - if (H5G_loc_native_info(&loc, loc_params->loc_data.loc_by_name.name, native_info, fields) < 0) + if (H5G_loc_native_info(&loc, loc_params->loc_data.loc_by_name.name, gni_args->ninfo, + gni_args->fields) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") } /* end else-if */ else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Oget_info_by_idx */ @@ -582,8 +547,7 @@ H5VL__native_object_optional(void *obj, H5VL_object_optional_t optional_type, hi loc_params->loc_data.loc_by_idx.n, &obj_loc /*out*/) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "group not found") - /* Retrieve the object's information */ - if (H5O_get_native_info(obj_loc.oloc, native_info, fields) < 0) { + if (H5O_get_native_info(obj_loc.oloc, gni_args->ninfo, gni_args->fields) < 0) { H5G_loc_free(&obj_loc); HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't retrieve object info") } /* end if */ diff --git a/src/H5VLnative_private.h b/src/H5VLnative_private.h index 687221a..1fd90c8 100644 --- a/src/H5VLnative_private.h +++ b/src/H5VLnative_private.h @@ -49,13 +49,10 @@ void * H5VL__native_attr_open(void *obj, const H5VL_loc_params_t *loc_par hid_t aapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_attr_write(void *attr, hid_t dtype_id, const void *buf, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL__native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); +H5_DLL herr_t H5VL__native_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_attr_optional(void *obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_attr_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_attr_close(void *attr, hid_t dxpl_id, void **req); /* Dataset callbacks */ @@ -68,12 +65,11 @@ H5_DLL herr_t H5VL__native_dataset_read(void *dset, hid_t mem_type_id, hid_t mem hid_t file_space_id, hid_t plist_id, void *buf, void **req); H5_DLL herr_t H5VL__native_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf, void **req); -H5_DLL herr_t H5VL__native_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_dataset_specific(void *dset, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VL__native_dataset_optional(void *dset, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +H5_DLL herr_t H5VL__native_dataset_get(void *dset, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_dataset_specific(void *dset, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL__native_dataset_optional(void *dset, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL__native_dataset_close(void *dset, hid_t dxpl_id, void **req); /* Datatype callbacks */ @@ -82,10 +78,9 @@ H5_DLL void * H5VL__native_datatype_commit(void *obj, const H5VL_loc_params_t *l hid_t dxpl_id, void **req); H5_DLL void * H5VL__native_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL__native_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_datatype_specific(void *dt, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); +H5_DLL herr_t H5VL__native_datatype_get(void *dt, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_datatype_specific(void *dt, H5VL_datatype_specific_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL__native_datatype_close(void *dt, hid_t dxpl_id, void **req); /* File callbacks */ @@ -93,12 +88,10 @@ H5_DLL void * H5VL__native_file_create(const char *name, unsigned flags, hid_t f hid_t dxpl_id, void **req); H5_DLL void * H5VL__native_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL__native_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_file_specific(void *file, H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VL__native_file_optional(void *file, H5VL_file_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments); +H5_DLL herr_t H5VL__native_file_get(void *file, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_file_specific(void *file, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL__native_file_optional(void *file, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_file_close(void *file, hid_t dxpl_id, void **req); /* Group callbacks */ @@ -107,29 +100,26 @@ H5_DLL void * H5VL__native_group_create(void *obj, const H5VL_loc_params_t *loc_ void **req); H5_DLL void * H5VL__native_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL__native_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -H5_DLL herr_t H5VL__native_group_optional(void *obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +H5_DLL herr_t H5VL__native_group_get(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_group_specific(void *obj, H5VL_group_specific_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL__native_group_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_group_close(void *grp, hid_t dxpl_id, void **req); /* Link callbacks */ -H5_DLL herr_t H5VL__native_link_create(H5VL_link_create_type_t create_type, void *obj, +H5_DLL herr_t H5VL__native_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, - hid_t dxpl_id, void **req, va_list arguments); + hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments); +H5_DLL herr_t H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req); /* Object callbacks */ H5_DLL void *H5VL__native_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_type_t *opened_type, @@ -139,25 +129,23 @@ H5_DLL herr_t H5VL__native_object_copy(void *src_obj, const H5VL_loc_params_t *l const H5VL_loc_params_t *loc_params2, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_object_get(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL__native_object_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -H5_DLL herr_t H5VL__native_object_optional(void *obj, H5VL_object_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL__native_object_optional(void *obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Connector/container introspection functions */ H5_DLL herr_t H5VL__native_introspect_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); +H5_DLL herr_t H5VL__native_introspect_get_cap_flags(const void *info, unsigned *cap_flags); H5_DLL herr_t H5VL__native_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_type, uint64_t *flags); /* Blob callbacks */ H5_DLL herr_t H5VL__native_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); H5_DLL herr_t H5VL__native_blob_get(void *obj, const void *blob_id, void *buf, size_t size, void *ctx); -H5_DLL herr_t H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, - va_list arguments); +H5_DLL herr_t H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_args_t *args); /* Token callbacks */ H5_DLL herr_t H5VL__native_token_cmp(void *obj, const H5O_token_t *token1, const H5O_token_t *token2, diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c index 5ccc082..681531e 100644 --- a/src/H5VLpassthru.c +++ b/src/H5VLpassthru.c @@ -77,15 +77,6 @@ typedef struct H5VL_pass_through_wrap_ctx_t { /********************* */ /* Helper routines */ -static herr_t H5VL_pass_through_file_specific_reissue(void *obj, hid_t connector_id, - H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req, ...); -static herr_t H5VL_pass_through_request_specific_reissue(void *obj, hid_t connector_id, - H5VL_request_specific_t specific_type, ...); -static herr_t H5VL_pass_through_link_create_reissue(H5VL_link_create_type_t create_type, void *obj, - const H5VL_loc_params_t *loc_params, hid_t connector_id, - hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req, - ...); static H5VL_pass_through_t *H5VL_pass_through_new_obj(void *under_obj, hid_t under_vol_id); static herr_t H5VL_pass_through_free_obj(H5VL_pass_through_t *obj); @@ -117,13 +108,11 @@ static herr_t H5VL_pass_through_attr_read(void *attr, hid_t mem_type_id, void *b void **req); static herr_t H5VL_pass_through_attr_write(void *attr, hid_t mem_type_id, const void *buf, hid_t dxpl_id, void **req); -static herr_t H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); +static herr_t H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL_pass_through_attr_optional(void *obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_attr_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL_pass_through_attr_close(void *attr, hid_t dxpl_id, void **req); /* Dataset callbacks */ @@ -137,12 +126,12 @@ static herr_t H5VL_pass_through_dataset_read(void *dset, hid_t mem_type_id, hid_ static herr_t H5VL_pass_through_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf, void **req); -static herr_t H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL_pass_through_dataset_optional(void *obj, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +static herr_t H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL_pass_through_dataset_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL_pass_through_dataset_close(void *dset, hid_t dxpl_id, void **req); /* Datatype callbacks */ @@ -151,12 +140,12 @@ static void *H5VL_pass_through_datatype_commit(void *obj, const H5VL_loc_params_ hid_t tapl_id, hid_t dxpl_id, void **req); static void *H5VL_pass_through_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); -static herr_t H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific_type, - hid_t dxpl_id, void **req, va_list arguments); -static herr_t H5VL_pass_through_datatype_optional(void *obj, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +static herr_t H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_args_t *args, + hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_datatype_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL_pass_through_datatype_close(void *dt, hid_t dxpl_id, void **req); /* File callbacks */ @@ -164,12 +153,11 @@ static void * H5VL_pass_through_file_create(const char *name, unsigned flags, hi hid_t dxpl_id, void **req); static void * H5VL_pass_through_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); -static herr_t H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL_pass_through_file_optional(void *file, H5VL_file_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +static herr_t H5VL_pass_through_file_get(void *file, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_file_specific(void *file, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL_pass_through_file_optional(void *file, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL_pass_through_file_close(void *file, hid_t dxpl_id, void **req); /* Group callbacks */ @@ -178,18 +166,17 @@ static void * H5VL_pass_through_group_create(void *obj, const H5VL_loc_params_t void **req); static void * H5VL_pass_through_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); -static herr_t H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL_pass_through_group_optional(void *obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); +static herr_t H5VL_pass_through_group_get(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_args_t *args, hid_t dxpl_id, + void **req); +static herr_t H5VL_pass_through_group_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); static herr_t H5VL_pass_through_group_close(void *grp, hid_t dxpl_id, void **req); /* Link callbacks */ -static herr_t H5VL_pass_through_link_create(H5VL_link_create_type_t create_type, void *obj, +static herr_t H5VL_pass_through_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, - hid_t dxpl_id, void **req, va_list arguments); + hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); @@ -197,13 +184,11 @@ static herr_t H5VL_pass_through_link_move(void *src_obj, const H5VL_loc_params_t const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_link_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments); -static herr_t H5VL_pass_through_link_optional(void *obj, H5VL_link_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_link_optional(void *obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Object callbacks */ static void * H5VL_pass_through_object_open(void *obj, const H5VL_loc_params_t *loc_params, @@ -213,17 +198,16 @@ static herr_t H5VL_pass_through_object_copy(void *src_obj, const H5VL_loc_params const H5VL_loc_params_t *dst_loc_params, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments); + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req); static herr_t H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments); -static herr_t H5VL_pass_through_object_optional(void *obj, H5VL_object_optional_t opt_type, hid_t dxpl_id, - void **req, va_list arguments); + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req); +static herr_t H5VL_pass_through_object_optional(void *obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Container/connector introspection callbacks */ static herr_t H5VL_pass_through_introspect_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); +static herr_t H5VL_pass_through_introspect_get_cap_flags(const void *info, unsigned *cap_flags); static herr_t H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_type, uint64_t *flags); @@ -231,19 +215,15 @@ static herr_t H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t static herr_t H5VL_pass_through_request_wait(void *req, uint64_t timeout, H5VL_request_status_t *status); static herr_t H5VL_pass_through_request_notify(void *obj, H5VL_request_notify_t cb, void *ctx); static herr_t H5VL_pass_through_request_cancel(void *req, H5VL_request_status_t *status); -static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specific_t specific_type, - va_list arguments); -static herr_t H5VL_pass_through_request_optional(void *req, H5VL_request_optional_t opt_type, - va_list arguments); +static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specific_args_t *args); +static herr_t H5VL_pass_through_request_optional(void *req, H5VL_optional_args_t *args); static herr_t H5VL_pass_through_request_free(void *req); /* Blob callbacks */ static herr_t H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); static herr_t H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, size_t size, void *ctx); -static herr_t H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, - va_list arguments); -static herr_t H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_blob_optional_t opt_type, - va_list arguments); +static herr_t H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_args_t *args); +static herr_t H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_optional_args_t *args); /* Token callbacks */ static herr_t H5VL_pass_through_token_cmp(void *obj, const H5O_token_t *token1, const H5O_token_t *token2, @@ -254,8 +234,7 @@ static herr_t H5VL_pass_through_token_from_str(void *obj, H5I_type_t obj_type, c H5O_token_t *token); /* Generic optional callback */ -static herr_t H5VL_pass_through_optional(void *obj, int op_type, hid_t dxpl_id, void **req, - va_list arguments); +static herr_t H5VL_pass_through_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /*******************/ /* Local variables */ @@ -355,8 +334,9 @@ static const H5VL_class_t H5VL_pass_through_g = { }, { /* introspect_cls */ - H5VL_pass_through_introspect_get_conn_cls, /* get_conn_cls */ - H5VL_pass_through_introspect_opt_query, /* opt_query */ + H5VL_pass_through_introspect_get_conn_cls, /* get_conn_cls */ + H5VL_pass_through_introspect_get_cap_flags, /* get_cap_flags */ + H5VL_pass_through_introspect_opt_query, /* opt_query */ }, { /* request_cls */ @@ -1025,7 +1005,7 @@ H5VL_pass_through_attr_write(void *attr, hid_t mem_type_id, const void *buf, hid *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -1034,7 +1014,7 @@ H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, v printf("------- PASS THROUGH VOL ATTRIBUTE Get\n"); #endif - ret_value = H5VLattr_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLattr_get(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1055,8 +1035,7 @@ H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, v */ static herr_t H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments) + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -1065,8 +1044,7 @@ H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, printf("------- PASS THROUGH VOL ATTRIBUTE Specific\n"); #endif - ret_value = H5VLattr_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req, - arguments); + ret_value = H5VLattr_specific(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1086,8 +1064,7 @@ H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_attr_optional(void *obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_attr_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -1096,7 +1073,7 @@ H5VL_pass_through_attr_optional(void *obj, H5VL_attr_optional_t opt_type, hid_t printf("------- PASS THROUGH VOL ATTRIBUTE Optional\n"); #endif - ret_value = H5VLattr_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLattr_optional(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1285,8 +1262,7 @@ H5VL_pass_through_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_i *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset; herr_t ret_value; @@ -1295,7 +1271,7 @@ H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxp printf("------- PASS THROUGH VOL DATASET Get\n"); #endif - ret_value = H5VLdataset_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLdataset_get(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1315,8 +1291,7 @@ H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxp *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; hid_t under_vol_id; @@ -1326,12 +1301,12 @@ H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_t printf("------- PASS THROUGH VOL H5Dspecific\n"); #endif - // Save copy of underlying VOL connector ID and prov helper, in case of - // refresh destroying the current object + /* Save copy of underlying VOL connector ID, in case of + * 'refresh' operation destroying the current object + */ under_vol_id = o->under_vol_id; - ret_value = - H5VLdataset_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments); + ret_value = H5VLdataset_specific(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1351,8 +1326,7 @@ H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_t *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_dataset_optional(void *obj, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_dataset_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -1361,7 +1335,7 @@ H5VL_pass_through_dataset_optional(void *obj, H5VL_dataset_optional_t opt_type, printf("------- PASS THROUGH VOL DATASET Optional\n"); #endif - ret_value = H5VLdataset_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLdataset_optional(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1488,8 +1462,7 @@ H5VL_pass_through_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)dt; herr_t ret_value; @@ -1498,7 +1471,7 @@ H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxp printf("------- PASS THROUGH VOL DATATYPE Get\n"); #endif - ret_value = H5VLdatatype_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLdatatype_get(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1518,8 +1491,7 @@ H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxp *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, - void **req, va_list arguments) +H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; hid_t under_vol_id; @@ -1529,12 +1501,12 @@ H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific printf("------- PASS THROUGH VOL DATATYPE Specific\n"); #endif - // Save copy of underlying VOL connector ID and prov helper, in case of - // refresh destroying the current object + /* Save copy of underlying VOL connector ID, in case of + * 'refresh' operation destroying the current object + */ under_vol_id = o->under_vol_id; - ret_value = - H5VLdatatype_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments); + ret_value = H5VLdatatype_specific(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1554,8 +1526,7 @@ H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_datatype_optional(void *obj, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_datatype_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -1564,7 +1535,7 @@ H5VL_pass_through_datatype_optional(void *obj, H5VL_datatype_optional_t opt_type printf("------- PASS THROUGH VOL DATATYPE Optional\n"); #endif - ret_value = H5VLdatatype_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLdatatype_optional(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1732,7 +1703,7 @@ H5VL_pass_through_file_open(const char *name, unsigned flags, hid_t fapl_id, hid *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_file_get(void *file, H5VL_file_get_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)file; herr_t ret_value; @@ -1741,7 +1712,7 @@ H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, printf("------- PASS THROUGH VOL FILE Get\n"); #endif - ret_value = H5VLfile_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLfile_get(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -1751,31 +1722,6 @@ H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, } /* end H5VL_pass_through_file_get() */ /*------------------------------------------------------------------------- - * Function: H5VL_pass_through_file_specific_reissue - * - * Purpose: Re-wrap vararg arguments into a va_list and reissue the - * file specific callback to the underlying VOL connector. - * - * Return: Success: 0 - * Failure: -1 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5VL_pass_through_file_specific_reissue(void *obj, hid_t connector_id, H5VL_file_specific_t specific_type, - hid_t dxpl_id, void **req, ...) -{ - va_list arguments; - herr_t ret_value; - - va_start(arguments, req); - ret_value = H5VLfile_specific(obj, connector_id, specific_type, dxpl_id, req, arguments); - va_end(arguments); - - return ret_value; -} /* end H5VL_pass_through_file_specific_reissue() */ - -/*------------------------------------------------------------------------- * Function: H5VL_pass_through_file_specific * * Purpose: Specific operation on file @@ -1786,106 +1732,109 @@ H5VL_pass_through_file_specific_reissue(void *obj, hid_t connector_id, H5VL_file *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_file_specific(void *file, H5VL_file_specific_args_t *args, hid_t dxpl_id, void **req) { - H5VL_pass_through_t *o = (H5VL_pass_through_t *)file; - hid_t under_vol_id = -1; - herr_t ret_value; + H5VL_pass_through_t * o = (H5VL_pass_through_t *)file; + H5VL_pass_through_t * new_o; + H5VL_file_specific_args_t my_args; + H5VL_file_specific_args_t *new_args; + H5VL_pass_through_info_t * info; + hid_t under_vol_id = -1; + herr_t ret_value; #ifdef ENABLE_PASSTHRU_LOGGING printf("------- PASS THROUGH VOL FILE Specific\n"); #endif - /* Unpack arguments to get at the child file pointer when mounting a file */ - if (specific_type == H5VL_FILE_MOUNT) { - H5I_type_t loc_type; - const char * name; - H5VL_pass_through_t *child_file; - hid_t plist_id; - - /* Retrieve parameters for 'mount' operation, so we can unwrap the child file */ - loc_type = (H5I_type_t)va_arg(arguments, int); /* enum work-around */ - name = va_arg(arguments, const char *); - child_file = (H5VL_pass_through_t *)va_arg(arguments, void *); - plist_id = va_arg(arguments, hid_t); - - /* Keep the correct underlying VOL ID for possible async request token */ - under_vol_id = o->under_vol_id; - - /* Re-issue 'file specific' call, using the unwrapped pieces */ - ret_value = H5VL_pass_through_file_specific_reissue(o->under_object, o->under_vol_id, specific_type, - dxpl_id, req, (int)loc_type, name, - child_file->under_object, plist_id); - } /* end if */ - else if (specific_type == H5VL_FILE_IS_ACCESSIBLE || specific_type == H5VL_FILE_DELETE) { - H5VL_pass_through_info_t *info; - hid_t fapl_id, under_fapl_id; - const char * name; - htri_t * ret; - - /* Get the arguments for the 'is accessible' check */ - fapl_id = va_arg(arguments, hid_t); - name = va_arg(arguments, const char *); - ret = va_arg(arguments, htri_t *); + if (args->op_type == H5VL_FILE_IS_ACCESSIBLE) { + /* Shallow copy the args */ + memcpy(&my_args, args, sizeof(my_args)); /* Get copy of our VOL info from FAPL */ - H5Pget_vol_info(fapl_id, (void **)&info); + H5Pget_vol_info(args->args.is_accessible.fapl_id, (void **)&info); /* Make sure we have info about the underlying VOL to be used */ if (!info) return (-1); + /* Keep the correct underlying VOL ID for later */ + under_vol_id = info->under_vol_id; + /* Copy the FAPL */ - under_fapl_id = H5Pcopy(fapl_id); + my_args.args.is_accessible.fapl_id = H5Pcopy(args->args.is_accessible.fapl_id); /* Set the VOL ID and info for the underlying FAPL */ - H5Pset_vol(under_fapl_id, info->under_vol_id, info->under_vol_info); + H5Pset_vol(my_args.args.is_accessible.fapl_id, info->under_vol_id, info->under_vol_info); - /* Keep the correct underlying VOL ID for possible async request token */ + /* Set argument pointer to new arguments */ + new_args = &my_args; + + /* Set object pointer for operation */ + new_o = NULL; + } /* end else-if */ + else if (args->op_type == H5VL_FILE_DELETE) { + /* Shallow copy the args */ + memcpy(&my_args, args, sizeof(my_args)); + + /* Get copy of our VOL info from FAPL */ + H5Pget_vol_info(args->args.del.fapl_id, (void **)&info); + + /* Make sure we have info about the underlying VOL to be used */ + if (!info) + return (-1); + + /* Keep the correct underlying VOL ID for later */ under_vol_id = info->under_vol_id; - /* Re-issue 'file specific' call */ - ret_value = H5VL_pass_through_file_specific_reissue(NULL, info->under_vol_id, specific_type, dxpl_id, - req, under_fapl_id, name, ret); + /* Copy the FAPL */ + my_args.args.del.fapl_id = H5Pcopy(args->args.del.fapl_id); - /* Close underlying FAPL */ - H5Pclose(under_fapl_id); + /* Set the VOL ID and info for the underlying FAPL */ + H5Pset_vol(my_args.args.del.fapl_id, info->under_vol_id, info->under_vol_info); - /* Release copy of our VOL info */ - H5VL_pass_through_info_free(info); + /* Set argument pointer to new arguments */ + new_args = &my_args; + + /* Set object pointer for operation */ + new_o = NULL; } /* end else-if */ else { - va_list my_arguments; - - /* Make a copy of the argument list for later, if reopening */ - if (specific_type == H5VL_FILE_REOPEN) - va_copy(my_arguments, arguments); - - /* Keep the correct underlying VOL ID for possible async request token */ + /* Keep the correct underlying VOL ID for later */ under_vol_id = o->under_vol_id; - ret_value = - H5VLfile_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments); - - /* Wrap file struct pointer, if we reopened one */ - if (specific_type == H5VL_FILE_REOPEN) { - if (ret_value >= 0) { - void **ret = va_arg(my_arguments, void **); + /* Set argument pointer to current arguments */ + new_args = args; - if (ret && *ret) - *ret = H5VL_pass_through_new_obj(*ret, o->under_vol_id); - } /* end if */ + /* Set object pointer for operation */ + new_o = o->under_object; + } /* end else */ - /* Finish use of copied vararg list */ - va_end(my_arguments); - } /* end if */ - } /* end else */ + ret_value = H5VLfile_specific(new_o, under_vol_id, new_args, dxpl_id, req); /* Check for async request */ if (req && *req) *req = H5VL_pass_through_new_obj(*req, under_vol_id); + if (args->op_type == H5VL_FILE_IS_ACCESSIBLE) { + /* Close underlying FAPL */ + H5Pclose(my_args.args.is_accessible.fapl_id); + + /* Release copy of our VOL info */ + H5VL_pass_through_info_free(info); + } /* end else-if */ + else if (args->op_type == H5VL_FILE_DELETE) { + /* Close underlying FAPL */ + H5Pclose(my_args.args.del.fapl_id); + + /* Release copy of our VOL info */ + H5VL_pass_through_info_free(info); + } /* end else-if */ + else if (args->op_type == H5VL_FILE_REOPEN) { + /* Wrap file struct pointer for 'reopen' operation, if we reopened one */ + if (ret_value >= 0 && *args->args.reopen.file) + *args->args.reopen.file = H5VL_pass_through_new_obj(*args->args.reopen.file, under_vol_id); + } /* end else */ + return ret_value; } /* end H5VL_pass_through_file_specific() */ @@ -1900,8 +1849,7 @@ H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_file_optional(void *file, H5VL_file_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_file_optional(void *file, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)file; herr_t ret_value; @@ -1910,7 +1858,7 @@ H5VL_pass_through_file_optional(void *file, H5VL_file_optional_t opt_type, hid_t printf("------- PASS THROUGH VOL File Optional\n"); #endif - ret_value = H5VLfile_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLfile_optional(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2036,8 +1984,7 @@ H5VL_pass_through_group_open(void *obj, const H5VL_loc_params_t *loc_params, con *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_group_get(void *obj, H5VL_group_get_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2046,7 +1993,7 @@ H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, printf("------- PASS THROUGH VOL GROUP Get\n"); #endif - ret_value = H5VLgroup_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLgroup_get(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2066,8 +2013,7 @@ H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; hid_t under_vol_id; @@ -2077,11 +2023,27 @@ H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type, printf("------- PASS THROUGH VOL GROUP Specific\n"); #endif - // Save copy of underlying VOL connector ID and prov helper, in case of - // refresh destroying the current object + /* Save copy of underlying VOL connector ID, in case of + * 'refresh' operation destroying the current object + */ under_vol_id = o->under_vol_id; - ret_value = H5VLgroup_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments); + /* Unpack arguments to get at the child file pointer when mounting a file */ + if (args->op_type == H5VL_GROUP_MOUNT) { + H5VL_group_specific_args_t vol_cb_args; /* New group specific arg struct */ + + /* Set up new VOL callback arguments */ + vol_cb_args.op_type = H5VL_GROUP_MOUNT; + vol_cb_args.args.mount.name = args->args.mount.name; + vol_cb_args.args.mount.child_file = + ((H5VL_pass_through_t *)args->args.mount.child_file)->under_object; + vol_cb_args.args.mount.fmpl_id = args->args.mount.fmpl_id; + + /* Re-issue 'group specific' call, using the unwrapped pieces */ + ret_value = H5VLgroup_specific(o->under_object, under_vol_id, &vol_cb_args, dxpl_id, req); + } /* end if */ + else + ret_value = H5VLgroup_specific(o->under_object, under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2101,8 +2063,7 @@ H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_group_optional(void *obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_group_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2111,7 +2072,7 @@ H5VL_pass_through_group_optional(void *obj, H5VL_group_optional_t opt_type, hid_ printf("------- PASS THROUGH VOL GROUP Optional\n"); #endif - ret_value = H5VLgroup_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLgroup_optional(o->under_object, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2154,33 +2115,6 @@ H5VL_pass_through_group_close(void *grp, hid_t dxpl_id, void **req) } /* end H5VL_pass_through_group_close() */ /*------------------------------------------------------------------------- - * Function: H5VL_pass_through_link_create_reissue - * - * Purpose: Re-wrap vararg arguments into a va_list and reissue the - * link create callback to the underlying VOL connector. - * - * Return: Success: 0 - * Failure: -1 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5VL_pass_through_link_create_reissue(H5VL_link_create_type_t create_type, void *obj, - const H5VL_loc_params_t *loc_params, hid_t connector_id, hid_t lcpl_id, - hid_t lapl_id, hid_t dxpl_id, void **req, ...) -{ - va_list arguments; - herr_t ret_value; - - va_start(arguments, req); - ret_value = H5VLlink_create(create_type, obj, loc_params, connector_id, lcpl_id, lapl_id, dxpl_id, req, - arguments); - va_end(arguments); - - return ret_value; -} /* end H5VL_pass_through_link_create_reissue() */ - -/*------------------------------------------------------------------------- * Function: H5VL_pass_through_link_create * * Purpose: Creates a hard / soft / UD / external link. @@ -2191,9 +2125,8 @@ H5VL_pass_through_link_create_reissue(H5VL_link_create_type_t create_type, void *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_link_create(H5VL_link_create_type_t create_type, void *obj, - const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, - hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, + hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; hid_t under_vol_id = -1; @@ -2208,32 +2141,22 @@ H5VL_pass_through_link_create(H5VL_link_create_type_t create_type, void *obj, under_vol_id = o->under_vol_id; /* Fix up the link target object for hard link creation */ - if (H5VL_LINK_CREATE_HARD == create_type) { - void * cur_obj; - H5VL_loc_params_t *cur_params; + if (H5VL_LINK_CREATE_HARD == args->op_type) { + void *cur_obj = args->args.hard.curr_obj; - /* Retrieve the object & loc params for the link target */ - cur_obj = va_arg(arguments, void *); - cur_params = va_arg(arguments, H5VL_loc_params_t *); - - /* If it's a non-NULL pointer, find the 'under object' and re-set the property */ + /* If cur_obj is a non-NULL pointer, find its 'under object' and update the pointer */ if (cur_obj) { - /* Check if we still need the "under" VOL ID */ + /* Check if we still haven't set the "under" VOL ID */ if (under_vol_id < 0) under_vol_id = ((H5VL_pass_through_t *)cur_obj)->under_vol_id; - /* Set the object for the link target */ - cur_obj = ((H5VL_pass_through_t *)cur_obj)->under_object; + /* Update the object for the link target */ + args->args.hard.curr_obj = ((H5VL_pass_through_t *)cur_obj)->under_object; } /* end if */ + } /* end if */ - /* Re-issue 'link create' call, using the unwrapped pieces */ - ret_value = H5VL_pass_through_link_create_reissue(create_type, (o ? o->under_object : NULL), - loc_params, under_vol_id, lcpl_id, lapl_id, dxpl_id, - req, cur_obj, cur_params); - } /* end if */ - else - ret_value = H5VLlink_create(create_type, (o ? o->under_object : NULL), loc_params, under_vol_id, - lcpl_id, lapl_id, dxpl_id, req, arguments); + ret_value = H5VLlink_create(args, (o ? o->under_object : NULL), loc_params, under_vol_id, lcpl_id, + lapl_id, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2347,8 +2270,8 @@ H5VL_pass_through_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t *args, + hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2357,7 +2280,7 @@ H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ printf("------- PASS THROUGH VOL LINK Get\n"); #endif - ret_value = H5VLlink_get(o->under_object, loc_params, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLlink_get(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2378,8 +2301,7 @@ H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_ */ static herr_t H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments) + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2388,8 +2310,7 @@ H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params, printf("------- PASS THROUGH VOL LINK Specific\n"); #endif - ret_value = H5VLlink_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req, - arguments); + ret_value = H5VLlink_specific(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2409,8 +2330,8 @@ H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_link_optional(void *obj, H5VL_link_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_link_optional(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2419,7 +2340,7 @@ H5VL_pass_through_link_optional(void *obj, H5VL_link_optional_t opt_type, hid_t printf("------- PASS THROUGH VOL LINK Optional\n"); #endif - ret_value = H5VLlink_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLlink_optional(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2509,8 +2430,8 @@ H5VL_pass_through_object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_pa *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, - hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_args_t *args, + hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2519,8 +2440,7 @@ H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5V printf("------- PASS THROUGH VOL OBJECT Get\n"); #endif - ret_value = - H5VLobject_get(o->under_object, loc_params, o->under_vol_id, get_type, dxpl_id, req, arguments); + ret_value = H5VLobject_get(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2541,8 +2461,7 @@ H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5V */ static herr_t H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, - va_list arguments) + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; hid_t under_vol_id; @@ -2552,12 +2471,12 @@ H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params printf("------- PASS THROUGH VOL OBJECT Specific\n"); #endif - // Save copy of underlying VOL connector ID and prov helper, in case of - // refresh destroying the current object + /* Save copy of underlying VOL connector ID, in case of + * 'refresh' operation destroying the current object + */ under_vol_id = o->under_vol_id; - ret_value = H5VLobject_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req, - arguments); + ret_value = H5VLobject_specific(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2577,8 +2496,8 @@ H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_object_optional(void *obj, H5VL_object_optional_t opt_type, hid_t dxpl_id, void **req, - va_list arguments) +H5VL_pass_through_object_optional(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2587,7 +2506,7 @@ H5VL_pass_through_object_optional(void *obj, H5VL_object_optional_t opt_type, hi printf("------- PASS THROUGH VOL OBJECT Optional\n"); #endif - ret_value = H5VLobject_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments); + ret_value = H5VLobject_optional(o->under_object, loc_params, o->under_vol_id, args, dxpl_id, req); /* Check for async request */ if (req && *req) @@ -2597,7 +2516,7 @@ H5VL_pass_through_object_optional(void *obj, H5VL_object_optional_t opt_type, hi } /* end H5VL_pass_through_object_optional() */ /*------------------------------------------------------------------------- - * Function: H5VL_pass_through_introspect_get_conn_clss + * Function: H5VL_pass_through_introspect_get_conn_cls * * Purpose: Query the connector class. * @@ -2627,6 +2546,36 @@ H5VL_pass_through_introspect_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl, co } /* end H5VL_pass_through_introspect_get_conn_cls() */ /*------------------------------------------------------------------------- + * Function: H5VL_pass_through_introspect_get_cap_flags + * + * Purpose: Query the capability flags for this connector and any + * underlying connector(s). + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_pass_through_introspect_get_cap_flags(const void *_info, unsigned *cap_flags) +{ + const H5VL_pass_through_info_t *info = (const H5VL_pass_through_info_t *)_info; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL INTROSPECT GetCapFlags\n"); +#endif + + /* Invoke the query on the underlying VOL connector */ + ret_value = H5VLintrospect_get_cap_flags(info->under_vol_info, info->under_vol_id, cap_flags); + + /* Bitwise OR our capability flags in */ + if (ret_value >= 0) + *cap_flags |= H5VL_pass_through_g.cap_flags; + + return ret_value; +} /* end H5VL_pass_through_introspect_get_cap_flags() */ + +/*------------------------------------------------------------------------- * Function: H5VL_pass_through_introspect_opt_query * * Purpose: Query if an optional operation is supported by this connector @@ -2743,31 +2692,6 @@ H5VL_pass_through_request_cancel(void *obj, H5VL_request_status_t *status) } /* end H5VL_pass_through_request_cancel() */ /*------------------------------------------------------------------------- - * Function: H5VL_pass_through_request_specific_reissue - * - * Purpose: Re-wrap vararg arguments into a va_list and reissue the - * request specific callback to the underlying VOL connector. - * - * Return: Success: 0 - * Failure: -1 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5VL_pass_through_request_specific_reissue(void *obj, hid_t connector_id, - H5VL_request_specific_t specific_type, ...) -{ - va_list arguments; - herr_t ret_value; - - va_start(arguments, specific_type); - ret_value = H5VLrequest_specific(obj, connector_id, specific_type, arguments); - va_end(arguments); - - return ret_value; -} /* end H5VL_pass_through_request_specific_reissue() */ - -/*------------------------------------------------------------------------- * Function: H5VL_pass_through_request_specific * * Purpose: Specific operation on a request @@ -2778,139 +2702,16 @@ H5VL_pass_through_request_specific_reissue(void *obj, hid_t connector_id, *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_type, va_list arguments) +H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_args_t *args) { - herr_t ret_value = -1; + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value = -1; #ifdef ENABLE_PASSTHRU_LOGGING printf("------- PASS THROUGH VOL REQUEST Specific\n"); #endif - if (H5VL_REQUEST_WAITANY == specific_type || H5VL_REQUEST_WAITSOME == specific_type || - H5VL_REQUEST_WAITALL == specific_type) { - va_list tmp_arguments; - size_t req_count; - - /* Sanity check */ - assert(obj == NULL); - - /* Get enough info to call the underlying connector */ - va_copy(tmp_arguments, arguments); - req_count = va_arg(tmp_arguments, size_t); - - /* Can only use a request to invoke the underlying VOL connector when there's >0 requests */ - if (req_count > 0) { - void ** req_array; - void ** under_req_array; - uint64_t timeout; - H5VL_pass_through_t *o; - size_t u; /* Local index variable */ - - /* Get the request array */ - req_array = va_arg(tmp_arguments, void **); - - /* Get a request to use for determining the underlying VOL connector */ - o = (H5VL_pass_through_t *)req_array[0]; - - /* Create array of underlying VOL requests */ - under_req_array = (void **)malloc(req_count * sizeof(void **)); - for (u = 0; u < req_count; u++) - under_req_array[u] = ((H5VL_pass_through_t *)req_array[u])->under_object; - - /* Remove the timeout value from the vararg list (it's used in all the calls below) */ - timeout = va_arg(tmp_arguments, uint64_t); - - /* Release requests that have completed */ - if (H5VL_REQUEST_WAITANY == specific_type) { - size_t * idx; /* Pointer to the index of completed request */ - H5VL_request_status_t *status; /* Pointer to the request's status */ - - /* Retrieve the remaining arguments */ - idx = va_arg(tmp_arguments, size_t *); - assert(*idx <= req_count); - status = va_arg(tmp_arguments, H5VL_request_status_t *); - - /* Reissue the WAITANY 'request specific' call */ - ret_value = H5VL_pass_through_request_specific_reissue(o->under_object, o->under_vol_id, - specific_type, req_count, - under_req_array, timeout, idx, status); - - /* Release the completed request, if it completed */ - if (ret_value >= 0 && *status != H5ES_STATUS_IN_PROGRESS) { - H5VL_pass_through_t *tmp_o; - - tmp_o = (H5VL_pass_through_t *)req_array[*idx]; - H5VL_pass_through_free_obj(tmp_o); - } /* end if */ - } /* end if */ - else if (H5VL_REQUEST_WAITSOME == specific_type) { - size_t * outcount; /* # of completed requests */ - unsigned * array_of_indices; /* Array of indices for completed requests */ - H5VL_request_status_t *array_of_statuses; /* Array of statuses for completed requests */ - - /* Retrieve the remaining arguments */ - outcount = va_arg(tmp_arguments, size_t *); - assert(*outcount <= req_count); - array_of_indices = va_arg(tmp_arguments, unsigned *); - array_of_statuses = va_arg(tmp_arguments, H5VL_request_status_t *); - - /* Reissue the WAITSOME 'request specific' call */ - ret_value = H5VL_pass_through_request_specific_reissue( - o->under_object, o->under_vol_id, specific_type, req_count, under_req_array, timeout, - outcount, array_of_indices, array_of_statuses); - - /* If any requests completed, release them */ - if (ret_value >= 0 && *outcount > 0) { - unsigned *idx_array; /* Array of indices of completed requests */ - - /* Retrieve the array of completed request indices */ - idx_array = va_arg(tmp_arguments, unsigned *); - - /* Release the completed requests */ - for (u = 0; u < *outcount; u++) { - H5VL_pass_through_t *tmp_o; - - tmp_o = (H5VL_pass_through_t *)req_array[idx_array[u]]; - H5VL_pass_through_free_obj(tmp_o); - } /* end for */ - } /* end if */ - } /* end else-if */ - else { /* H5VL_REQUEST_WAITALL == specific_type */ - H5VL_request_status_t *array_of_statuses; /* Array of statuses for completed requests */ - - /* Retrieve the remaining arguments */ - array_of_statuses = va_arg(tmp_arguments, H5VL_request_status_t *); - - /* Reissue the WAITALL 'request specific' call */ - ret_value = H5VL_pass_through_request_specific_reissue( - o->under_object, o->under_vol_id, specific_type, req_count, under_req_array, timeout, - array_of_statuses); - - /* Release the completed requests */ - if (ret_value >= 0) { - for (u = 0; u < req_count; u++) { - if (array_of_statuses[u] != H5ES_STATUS_IN_PROGRESS) { - H5VL_pass_through_t *tmp_o; - - tmp_o = (H5VL_pass_through_t *)req_array[u]; - H5VL_pass_through_free_obj(tmp_o); - } /* end if */ - } /* end for */ - } /* end if */ - } /* end else */ - - /* Release array of requests for underlying connector */ - free(under_req_array); - } /* end if */ - - /* Finish use of copied vararg list */ - va_end(tmp_arguments); - } /* end if */ - else { - H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; - - ret_value = H5VLrequest_specific(o->under_object, o->under_vol_id, specific_type, arguments); - } /* end else */ + ret_value = H5VLrequest_specific(o->under_object, o->under_vol_id, args); return ret_value; } /* end H5VL_pass_through_request_specific() */ @@ -2926,7 +2727,7 @@ H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_t *------------------------------------------------------------------------- */ static herr_t -H5VL_pass_through_request_optional(void *obj, H5VL_request_optional_t opt_type, va_list arguments) +H5VL_pass_through_request_optional(void *obj, H5VL_optional_args_t *args) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -2935,7 +2736,7 @@ H5VL_pass_through_request_optional(void *obj, H5VL_request_optional_t opt_type, printf("------- PASS THROUGH VOL REQUEST Optional\n"); #endif - ret_value = H5VLrequest_optional(o->under_object, o->under_vol_id, opt_type, arguments); + ret_value = H5VLrequest_optional(o->under_object, o->under_vol_id, args); return ret_value; } /* end H5VL_pass_through_request_optional() */ @@ -3027,8 +2828,7 @@ H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, size_t siz *------------------------------------------------------------------------- */ herr_t -H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, - va_list arguments) +H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_args_t *args) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -3037,7 +2837,7 @@ H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t s printf("------- PASS THROUGH VOL BLOB Specific\n"); #endif - ret_value = H5VLblob_specific(o->under_object, o->under_vol_id, blob_id, specific_type, arguments); + ret_value = H5VLblob_specific(o->under_object, o->under_vol_id, blob_id, args); return ret_value; } /* end H5VL_pass_through_blob_specific() */ @@ -3052,7 +2852,7 @@ H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t s *------------------------------------------------------------------------- */ herr_t -H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_blob_optional_t opt_type, va_list arguments) +H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_optional_args_t *args) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -3061,7 +2861,7 @@ H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_blob_optional_t o printf("------- PASS THROUGH VOL BLOB Optional\n"); #endif - ret_value = H5VLblob_optional(o->under_object, o->under_vol_id, blob_id, opt_type, arguments); + ret_value = H5VLblob_optional(o->under_object, o->under_vol_id, blob_id, args); return ret_value; } /* end H5VL_pass_through_blob_optional() */ @@ -3168,7 +2968,7 @@ H5VL_pass_through_token_from_str(void *obj, H5I_type_t obj_type, const char *tok *------------------------------------------------------------------------- */ herr_t -H5VL_pass_through_optional(void *obj, int op_type, hid_t dxpl_id, void **req, va_list arguments) +H5VL_pass_through_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req) { H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; herr_t ret_value; @@ -3177,7 +2977,7 @@ H5VL_pass_through_optional(void *obj, int op_type, hid_t dxpl_id, void **req, va printf("------- PASS THROUGH VOL generic Optional\n"); #endif - ret_value = H5VLoptional(o->under_object, o->under_vol_id, op_type, dxpl_id, req, arguments); + ret_value = H5VLoptional(o->under_object, o->under_vol_id, args, dxpl_id, req); return ret_value; } /* end H5VL_pass_through_optional() */ diff --git a/src/H5VLpkg.h b/src/H5VLpkg.h index 7b8a877..5a4ccc1 100644 --- a/src/H5VLpkg.h +++ b/src/H5VLpkg.h @@ -43,6 +43,7 @@ /******************************/ /* Package Private Prototypes */ /******************************/ +H5_DLL herr_t H5VL__set_def_conn(void); H5_DLL hid_t H5VL__register_connector(const void *cls, hbool_t app_ref, hid_t vipl_id); H5_DLL hid_t H5VL__register_connector_by_class(const H5VL_class_t *cls, hbool_t app_ref, hid_t vipl_id); H5_DLL hid_t H5VL__register_connector_by_name(const char *name, hbool_t app_ref, hid_t vipl_id); @@ -56,5 +57,16 @@ H5_DLL hid_t H5VL__peek_connector_id_by_name(const char *name); H5_DLL hid_t H5VL__peek_connector_id_by_value(H5VL_class_value_t value); H5_DLL herr_t H5VL__connector_str_to_info(const char *str, hid_t connector_id, void **info); H5_DLL ssize_t H5VL__get_connector_name(hid_t id, char *name /*out*/, size_t size); +H5_DLL void H5VL__is_default_conn(hid_t fapl_id, hid_t connector_id, hbool_t *is_default); +H5_DLL herr_t H5VL__register_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val); +H5_DLL size_t H5VL__num_opt_operation(void); +H5_DLL herr_t H5VL__find_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val); +H5_DLL herr_t H5VL__unregister_opt_operation(H5VL_subclass_t subcls, const char *op_name); +H5_DLL herr_t H5VL__term_opt_operation(void); + +/* Testing functions */ +#ifdef H5VL_TESTING +H5_DLL herr_t H5VL__reparse_def_vol_conn_variable_test(void); +#endif /* H5VL_TESTING */ #endif /* H5VLpkg_H */ diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h index 34fb13d..f929d03 100644 --- a/src/H5VLprivate.h +++ b/src/H5VLprivate.h @@ -16,6 +16,11 @@ /* Include package's public header */ #include "H5VLpublic.h" /* Generic Functions */ +/* Include connector author public header(s) */ +#include "H5VLconnector.h" /* VOL connector author routines */ +#include "H5VLconnector_passthru.h" /* Pass-through VOL connector author routines */ +#include "H5VLnative.h" /* Native VOL connector macros, for VOL connector authors */ + /* Private headers needed by this file */ /**************************/ @@ -61,13 +66,15 @@ typedef enum H5VL_get_connector_kind_t { /******************************/ /* Utility functions */ -H5_DLL herr_t H5VL_init_phase1(void); -H5_DLL herr_t H5VL_init_phase2(void); +H5_DLL herr_t H5VL_init_phase1(void); +H5_DLL herr_t H5VL_init_phase2(void); +H5_DLL H5VL_t *H5VL_new_connector(hid_t connector_id); H5_DLL herr_t H5VL_cmp_connector_cls(int *cmp_value, const H5VL_class_t *cls1, const H5VL_class_t *cls2); H5_DLL herr_t H5VL_conn_copy(H5VL_connector_prop_t *value); H5_DLL int64_t H5VL_conn_inc_rc(H5VL_t *connector); H5_DLL int64_t H5VL_conn_dec_rc(H5VL_t *connector); H5_DLL herr_t H5VL_conn_free(const H5VL_connector_prop_t *info); +H5_DLL herr_t H5VL_get_cap_flags(const H5VL_connector_prop_t *prop, unsigned *cap_flags); /* Functions that deal with VOL connectors */ union H5PL_key_t; @@ -109,8 +116,9 @@ H5_DLL herr_t H5VL_reset_vol_wrapper(void); /* Library state functions */ H5_DLL herr_t H5VL_retrieve_lib_state(void **state); +H5_DLL herr_t H5VL_start_lib_state(void); H5_DLL herr_t H5VL_restore_lib_state(const void *state); -H5_DLL herr_t H5VL_reset_lib_state(void); +H5_DLL herr_t H5VL_finish_lib_state(void); H5_DLL herr_t H5VL_free_lib_state(void *state); /* ID registration functions */ @@ -127,12 +135,11 @@ H5_DLL herr_t H5VL_setup_loc_args(hid_t loc_id, H5VL_object_t **vol_obj, H5VL_lo H5_DLL herr_t H5VL_setup_acc_args(hid_t loc_id, const struct H5P_libclass_t *libclass, hbool_t is_collective, hid_t *acspl_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params); H5_DLL herr_t H5VL_setup_self_args(hid_t loc_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params); -H5_DLL herr_t H5VL_setup_name_args(hid_t loc_id, const char *name, const struct H5P_libclass_t *libclass, - hbool_t is_collective, hid_t acspl_id, H5VL_object_t **vol_obj, - H5VL_loc_params_t *loc_params); +H5_DLL herr_t H5VL_setup_name_args(hid_t loc_id, const char *name, hbool_t is_collective, hid_t lapl_id, + H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params); H5_DLL herr_t H5VL_setup_idx_args(hid_t loc_id, const char *name, H5_index_t idx_type, H5_iter_order_t order, - hsize_t n, const struct H5P_libclass_t *libclass, hbool_t is_collective, - hid_t acspl_id, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params); + hsize_t n, hbool_t is_collective, hid_t lapl_id, H5VL_object_t **vol_obj, + H5VL_loc_params_t *loc_params); H5_DLL herr_t H5VL_setup_token_args(hid_t loc_id, H5O_token_t *obj_token, H5VL_object_t **vol_obj, H5VL_loc_params_t *loc_params); @@ -156,12 +163,12 @@ H5_DLL herr_t H5VL_attr_read(const H5VL_object_t *vol_obj, hid_t dtype_id, void void **req); H5_DLL herr_t H5VL_attr_write(const H5VL_object_t *vol_obj, hid_t dtype_id, const void *buf, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL_attr_get(const H5VL_object_t *vol_obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, - ...); +H5_DLL herr_t H5VL_attr_get(const H5VL_object_t *vol_obj, H5VL_attr_get_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL_attr_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_attr_optional(const H5VL_object_t *vol_obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, - void **req, ...); + H5VL_attr_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_attr_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL_attr_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req); /* Dataset functions */ @@ -174,12 +181,12 @@ H5_DLL herr_t H5VL_dataset_read(const H5VL_object_t *vol_obj, hid_t mem_type_id, hid_t file_space_id, hid_t dxpl_id, void *buf, void **req); H5_DLL herr_t H5VL_dataset_write(const H5VL_object_t *vol_obj, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf, void **req); -H5_DLL herr_t H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_t get_type, hid_t dxpl_id, - void **req, ...); -H5_DLL herr_t H5VL_dataset_specific(const H5VL_object_t *cls, H5VL_dataset_specific_t specific_type, - hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_dataset_optional(const H5VL_object_t *vol_obj, H5VL_dataset_optional_t opt_type, - hid_t dxpl_id, void **req, ...); +H5_DLL herr_t H5VL_dataset_get(const H5VL_object_t *vol_obj, H5VL_dataset_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_dataset_specific(const H5VL_object_t *cls, H5VL_dataset_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_dataset_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL_dataset_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req); /* Datatype functions */ @@ -188,12 +195,14 @@ H5_DLL void * H5VL_datatype_commit(const H5VL_object_t *vol_obj, const H5VL_loc_ hid_t tapl_id, hid_t dxpl_id, void **req); H5_DLL void * H5VL_datatype_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL_datatype_get(const H5VL_object_t *vol_obj, H5VL_datatype_get_t get_type, hid_t dxpl_id, - void **req, ...); -H5_DLL herr_t H5VL_datatype_specific(const H5VL_object_t *vol_obj, H5VL_datatype_specific_t specific_type, - hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_datatype_optional(const H5VL_object_t *vol_obj, H5VL_datatype_optional_t opt_type, - hid_t dxpl_id, void **req, ...); +H5_DLL herr_t H5VL_datatype_get(const H5VL_object_t *vol_obj, H5VL_datatype_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_datatype_specific(const H5VL_object_t *vol_obj, H5VL_datatype_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_datatype_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_datatype_optional_op(H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req, H5VL_object_t **vol_obj_ptr); H5_DLL herr_t H5VL_datatype_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req); /* File functions */ @@ -201,12 +210,12 @@ H5_DLL void * H5VL_file_create(const H5VL_connector_prop_t *connector_prop, cons hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req); H5_DLL void * H5VL_file_open(H5VL_connector_prop_t *connector_prop, const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, - ...); -H5_DLL herr_t H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_t specific_type, - hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_file_optional(const H5VL_object_t *vol_obj, H5VL_file_optional_t opt_type, hid_t dxpl_id, - void **req, ...); +H5_DLL herr_t H5VL_file_get(const H5VL_object_t *vol_obj, H5VL_file_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_file_specific(const H5VL_object_t *vol_obj, H5VL_file_specific_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_file_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL_file_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req); /* Group functions */ @@ -215,18 +224,18 @@ H5_DLL void * H5VL_group_create(const H5VL_object_t *vol_obj, const H5VL_loc_par void **req); H5_DLL void * H5VL_group_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req); -H5_DLL herr_t H5VL_group_get(const H5VL_object_t *vol_obj, H5VL_group_get_t get_type, hid_t dxpl_id, - void **req, ...); -H5_DLL herr_t H5VL_group_specific(const H5VL_object_t *vol_obj, H5VL_group_specific_t specific_type, - hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_group_optional(const H5VL_object_t *vol_obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, - void **req, ...); +H5_DLL herr_t H5VL_group_get(const H5VL_object_t *vol_obj, H5VL_group_get_args_t *args, hid_t dxpl_id, + void **req); +H5_DLL herr_t H5VL_group_specific(const H5VL_object_t *vol_obj, H5VL_group_specific_args_t *args, + hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_group_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); H5_DLL herr_t H5VL_group_close(const H5VL_object_t *vol_obj, hid_t dxpl_id, void **req); /* Link functions */ -H5_DLL herr_t H5VL_link_create(H5VL_link_create_type_t create_type, const H5VL_object_t *vol_obj, +H5_DLL herr_t H5VL_link_create(H5VL_link_create_args_t *args, const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, - hid_t dxpl_id, void **req, ...); + hid_t dxpl_id, void **req); H5_DLL herr_t H5VL_link_copy(const H5VL_object_t *src_vol_obj, const H5VL_loc_params_t *loc_params1, const H5VL_object_t *dst_vol_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); @@ -234,11 +243,11 @@ H5_DLL herr_t H5VL_link_move(const H5VL_object_t *src_vol_obj, const H5VL_loc_pa const H5VL_object_t *dst_vol_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL_link_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_link_get_t get_type, hid_t dxpl_id, void **req, ...); + H5VL_link_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL_link_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_link_optional(const H5VL_object_t *vol_obj, H5VL_link_optional_t opt_type, hid_t dxpl_id, - void **req, ...); + H5VL_link_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_link_optional(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Object functions */ H5_DLL void * H5VL_object_open(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *params, @@ -248,15 +257,16 @@ H5_DLL herr_t H5VL_object_copy(const H5VL_object_t *src_obj, const H5VL_loc_para const H5VL_loc_params_t *dst_loc_params, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL_object_get(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_object_get_t get_type, hid_t dxpl_id, void **req, ...); + H5VL_object_get_args_t *args, hid_t dxpl_id, void **req); H5_DLL herr_t H5VL_object_specific(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, - H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, ...); -H5_DLL herr_t H5VL_object_optional(const H5VL_object_t *vol_obj, H5VL_object_optional_t opt_type, - hid_t dxpl_id, void **req, ...); + H5VL_object_specific_args_t *args, hid_t dxpl_id, void **req); +H5_DLL herr_t H5VL_object_optional(const H5VL_object_t *vol_obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); /* Connector/container introspection functions */ H5_DLL herr_t H5VL_introspect_get_conn_cls(const H5VL_object_t *vol_obj, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls); +H5_DLL herr_t H5VL_introspect_get_cap_flags(const void *info, const H5VL_class_t *cls, unsigned *cap_flags); H5_DLL herr_t H5VL_introspect_opt_query(const H5VL_object_t *vol_obj, H5VL_subclass_t subcls, int opt_type, uint64_t *flags); @@ -265,8 +275,8 @@ H5_DLL herr_t H5VL_request_wait(const H5VL_object_t *vol_obj, uint64_t timeout, H5VL_request_status_t *status); H5_DLL herr_t H5VL_request_notify(const H5VL_object_t *vol_obj, H5VL_request_notify_t cb, void *ctx); H5_DLL herr_t H5VL_request_cancel(const H5VL_object_t *vol_obj, H5VL_request_status_t *status); -H5_DLL herr_t H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_t specific_type, ...); -H5_DLL herr_t H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_request_optional_t opt_type, ...); +H5_DLL herr_t H5VL_request_specific(const H5VL_object_t *vol_obj, H5VL_request_specific_args_t *args); +H5_DLL herr_t H5VL_request_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args); H5_DLL herr_t H5VL_request_free(const H5VL_object_t *vol_obj); /* Blob functions */ @@ -275,9 +285,8 @@ H5_DLL herr_t H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_ H5_DLL herr_t H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, size_t size, void *ctx); H5_DLL herr_t H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, - H5VL_blob_specific_t specific_type, ...); -H5_DLL herr_t H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_optional_t opt_type, - ...); + H5VL_blob_specific_args_t *args); +H5_DLL herr_t H5VL_blob_optional(const H5VL_object_t *vol_obj, void *blob_id, H5VL_optional_args_t *args); /* Token functions */ H5_DLL herr_t H5VL_token_cmp(const H5VL_object_t *vol_obj, const H5O_token_t *token1, @@ -288,6 +297,7 @@ H5_DLL herr_t H5VL_token_from_str(const H5VL_object_t *vol_obj, H5I_type_t obj_t H5O_token_t *token); /* Generic functions */ -H5_DLL herr_t H5VL_optional(const H5VL_object_t *vol_obj, int op_type, hid_t dxpl_id, void **req, ...); +H5_DLL herr_t H5VL_optional(const H5VL_object_t *vol_obj, H5VL_optional_args_t *args, hid_t dxpl_id, + void **req); #endif /* H5VLprivate_H */ diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h index c5f85dc..78e39e3 100644 --- a/src/H5VLpublic.h +++ b/src/H5VLpublic.h @@ -116,6 +116,9 @@ typedef enum H5VL_subclass_t { H5VL_SUBCLS_REQUEST, /**< 'Request' subclass */ H5VL_SUBCLS_BLOB, /**< 'Blob' subclass */ H5VL_SUBCLS_TOKEN /**< 'Token' subclass */ + /* NOTE: if more operations are added, the + * H5VL_opt_vals_g[] array size should be updated. + */ } H5VL_subclass_t; /********************/ @@ -358,9 +361,4 @@ H5_DLL herr_t H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_t } #endif -/* Semi-public headers mainly for VOL connector authors */ -#include "H5VLconnector.h" /* VOL connector author routines */ -#include "H5VLconnector_passthru.h" /* Pass-through VOL connector author routines */ -#include "H5VLnative.h" /* Native VOL connector macros, for VOL connector authors */ - #endif /* H5VLpublic_H */ diff --git a/src/H5VLtest.c b/src/H5VLtest.c new file mode 100644 index 0000000..1f99ce5 --- /dev/null +++ b/src/H5VLtest.c @@ -0,0 +1,96 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5VLtest.c + * Jan 3 2021 + * Quincey Koziol + * + * Purpose: Virtual Object Layer (VOL) testing routines. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5VLmodule.h" /* This source code file is part of the H5VL module */ +#define H5VL_TESTING /* Suppress warning about H5VL testing funcs */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5VLpkg.h" /* Virtual Object Layer */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/********************/ +/* Package Typedefs */ +/********************/ + +/********************/ +/* Local Prototypes */ +/********************/ + +/*********************/ +/* Package Variables */ +/*********************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + +/*------------------------------------------------------------------------- + * Function: H5VL__reparse_def_vol_conn_variable_test + * + * Purpose: Re-parse the default VOL connector environment variable. + * + * Since getenv(3) is fairly expensive, we only parse it once, + * when the library opens. This test function is used to + * re-parse the environment variable after we've changed it + * with setenv(3). + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * Feb 3, 2021 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL__reparse_def_vol_conn_variable_test(void) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Re-check for the HDF5_VOL_CONNECTOR environment variable */ + if (H5VL__set_def_conn() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize default VOL connector") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__reparse_def_vol_conn_variable_test() */ diff --git a/src/H5Zmodule.h b/src/H5Zmodule.h index 76a2380..9312b72 100644 --- a/src/H5Zmodule.h +++ b/src/H5Zmodule.h @@ -29,57 +29,80 @@ #define H5_MY_PKG_ERR H5E_PLINE #define H5_MY_PKG_INIT YES -/** - * \defgroup H5Z H5Z +/**\defgroup H5Z H5Z * + * Use the functions in this module to manage HDF5 filters. * - * \brief Filter and Compression Interface + * User-defined filters are created by registering a filter descriptor of + * type #H5Z_class_t with the library. * - * \details The functions in this module let you configure filters that process - * data during I/O operation. + * Available filters can be read or examined at runtime. * - * HDF5 supports a filter pipeline that provides the capability for - * standard and customized raw data processing during I/O operations. - * HDF5 is distributed with a small set of standard filters such as - * compression (gzip, SZIP, and a shuffling algorithm) and error - * checking (Fletcher32 checksum). For further flexibility, the - * library allows a user application to extend the pipeline through - * the creation and registration of customized filters. + * It is conceivable that filters are stateful and that that state be + * updated at runtime. * - * The flexibility of the filter pipeline implementation enables the - * definition of additional filters by a user application. A filter - * \li is associated with a dataset when the dataset is created, - * \li can be used only with chunked data (i.e., datasets stored in - * the #H5D_CHUNKED storage layout), and - * \li is applied independently to each chunk of the dataset. + * Filters are deleted by unregistering. * - * The HDF5 library does not support filters for contiguous datasets - * because of the difficulty of implementing random access for partial - * I/O. Compact dataset filters are not supported because it would not - * produce significant results. + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5Z_examples.c filter + * \snippet{lineno} H5Z_examples.c create + * </td> + * <td> + * \snippet{lineno} H5Z_examples.c read + * </td> + * </tr> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5Z_examples.c update + * </td> + * <td> + * \snippet{lineno} H5Z_examples.c delete + * </tr> + * </table> * - * Filter identifiers for the filters distributed with the HDF5 - * Library are as follows: - * <table> - * <tr><td>#H5Z_FILTER_DEFLATE</td><td>The gzip compression, or - * deflation, filter</td></tr> - * <tr><td>#H5Z_FILTER_SZIP</td><td>The SZIP compression - * filter</td></tr> - * <tr><td>#H5Z_FILTER_NBIT</td><td>The N-bit compression - * filter</td></tr> - * <tr><td>#H5Z_FILTER_SCALEOFFSET</td><td>The scale-offset - * compression filter</td></tr> - * <tr><td>#H5Z_FILTER_SHUFFLE</td><td>The shuffle algorithm - * filter</td></tr> - * <tr><td>#H5Z_FILTER_FLETCHER32</td><td>The Fletcher32 checksum, - * or error checking, filter</td></tr> - * </table> - * Custom filters that have been registered with the library will have - * additional unique identifiers. + * HDF5 supports a filter pipeline that provides the capability for standard and + * customized raw data processing during I/O operations. HDF5 is distributed + * with a small set of standard filters such as compression (gzip, SZIP, and a + * shuffling algorithm) and error checking (Fletcher32 checksum). For further + * flexibility, the library allows a user application to extend the pipeline + * through the creation and registration of customized filters. * - * See \ref_dld_filters for more information on how an HDF5 - * application can apply a filter that is not registered with the HDF5 - * library. + * The flexibility of the filter pipeline implementation enables the definition + * of additional filters by a user application. A filter + * \li is associated with a dataset when the dataset is created, + * \li can be used only with chunked data (i.e., datasets stored in the + * #H5D_CHUNKED storage layout), and + * \li is applied independently to each chunk of the dataset. + * + * The HDF5 library does not support filters for contiguous datasets because of + * the difficulty of implementing random access for partial I/O. Compact dataset + * filters are not supported because it would not produce significant results. + * + * Filter identifiers for the filters distributed with the HDF5 + * Library are as follows: + * <table> + * <tr><td>#H5Z_FILTER_DEFLATE</td><td>The gzip compression, or + * deflation, filter</td></tr> + * <tr><td>#H5Z_FILTER_SZIP</td><td>The SZIP compression + * filter</td></tr> + * <tr><td>#H5Z_FILTER_NBIT</td><td>The N-bit compression + * filter</td></tr> + * <tr><td>#H5Z_FILTER_SCALEOFFSET</td><td>The scale-offset + * compression filter</td></tr> + * <tr><td>#H5Z_FILTER_SHUFFLE</td><td>The shuffle algorithm + * filter</td></tr> + * <tr><td>#H5Z_FILTER_FLETCHER32</td><td>The Fletcher32 checksum, + * or error checking, filter</td></tr> + * </table> + * Custom filters that have been registered with the library will have + * additional unique identifiers. + * + * See \ref_dld_filters for more information on how an HDF5 application can + * apply a filter that is not registered with the HDF5 library. * * \defgroup H5ZPRE Predefined Filters * \ingroup H5Z diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c index 2e1a474..a8a63bf 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -425,22 +425,22 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ #define H5Z_scaleoffset_check_3(i, type, pow_fun, round_fun, max, min, minbits, D_val) \ { \ if (sizeof(type) == sizeof(int)) { \ - if (round_fun(max * pow_fun(10.0f, (type)D_val) - min * pow_fun(10.0f, (type)D_val)) > \ - pow_fun(2.0f, (type)(sizeof(int) * 8 - 1))) { \ + if (round_fun(max * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)) > \ + pow_fun(2.0F, (type)(sizeof(int) * 8 - 1))) { \ *minbits = sizeof(int) * 8; \ goto done; \ } \ } \ else if (sizeof(type) == sizeof(long)) { \ - if (round_fun(max * pow_fun(10.0f, (type)D_val) - min * pow_fun(10.0f, (type)D_val)) > \ - pow_fun(2.0f, (type)(sizeof(long) * 8 - 1))) { \ + if (round_fun(max * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)) > \ + pow_fun(2.0F, (type)(sizeof(long) * 8 - 1))) { \ *minbits = sizeof(long) * 8; \ goto done; \ } \ } \ else if (sizeof(type) == sizeof(long long)) { \ - if (round_fun(max * pow_fun(10.0f, (type)D_val) - min * pow_fun(10.0f, (type)D_val)) > \ - pow_fun(2.0f, (type)(sizeof(long long) * 8 - 1))) { \ + if (round_fun(max * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)) > \ + pow_fun(2.0F, (type)(sizeof(long long) * 8 - 1))) { \ *minbits = sizeof(long long) * 8; \ goto done; \ } \ @@ -530,27 +530,27 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ { \ if (sizeof(type) == sizeof(int)) \ for (i = 0; i < d_nelmts; i++) { \ - if (abs_fun(buf[i] - filval) < pow_fun(10.0f, (type)-D_val)) \ + if (abs_fun(buf[i] - filval) < pow_fun(10.0F, (type)-D_val)) \ *(int *)((void *)&buf[i]) = (int)(((unsigned int)1 << *minbits) - 1); \ else \ - *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)); \ + *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)); \ } \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) { \ - if (abs_fun(buf[i] - filval) < pow_fun(10.0f, (type)-D_val)) \ + if (abs_fun(buf[i] - filval) < pow_fun(10.0F, (type)-D_val)) \ *(long *)((void *)&buf[i]) = (long)(((unsigned long)1 << *minbits) - 1); \ else \ - *(long *)((void *)&buf[i]) = lround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)); \ + *(long *)((void *)&buf[i]) = lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)); \ } \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) { \ - if (abs_fun(buf[i] - filval) < pow_fun(10.0f, (type)-D_val)) \ + if (abs_fun(buf[i] - filval) < pow_fun(10.0F, (type)-D_val)) \ *(long long *)((void *)&buf[i]) = (long long)(((unsigned long long)1 << *minbits) - 1); \ else \ - *(long long *)((void *)&buf[i]) = llround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)); \ + *(long long *)((void *)&buf[i]) = llround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)); \ } \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ @@ -561,16 +561,16 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ { \ if (sizeof(type) == sizeof(int)) \ for (i = 0; i < d_nelmts; i++) \ - *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)); \ + *(int *)((void *)&buf[i]) = (int)lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)); \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) \ *(long *)((void *)&buf[i]) = \ - lround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - min * pow_fun(10.0f, (type)D_val)); \ + lround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)); \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) \ *(long long *)((void *)&buf[i]) = \ - llround_fun(buf[i] * pow_fun(10.0f, (type)D_val) - min * pow_fun(10.0f, (type)D_val)); \ + llround_fun(buf[i] * pow_fun(10.0F, (type)D_val) - min * pow_fun(10.0F, (type)D_val)); \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } @@ -606,8 +606,8 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ H5Z_scaleoffset_get_filval_2(type, cd_values, filval) \ H5Z_scaleoffset_max_min_3(i, d_nelmts, buf, filval, max, min, D_val) \ H5Z_scaleoffset_check_3(i, type, pow_fun, round_fun, max, min, minbits, D_val) span = \ - (unsigned long long)(llround_fun(max * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)) + \ + (unsigned long long)(llround_fun(max * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)) + \ 1); \ *minbits = H5Z__scaleoffset_log2(span + 1); \ if (*minbits != sizeof(type) * 8) /* change values if minbits != full precision */ \ @@ -617,8 +617,8 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ else { /* fill value undefined */ \ H5Z_scaleoffset_max_min_2(i, d_nelmts, buf, max, min) \ H5Z_scaleoffset_check_3(i, type, pow_fun, round_fun, max, min, minbits, D_val) span = \ - (unsigned long long)(llround_fun(max * pow_fun(10.0f, (type)D_val) - \ - min * pow_fun(10.0f, (type)D_val)) + \ + (unsigned long long)(llround_fun(max * pow_fun(10.0F, (type)D_val) - \ + min * pow_fun(10.0F, (type)D_val)) + \ 1); \ *minbits = H5Z__scaleoffset_log2(span); \ if (*minbits != sizeof(type) * 8) /* change values if minbits != full precision */ \ @@ -685,19 +685,19 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ buf[i] = \ (type)((*(int *)((void *)&buf[i]) == (int)(((unsigned int)1 << minbits) - 1)) \ ? filval \ - : (type)(*(int *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + : (type)(*(int *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) \ buf[i] = \ (type)((*(long *)((void *)&buf[i]) == (long)(((unsigned long)1 << minbits) - 1)) \ ? filval \ - : (type)(*(long *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + : (type)(*(long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) \ buf[i] = (type)( \ (*(long long *)((void *)&buf[i]) == (long long)(((unsigned long long)1 << minbits) - 1)) \ ? filval \ - : (type)(*(long long *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + : (type)(*(long long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } @@ -707,13 +707,13 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ { \ if (sizeof(type) == sizeof(int)) \ for (i = 0; i < d_nelmts; i++) \ - buf[i] = ((type)(*(int *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + buf[i] = ((type)(*(int *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long)) \ for (i = 0; i < d_nelmts; i++) \ - buf[i] = ((type)(*(long *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + buf[i] = ((type)(*(long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else if (sizeof(type) == sizeof(long long)) \ for (i = 0; i < d_nelmts; i++) \ - buf[i] = ((type)(*(long long *)((void *)&buf[i])) / pow_fun(10.0f, (type)D_val) + min); \ + buf[i] = ((type)(*(long long *)((void *)&buf[i])) / pow_fun(10.0F, (type)D_val) + min); \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } diff --git a/src/H5Ztrans.c b/src/H5Ztrans.c index 7d55efd..ab7e9be 100644 --- a/src/H5Ztrans.c +++ b/src/H5Ztrans.c @@ -1547,11 +1547,11 @@ H5Z_xform_create(const char *expr) (HDisdigit(expr[i - 1]) || (expr[i - 1] == '.')) && (HDisdigit(expr[i + 1]) || (expr[i + 1] == '-') || (expr[i + 1] == '+'))) continue; - } + } /* end if */ count++; - } - } + } /* end if */ + } /* end for */ /* When there are no "x"'s in the equation (ie, simple transform case), * we don't need to allocate any space since no array will have to be @@ -1749,11 +1749,19 @@ done: hbool_t H5Z_xform_noop(const H5Z_data_xform_t *data_xform_prop) { - hbool_t ret_value = FALSE; /* Return value */ + hbool_t ret_value = TRUE; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOERR - ret_value = (data_xform_prop ? FALSE : TRUE); + if (data_xform_prop) { + ret_value = FALSE; + + /* Check for trivial data tranformation: expression = "x" */ + if ((HDstrlen(data_xform_prop->xform_exp) == 1) && data_xform_prop->dat_val_pointers && + (data_xform_prop->dat_val_pointers->num_ptrs == 1)) { + ret_value = TRUE; + } /* end if */ + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* H5Z_xform_noop() */ diff --git a/src/H5detect.c b/src/H5detect.c index 2e893cf..e8cded7 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -52,7 +52,7 @@ static const char *FileHeader = "\n\ /* Disable warning about cast increasing the alignment of the target type, * that's _exactly_ what this code is probing. -QAK */ -H5_GCC_DIAG_OFF("cast-align") +H5_GCC_CLANG_DIAG_OFF("cast-align") #if defined(__has_attribute) #if __has_attribute(no_sanitize_address) @@ -300,10 +300,10 @@ precision(detected_t *d) for (_byte_mask = (unsigned char)1; _byte_mask; _byte_mask = (unsigned char)(_byte_mask << 1)) { \ _buf1[_i] ^= _byte_mask; \ HDmemcpy((void *)&_v2, (const void *)_buf1, sizeof(TYPE)); \ - H5_GCC_DIAG_OFF("float-equal") \ + H5_GCC_CLANG_DIAG_OFF("float-equal") \ if (_v1 != _v2) \ _pad_mask[_i] |= _byte_mask; \ - H5_GCC_DIAG_ON("float-equal") \ + H5_GCC_CLANG_DIAG_ON("float-equal") \ _buf1[_i] ^= _byte_mask; \ } /* end for */ \ \ @@ -414,10 +414,10 @@ precision(detected_t *d) HDmemcpy(_buf + align_g[_ano] + (INFO.offset / 8), ((char *)&_val) + (INFO.offset / 8), \ (size_t)(INFO.precision / 8)); \ _val2 = *((TYPE *)(_buf + align_g[_ano])); \ - H5_GCC_DIAG_OFF("float-equal") \ + H5_GCC_CLANG_DIAG_OFF("float-equal") \ if (_val != _val2) \ H5LONGJMP(jbuf_g, 1); \ - H5_GCC_DIAG_ON("float-equal") \ + H5_GCC_CLANG_DIAG_ON("float-equal") \ /* End Cray Check */ \ (INFO.align) = align_g[_ano]; \ } \ @@ -1567,4 +1567,4 @@ main(int argc, char *argv[]) return EXIT_SUCCESS; } -H5_GCC_DIAG_ON("cast-align") +H5_GCC_CLANG_DIAG_ON("cast-align") diff --git a/src/H5module.h b/src/H5module.h index 64081bf..6d3cba8 100644 --- a/src/H5module.h +++ b/src/H5module.h @@ -27,8 +27,31 @@ #define H5_MY_PKG_INIT YES /**\defgroup H5 H5 - * \brief General Library Functions - * \todo Describe concisely what the functions in this module are about. + * + * Use the functions in this module to manage the life cycle of HDF5 library + * instances. + * + * <table> + * <tr><th>Create</th><th>Read</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5_examples.c create + * </td> + * <td> + * \snippet{lineno} H5_examples.c read + * </td> + * <tr><th>Update</th><th>Delete</th></tr> + * <tr valign="top"> + * <td> + * \snippet{lineno} H5_examples.c update + * </td> + * <td> + * \snippet{lineno} H5_examples.c closing_shop + * \snippet{lineno} H5_examples.c delete + * </td> + * </tr> + * </table> + * */ #endif /* H5module_H */ diff --git a/src/H5mpi.c b/src/H5mpi.c index 9749721..4a8aa44 100644 --- a/src/H5mpi.c +++ b/src/H5mpi.c @@ -523,7 +523,7 @@ H5_mpio_create_large_type(hsize_t num_elements, MPI_Aint stride_bytes, MPI_Datat MPI_Type_get_extent(old_type, &unused_lb_arg, &old_extent); } - /* Set up the arguments for MPI_Type_struct constructor */ + /* Set up the arguments for MPI_Type_create_struct() */ type[0] = outer_type; type[1] = leftover_type; block_len[0] = 1; diff --git a/src/H5private.h b/src/H5private.h index bb416ef..7c76483 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -44,7 +44,9 @@ #include <sys/time.h> #endif #ifdef H5_HAVE_UNISTD_H +#ifdef H5_HAVE_PWD_H #include <pwd.h> +#endif #include <unistd.h> #include <sys/wait.h> #endif @@ -456,7 +458,7 @@ #define LOCK_UN 0x08 #endif /* H5_HAVE_FLOCK */ -/* Macros for enabling/disabling particular GCC warnings +/* Macros for enabling/disabling particular GCC / clang warnings * * These are duplicated in H5FDmulti.c (we don't want to put them in the * public header and the multi VFD can't use private headers). If you make @@ -466,19 +468,45 @@ * http://www.dbp-consulting.com/tutorials/SuppressingGCCWarnings.html * http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas */ -/* These pragmas are only implemented usefully in gcc 4.6+ */ -#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406 -#define H5_GCC_DIAG_JOINSTR(x, y) x y -#define H5_GCC_DIAG_DO_PRAGMA(x) _Pragma(#x) -#define H5_GCC_DIAG_PRAGMA(x) H5_GCC_DIAG_DO_PRAGMA(GCC diagnostic x) - -#define H5_GCC_DIAG_OFF(x) H5_GCC_DIAG_PRAGMA(push) H5_GCC_DIAG_PRAGMA(ignored H5_GCC_DIAG_JOINSTR("-W", x)) -#define H5_GCC_DIAG_ON(x) H5_GCC_DIAG_PRAGMA(pop) +#define H5_DIAG_JOINSTR(x, y) x y +#define H5_DIAG_DO_PRAGMA(x) _Pragma(#x) +#define H5_DIAG_PRAGMA(x) H5_DIAG_DO_PRAGMA(GCC diagnostic x) + +#define H5_DIAG_OFF(x) H5_DIAG_PRAGMA(push) H5_DIAG_PRAGMA(ignored H5_DIAG_JOINSTR("-W", x)) +#define H5_DIAG_ON(x) H5_DIAG_PRAGMA(pop) + +/* Macros for enabling/disabling particular GCC-only warnings. + * These pragmas are only implemented usefully in gcc 4.6+ + */ +#if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) +#define H5_GCC_DIAG_OFF(x) H5_DIAG_OFF(x) +#define H5_GCC_DIAG_ON(x) H5_DIAG_ON(x) #else #define H5_GCC_DIAG_OFF(x) #define H5_GCC_DIAG_ON(x) #endif +/* Macros for enabling/disabling particular clang-only warnings. + */ +#if defined(__clang__) +#define H5_CLANG_DIAG_OFF(x) H5_DIAG_OFF(x) +#define H5_CLANG_DIAG_ON(x) H5_DIAG_ON(x) +#else +#define H5_CLANG_DIAG_OFF(x) +#define H5_CLANG_DIAG_ON(x) +#endif + +/* Macros for enabling/disabling particular GCC / clang warnings. + * These macros should be used for warnings supported by both gcc and clang. + */ +#if (((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) || defined(__clang__) +#define H5_GCC_CLANG_DIAG_OFF(x) H5_DIAG_OFF(x) +#define H5_GCC_CLANG_DIAG_ON(x) H5_DIAG_ON(x) +#else +#define H5_GCC_CLANG_DIAG_OFF(x) +#define H5_GCC_CLANG_DIAG_ON(x) +#endif + /* Typedefs and functions for timing certain parts of the library. */ /* A set of elapsed/user/system times emitted as a time point by the @@ -2227,7 +2255,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props); * Use this macro for API functions that shouldn't perform _any_ initialization * of the library or an interface, or push themselves on the function * stack, or perform tracing, etc. This macro _only_ sanity checks the - * API name itself. Examples are: H5TSmutex_acquire, + * API name itself. Examples are: H5TSmutex_acquire, * */ #define FUNC_ENTER_API_NAMECHECK_ONLY \ @@ -2323,7 +2351,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props); * Use this macro for non-API functions that shouldn't perform _any_ initialization * of the library or an interface, or push themselves on the function * stack, or perform tracing, etc. This macro _only_ sanity checks the - * API name itself. Examples are private routines in the H5TS package. + * API name itself. Examples are private routines in the H5TS package. * */ #define FUNC_ENTER_NOAPI_NAMECHECK_ONLY \ @@ -2401,7 +2429,7 @@ H5_DLL herr_t H5CX_pop(hbool_t update_dxpl_props); * Use this macro for non-API functions that shouldn't perform _any_ initialization * of the library or an interface, or push themselves on the function * stack, or perform tracing, etc. This macro _only_ sanity checks the - * API name itself. Examples are static routines in the H5TS package. + * API name itself. Examples are static routines in the H5TS package. * */ #define FUNC_ENTER_STATIC_NAMECHECK_ONLY \ diff --git a/src/H5public.h b/src/H5public.h index e192de0..65709c6 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -56,8 +56,12 @@ #ifdef H5_HAVE_PARALLEL /* Don't link against MPI C++ bindings */ +#ifndef MPICH_SKIP_MPICXX #define MPICH_SKIP_MPICXX 1 -#define OMPI_SKIP_MPICXX 1 +#endif +#ifndef OMPI_SKIP_MPICXX +#define OMPI_SKIP_MPICXX 1 +#endif #include <mpi.h> #ifndef MPI_FILE_NULL /* MPIO may be defined in mpi.h already */ #include <mpio.h> @@ -168,8 +172,9 @@ * Status return values. Failed integer functions in HDF5 result almost * always in a negative value (unsigned failing functions sometimes return * zero for failure) while successful return is non-negative (often zero). - * The negative failure value is most commonly -1, but don't bet on it. The - * proper way to detect failure is something like: + * The negative failure value is most commonly -1, but don't bet on it. + * + * The proper way to detect failure is something like: * \code * if((dset = H5Dopen2(file, name)) < 0) * fprintf(stderr, "unable to open the requested dataset\n"); @@ -178,11 +183,17 @@ typedef int herr_t; /** - * Boolean type. Successful return values are zero (false) or positive - * (true). The typical true value is 1 but don't bet on it. Boolean - * functions cannot fail. Functions that return #htri_t however return zero - * (false), positive (true), or negative (failure). The proper way to test - * for truth from a #htri_t function is: + * C99-style Boolean type. Successful return values are zero (false) or positive + * (true). The typical true value is 1 but don't bet on it. + * \attention Boolean functions cannot fail. + */ +#include <stdbool.h> +typedef bool hbool_t; +/** + * Three-valued Boolean type. Functions that return #htri_t however return zero + * (false), positive (true), or negative (failure). + * + * The proper way to test for truth from a #htri_t function is: * \code * if ((retval = H5Tcommitted(type)) > 0) { * printf("data type is committed\n"); @@ -193,8 +204,7 @@ typedef int herr_t; * } * \endcode */ -typedef bool hbool_t; -typedef int htri_t; +typedef int htri_t; /* The signed version of size_t * @@ -281,9 +291,9 @@ typedef enum { /* (Actually, any positive value will cause the iterator to stop and pass back * that positive value to the function that called the iterator) */ -#define H5_ITER_ERROR (-1) -#define H5_ITER_CONT (0) -#define H5_ITER_STOP (1) +#define H5_ITER_ERROR (-1) /**< Error, stop iteration */ +#define H5_ITER_CONT (0) /**< Continue iteration */ +#define H5_ITER_STOP (1) /**< Stop iteration, short-circuit success */ //! <!-- [H5_index_t_snip] --> /** diff --git a/src/H5system.c b/src/H5system.c index adfb758..e671ea9 100644 --- a/src/H5system.c +++ b/src/H5system.c @@ -732,8 +732,8 @@ H5_build_extpath(const char *name, char **extpath /*out*/) HDstrncpy(full_path, cwdpath, cwdlen + 1); if (!H5_CHECK_DELIMITER(cwdpath[cwdlen - 1])) - HDstrncat(full_path, H5_DIR_SEPS, HDstrlen(H5_DIR_SEPS)); - HDstrncat(full_path, new_name, HDstrlen(new_name)); + HDstrncat(full_path, H5_DIR_SEPS, path_len - (cwdlen + 1)); + HDstrncat(full_path, new_name, path_len - (cwdlen + 1) - HDstrlen(H5_DIR_SEPS)); } /* end if */ } /* end else */ @@ -1098,8 +1098,8 @@ const char *H5_optarg; /* Flag argument (or value) */ int H5_get_option(int argc, const char **argv, const char *opts, const struct h5_long_options *l_opts) { - static int sp = 1; /* character index in current token */ - int optopt = '?'; /* option character passed back to user */ + static int sp = 1; /* character index in current token */ + int optchar = '?'; /* option character passed back to user */ if (sp == 1) { /* check for more flag-like tokens */ @@ -1130,7 +1130,7 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon for (i = 0; l_opts && l_opts[i].name; i++) { if (HDstrcmp(arg, l_opts[i].name) == 0) { /* we've found a matching long command line flag */ - optopt = l_opts[i].shortval; + optchar = l_opts[i].shortval; if (l_opts[i].has_arg != no_arg) { if (H5_optarg == NULL) { @@ -1143,7 +1143,7 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon if (H5_opterr) HDfprintf(stderr, "%s: option required for \"--%s\" flag\n", argv[0], arg); - optopt = '?'; + optchar = '?'; } } } @@ -1152,7 +1152,7 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon if (H5_opterr) HDfprintf(stderr, "%s: no option required for \"%s\" flag\n", argv[0], arg); - optopt = '?'; + optchar = '?'; } } break; @@ -1164,7 +1164,7 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon if (H5_opterr) HDfprintf(stderr, "%s: unknown option \"%s\"\n", argv[0], arg); - optopt = '?'; + optchar = '?'; } H5_optind++; @@ -1176,11 +1176,11 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon register char *cp; /* pointer into current token */ /* short command line option */ - optopt = argv[H5_optind][sp]; + optchar = argv[H5_optind][sp]; - if (optopt == ':' || (cp = HDstrchr(opts, optopt)) == 0) { + if (optchar == ':' || (cp = HDstrchr(opts, optchar)) == 0) { if (H5_opterr) - HDfprintf(stderr, "%s: unknown option \"%c\"\n", argv[0], optopt); + HDfprintf(stderr, "%s: unknown option \"%c\"\n", argv[0], optchar); /* if no chars left in this token, move to next token */ if (argv[H5_optind][++sp] == '\0') { @@ -1198,9 +1198,9 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon } else if (++H5_optind >= argc) { if (H5_opterr) - HDfprintf(stderr, "%s: value expected for option \"%c\"\n", argv[0], optopt); + HDfprintf(stderr, "%s: value expected for option \"%c\"\n", argv[0], optchar); - optopt = '?'; + optchar = '?'; } else { /* flag value is next token */ @@ -1238,5 +1238,5 @@ H5_get_option(int argc, const char **argv, const char *opts, const struct h5_lon } /* return the current flag character found */ - return optopt; + return optchar; } diff --git a/src/H5trace.c b/src/H5trace.c index e33bc12..3a5d420 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -1083,6 +1083,15 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) } /* end block */ break; + case 'C': /* H5ES_event_complete_func_t */ + { + H5ES_event_complete_func_t cfunc = + (H5ES_event_complete_func_t)HDva_arg(ap, H5ES_event_complete_func_t); + + H5RS_asprintf_cat(rs, "%p", (void *)(uintptr_t)cfunc); + } /* end block */ + break; + case 'd': /* H5E_direction_t */ { H5E_direction_t direction = (H5E_direction_t)HDva_arg(ap, int); @@ -1111,6 +1120,15 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) } /* end block */ break; + case 'I': /* H5ES_event_insert_func_t */ + { + H5ES_event_insert_func_t ifunc = + (H5ES_event_insert_func_t)HDva_arg(ap, H5ES_event_insert_func_t); + + H5RS_asprintf_cat(rs, "%p", (void *)(uintptr_t)ifunc); + } /* end block */ + break; + case 's': /* H5ES_status_t */ { H5ES_status_t status = (H5ES_status_t)HDva_arg(ap, int); @@ -1124,6 +1142,10 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5ES_STATUS_SUCCEED"); break; + case H5ES_STATUS_CANCELED: + H5RS_acat(rs, "H5ES_STATUS_CANCELED"); + break; + case H5ES_STATUS_FAIL: H5RS_acat(rs, "H5ES_STATUS_FAIL"); break; @@ -1467,6 +1489,14 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) } /* end block */ break; + case 'c': /* H5_atclose_func_t */ + { + H5_atclose_func_t cfunc = (H5_atclose_func_t)HDva_arg(ap, H5_atclose_func_t); + + H5RS_asprintf_cat(rs, "%p", (void *)(uintptr_t)cfunc); + } /* end block */ + break; + case 's': /* hssize_t */ { hssize_t hssize = HDva_arg(ap, hssize_t); @@ -2873,6 +2903,10 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5VL_ATTR_DELETE"); break; + case H5VL_ATTR_DELETE_BY_IDX: + H5RS_acat(rs, "H5VL_ATTR_DELETE_BY_IDX"); + break; + case H5VL_ATTR_EXISTS: H5RS_acat(rs, "H5VL_ATTR_EXISTS"); break; @@ -2901,10 +2935,6 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5VL_BLOB_DELETE"); break; - case H5VL_BLOB_GETSIZE: - H5RS_acat(rs, "H5VL_BLOB_GETSIZE"); - break; - case H5VL_BLOB_ISNULL: H5RS_acat(rs, "H5VL_BLOB_ISNULL"); break; @@ -2985,10 +3015,6 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5VL_DATASET_REFRESH"); break; - case H5VL_DATASET_WAIT: - H5RS_acat(rs, "H5VL_DATASET_WAIT"); - break; - default: H5RS_asprintf_cat(rs, "%ld", (long)specific); break; @@ -3001,6 +3027,10 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5VL_datatype_get_t get = (H5VL_datatype_get_t)HDva_arg(ap, int); switch (get) { + case H5VL_DATATYPE_GET_BINARY_SIZE: + H5RS_acat(rs, "H5VL_DATATYPE_GET_BINARY_SIZE"); + break; + case H5VL_DATATYPE_GET_BINARY: H5RS_acat(rs, "H5VL_DATATYPE_GET_BINARY"); break; @@ -3093,14 +3123,6 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5VL_FILE_REOPEN"); break; - case H5VL_FILE_MOUNT: - H5RS_acat(rs, "H5VL_FILE_MOUNT"); - break; - - case H5VL_FILE_UNMOUNT: - H5RS_acat(rs, "H5VL_FILE_UNMOUNT"); - break; - case H5VL_FILE_IS_ACCESSIBLE: H5RS_acat(rs, "H5VL_FILE_IS_ACCESSIBLE"); break; @@ -3113,10 +3135,6 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5RS_acat(rs, "H5VL_FILE_IS_EQUAL"); break; - case H5VL_FILE_WAIT: - H5RS_acat(rs, "H5VL_FILE_WAIT"); - break; - default: H5RS_asprintf_cat(rs, "%ld", (long)specific); break; @@ -3149,6 +3167,14 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5VL_group_specific_t specific = (H5VL_group_specific_t)HDva_arg(ap, int); switch (specific) { + case H5VL_GROUP_MOUNT: + H5RS_acat(rs, "H5VL_GROUP_MOUNT"); + break; + + case H5VL_GROUP_UNMOUNT: + H5RS_acat(rs, "H5VL_GROUP_UNMOUNT"); + break; + case H5VL_GROUP_FLUSH: H5RS_acat(rs, "H5VL_GROUP_FLUSH"); break; @@ -3164,9 +3190,9 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) } /* end block */ break; - case 'k': /* H5VL_link_create_type_t */ + case 'k': /* H5VL_link_create_t */ { - H5VL_link_create_type_t create = (H5VL_link_create_type_t)HDva_arg(ap, int); + H5VL_link_create_t create = (H5VL_link_create_t)HDva_arg(ap, int); switch (create) { case H5VL_LINK_CREATE_HARD: @@ -3334,22 +3360,14 @@ H5_trace_args(H5RS_str_t *rs, const char *type, va_list ap) H5VL_request_specific_t specific = (H5VL_request_specific_t)HDva_arg(ap, int); switch (specific) { - case H5VL_REQUEST_WAITANY: - H5RS_acat(rs, "H5VL_REQUEST_WAITANY"); - break; - - case H5VL_REQUEST_WAITSOME: - H5RS_acat(rs, "H5VL_REQUEST_WAITSOME"); - break; - - case H5VL_REQUEST_WAITALL: - H5RS_acat(rs, "H5VL_REQUEST_WAITALL"); - break; - case H5VL_REQUEST_GET_ERR_STACK: H5RS_acat(rs, "H5VL_REQUEST_GET_ERR_STACK"); break; + case H5VL_REQUEST_GET_EXEC_TIME: + H5RS_acat(rs, "H5VL_REQUEST_GET_EXEC_TIME"); + break; + default: H5RS_asprintf_cat(rs, "%ld", (long)specific); break; diff --git a/src/H5win32defs.h b/src/H5win32defs.h index 030b65b..44cf50c 100644 --- a/src/H5win32defs.h +++ b/src/H5win32defs.h @@ -80,7 +80,7 @@ struct timezone { #define HDstrtok_r(X, Y, Z) strtok_s(X, Y, Z) #define HDtzset() _tzset() #define HDunlink(S) _unlink(S) -#define HDunsetenv(N, V, O) Wsetenv(N, "", 1) +#define HDunsetenv(N) Wsetenv(N, "", 1) #define HDwrite(F, M, Z) _write(F, M, Z) #ifndef H5_HAVE_MINGW diff --git a/src/Makefile.am b/src/Makefile.am index 37ff850..ae058f4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -108,11 +108,11 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5lib_settings.c H5system.c \ H5Torder.c H5Tref.c H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvisit.c \ H5Tvlen.c \ H5TS.c \ - H5VL.c H5VLcallback.c H5VLint.c H5VLnative.c \ + H5VL.c H5VLcallback.c H5VLdyn_ops.c H5VLint.c H5VLnative.c \ H5VLnative_attr.c H5VLnative_blob.c H5VLnative_dataset.c \ H5VLnative_datatype.c H5VLnative_file.c H5VLnative_group.c \ H5VLnative_link.c H5VLnative_introspect.c H5VLnative_object.c \ - H5VLnative_token.c H5VLpassthru.c \ + H5VLnative_token.c H5VLpassthru.c H5VLtest.c \ H5VM.c H5WB.c H5Z.c \ H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zscaleoffset.c \ H5Zszip.c H5Ztrans.c @@ -160,7 +160,7 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers H5Zpublic.h # Public component author headers -include_HEADERS += H5FDdevelop.h H5Idevelop.h H5Ldevelop.h \ +include_HEADERS += H5ESdevelop.h H5FDdevelop.h H5Idevelop.h H5Ldevelop.h \ H5Tdevelop.h H5TSdevelop.h H5Zdevelop.h # install libhdf5.settings in lib directory diff --git a/src/hdf5.h b/src/hdf5.h index b4ece16..9236f2c 100644 --- a/src/hdf5.h +++ b/src/hdf5.h @@ -42,6 +42,7 @@ #include "H5Zpublic.h" /* Data filters */ /* Plugin/component developer headers */ +#include "H5ESdevelop.h" /* Event Sets */ #include "H5FDdevelop.h" /* File drivers */ #include "H5Idevelop.h" /* ID management */ #include "H5Ldevelop.h" /* Links */ @@ -52,6 +53,7 @@ /* Virtual object layer (VOL) connector developer support */ #include "H5VLconnector.h" /* VOL connector author routines */ #include "H5VLconnector_passthru.h" /* Pass-through VOL connector author routines */ +#include "H5VLnative.h" /* Native VOL connector macros, for VOL connector authors */ /* Predefined file drivers */ #include "H5FDcore.h" /* Files stored entirely in memory */ diff --git a/test/CMakeTests.cmake b/test/CMakeTests.cmake index 17931cf..bb5356d 100644 --- a/test/CMakeTests.cmake +++ b/test/CMakeTests.cmake @@ -402,6 +402,8 @@ set (test_CLEANFILES mirror_rw/* mirror_wo/* event_set_*.h5 + h5s_block.h5 + h5s_plist.h5 ) # Remove any output file left over from previous test run @@ -647,10 +649,10 @@ set_tests_properties (H5TEST-tcheck_version-minor PROPERTIES WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST WILL_FAIL "true" ) +# release + 1 should pass add_test (NAME H5TEST-tcheck_version-release COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:tcheck_version> "-tr") set_tests_properties (H5TEST-tcheck_version-release PROPERTIES WORKING_DIRECTORY ${HDF5_TEST_BINARY_DIR}/H5TEST - WILL_FAIL "true" ) ############################################################################## diff --git a/test/Makefile.am b/test/Makefile.am index 6df1653..87b2925 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -216,7 +216,7 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse zero_chunk.h5 chunk_single.h5 swmr_non_latest.h5 \ earray_hdr_fd.h5 farray_hdr_fd.h5 bt2_hdr_fd.h5 \ storage_size.h5 dls_01_strings.h5 power2up.h5 version_bounds.h5 \ - alloc_0sized.h5 \ + alloc_0sized.h5 h5s_block.h5 h5s_plist.h5 \ extend.h5 istore.h5 extlinks*.h5 frspace.h5 links*.h5 \ sys_file1 tfile[1-7].h5 th5s[1-4].h5 lheap.h5 fheap.h5 ohdr.h5 \ stab.h5 extern_[1-5].h5 extern_[1-4][rw].raw gheap[0-4].h5 \ diff --git a/test/ShellTests.cmake b/test/ShellTests.cmake index 812121e..9614152 100644 --- a/test/ShellTests.cmake +++ b/test/ShellTests.cmake @@ -19,7 +19,8 @@ if (UNIX) find_program (SH_PROGRAM bash) if (SH_PROGRAM) - + set (srcdir ${HDF5_TEST_SOURCE_DIR}) + set (bindir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) ############################################################################## # configure scripts to test dir ############################################################################## @@ -33,13 +34,8 @@ if (UNIX) ############################################################################## # copy test programs to test dir ############################################################################## - add_custom_command ( - TARGET swmr_check_compat_vfd - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_check_compat_vfd>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_check_compat_vfd" - ) - + #shell script creates dir + #file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/H5TEST/swmr_test") add_custom_command ( TARGET swmr_check_compat_vfd POST_BUILD @@ -47,118 +43,12 @@ if (UNIX) ARGS -E copy_if_different "${HDF5_SOURCE_DIR}/bin/output_filter.sh" "${HDF5_TEST_BINARY_DIR}/H5TEST/bin/output_filter.sh" ) - file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/H5TEST/flushrefresh_test") - add_custom_command ( - TARGET flushrefresh - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:flushrefresh>" "${HDF5_TEST_BINARY_DIR}/H5TEST/flushrefresh" - ) - #shell script creates dir #file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/H5TEST/usecases_test") - add_custom_command ( - TARGET use_append_mchunks - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:use_append_mchunks>" "${HDF5_TEST_BINARY_DIR}/H5TEST/use_append_mchunks" - ) - add_custom_command ( - TARGET use_disable_mdc_flushes - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:use_disable_mdc_flushes>" "${HDF5_TEST_BINARY_DIR}/H5TEST/use_disable_mdc_flushes" - ) - add_custom_command ( - TARGET twriteorder - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:twriteorder>" "${HDF5_TEST_BINARY_DIR}/H5TEST/twriteorder" - ) - add_custom_command ( - TARGET use_append_chunk - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:use_append_chunk>" "${HDF5_TEST_BINARY_DIR}/H5TEST/use_append_chunk" - ) file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/H5TEST/swmr_test") - add_custom_command ( - TARGET swmr_generator - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_generator>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_generator" - ) - add_custom_command ( - TARGET swmr_start_write - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_start_write>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_start_write" - ) - add_custom_command ( - TARGET swmr_reader - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_reader>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_reader" - ) - add_custom_command ( - TARGET swmr_writer - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_writer>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_writer" - ) - add_custom_command ( - TARGET swmr_remove_reader - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_remove_reader>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_remove_reader" - ) - add_custom_command ( - TARGET swmr_remove_writer - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_remove_writer>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_remove_writer" - ) - add_custom_command ( - TARGET swmr_addrem_writer - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_addrem_writer>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_addrem_writer" - ) - add_custom_command ( - TARGET swmr_sparse_reader - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_sparse_reader>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_sparse_reader" - ) - add_custom_command ( - TARGET swmr_sparse_writer - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:swmr_sparse_writer>" "${HDF5_TEST_BINARY_DIR}/H5TEST/swmr_test/swmr_sparse_writer" - ) file (MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/H5TEST/vds_swmr_test") - add_custom_command ( - TARGET vds_swmr_gen - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:vds_swmr_gen>" "${HDF5_TEST_BINARY_DIR}/H5TEST/vds_swmr_gen" - ) - add_custom_command ( - TARGET vds_swmr_writer - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:vds_swmr_writer>" "${HDF5_TEST_BINARY_DIR}/H5TEST/vds_swmr_writer" - ) - add_custom_command ( - TARGET vds_swmr_reader - POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS -E copy_if_different "$<TARGET_FILE:vds_swmr_reader>" "${HDF5_TEST_BINARY_DIR}/H5TEST/vds_swmr_reader" - ) - - ############################################################################## ############################################################################## diff --git a/test/big.c b/test/big.c index 36fb27d..6f8ce67 100644 --- a/test/big.c +++ b/test/big.c @@ -56,8 +56,8 @@ #define DNAME "big.data" #define WRT_N 50 -#define WRT_SIZE 4 * 1024 -#define FAMILY_SIZE 1024 * 1024 * 1024 +#define WRT_SIZE (4 * 1024) +#define FAMILY_SIZE (1024 * 1024 * 1024) #define GB (HDoff_t)0x40000000L @@ -277,7 +277,7 @@ error: * 'name' in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static int enough_room(hid_t fapl) { @@ -319,7 +319,7 @@ done: return ret_value; } -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: writer diff --git a/test/cache.c b/test/cache.c index 6ded559..6989564 100644 --- a/test/cache.c +++ b/test/cache.c @@ -1046,7 +1046,7 @@ smoke_check_5(int express_test, unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (2 * 1024 * 1024), - /* double min_clean_fraction = */ 0.1f, + /* double min_clean_fraction = */ 0.1, /* size_t max_size = */ (32 * 1024 * 1025), /* size_t min_size = */ (512 * 1024), @@ -1055,23 +1055,23 @@ smoke_check_5(int express_test, unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.9f, + /* double decrement = */ 0.9, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -1079,7 +1079,7 @@ smoke_check_5(int express_test, unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.5f + /* double empty_reserve = */ 0.5 }; if (paged) @@ -1278,7 +1278,7 @@ smoke_check_6(int express_test, unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (2 * 1024 * 1024), - /* double min_clean_fraction = */ 0.1f, + /* double min_clean_fraction = */ 0.1, /* size_t max_size = */ (32 * 1024 * 1025), /* size_t min_size = */ (512 * 1024), @@ -1287,23 +1287,23 @@ smoke_check_6(int express_test, unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.9f, + /* double decrement = */ 0.9, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -1311,7 +1311,7 @@ smoke_check_6(int express_test, unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f + /* double empty_reserve = */ 0.05 }; if (paged) @@ -1510,7 +1510,7 @@ smoke_check_7(int express_test, unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (2 * 1024 * 1024), - /* double min_clean_fraction = */ 0.1f, + /* double min_clean_fraction = */ 0.1, /* size_t max_size = */ (32 * 1024 * 1025), /* size_t min_size = */ (512 * 1024), @@ -1519,24 +1519,24 @@ smoke_check_7(int express_test, unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (8 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.9f, + /* double decrement = */ 0.9, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -1544,7 +1544,7 @@ smoke_check_7(int express_test, unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.1f + /* double empty_reserve = */ 0.1 }; if (paged) @@ -1743,7 +1743,7 @@ smoke_check_8(int express_test, unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (2 * 1024 * 1024), - /* double min_clean_fraction = */ 0.1f, + /* double min_clean_fraction = */ 0.1, /* size_t max_size = */ (32 * 1024 * 1025), /* size_t min_size = */ (512 * 1024), @@ -1752,24 +1752,24 @@ smoke_check_8(int express_test, unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.9f, + /* double decrement = */ 0.9, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -1777,7 +1777,7 @@ smoke_check_8(int express_test, unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.1f + /* double empty_reserve = */ 0.1 }; if (paged) @@ -17004,7 +17004,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (512 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (14 * 1024 * 1024), /* size_t min_size = */ (512 * 1024), @@ -17013,23 +17013,23 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.1f, + /* double decrement = */ 0.1, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -17037,7 +17037,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f}; + /* double empty_reserve = */ 0.05}; if (paged) TESTING("automatic cache resizing (paged aggregation)") @@ -17361,7 +17361,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1000 * 1000 + 10; - auto_size_ctl.min_clean_fraction = 0.1f; + auto_size_ctl.min_clean_fraction = 0.1; auto_size_ctl.max_size = 8 * 1000 * 1000; auto_size_ctl.min_size = 500 * 1000; @@ -17370,22 +17370,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1000 * 1000); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1000 * 1000); @@ -17393,7 +17393,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -17676,7 +17676,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -17685,22 +17685,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 4.0f; + auto_size_ctl.increment = 4.0; auto_size_ctl.apply_max_increment = FALSE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.25f; + auto_size_ctl.decrement = 0.25; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -17708,7 +17708,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -17852,7 +17852,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -17861,22 +17861,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -17884,7 +17884,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -18220,7 +18220,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -18229,22 +18229,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -18252,7 +18252,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -18702,7 +18702,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -18711,22 +18711,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -18734,7 +18734,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.5f; /* for ease of testing */ + auto_size_ctl.empty_reserve = 0.5; /* for ease of testing */ result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -19079,7 +19079,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -19088,16 +19088,16 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; @@ -19106,7 +19106,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) */ auto_size_ctl.upper_hr_threshold = 0.999; /* for ease of testing */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -19114,7 +19114,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 1; /* for ease of testing */ auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -19326,7 +19326,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1000 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1000 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -19335,22 +19335,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 0.999f; /* for ease of testing */ + auto_size_ctl.upper_hr_threshold = 0.999; /* for ease of testing */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1000 * 1024); @@ -19358,7 +19358,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 1; /* for ease of testing */ auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.5f; /* for ease of testing */ + auto_size_ctl.empty_reserve = 0.5; /* for ease of testing */ result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -19868,7 +19868,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 64 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 1024 * 1024; auto_size_ctl.min_size = 5 * 1024; @@ -19877,22 +19877,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (32 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - auto_size_ctl.flash_multiple = 1.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 1.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 0.999f; /* for ease of testing */ + auto_size_ctl.upper_hr_threshold = 0.999; /* for ease of testing */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1000 * 1024); @@ -19900,7 +19900,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 1; /* for ease of testing */ auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.5f; /* for ease of testing */ + auto_size_ctl.empty_reserve = 0.5; /* for ease of testing */ result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -20602,7 +20602,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 20 * 1024; auto_size_ctl.min_size = 4 * 1024; @@ -20611,22 +20611,22 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.4f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.4; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 0.999f; /* for ease of testing */ + auto_size_ctl.upper_hr_threshold = 0.999; /* for ease of testing */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (2 * 1024); @@ -20634,7 +20634,7 @@ check_auto_cache_resize(hbool_t cork_ageout, unsigned paged) auto_size_ctl.epochs_before_eviction = 1; /* for ease of testing */ auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.5f; /* for ease of testing */ + auto_size_ctl.empty_reserve = 0.5; /* for ease of testing */ result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); if (result != SUCCEED) { @@ -20859,7 +20859,7 @@ check_auto_cache_resize_disable(unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (512 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (14 * 1024 * 1024), /* size_t min_size = */ (512 * 1024), @@ -20868,23 +20868,23 @@ check_auto_cache_resize_disable(unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 1.0f, - /* double flash_threshold = */ 0.25f, + /* double flash_multiple = */ 1.0, + /* double flash_threshold = */ 0.25, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.1f, + /* double decrement = */ 0.1, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -20892,7 +20892,7 @@ check_auto_cache_resize_disable(unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f}; + /* double empty_reserve = */ 0.05}; if (paged) TESTING("automatic cache resize disable (paged aggregation)") @@ -20964,7 +20964,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -20973,22 +20973,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 1.0f; /* disable size increases */ + auto_size_ctl.increment = 1.0; /* disable size increases */ auto_size_ctl.apply_max_increment = FALSE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -20996,7 +20996,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21116,7 +21116,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21125,21 +21125,21 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.0f; /* disable size increases */ + auto_size_ctl.lower_hr_threshold = 0.0; /* disable size increases */ - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = FALSE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.upper_hr_threshold = 0.995; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -21147,7 +21147,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21267,7 +21267,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21276,22 +21276,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = FALSE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -21299,7 +21299,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21418,7 +21418,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21427,22 +21427,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 1.0f; /* disable size decreases */ + auto_size_ctl.decrement = 1.0; /* disable size decreases */ auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -21450,7 +21450,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21572,7 +21572,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21581,22 +21581,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 1.0f; /* disable size decreases */ + auto_size_ctl.upper_hr_threshold = 1.0; /* disable size decreases */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -21604,7 +21604,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21722,7 +21722,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21731,22 +21731,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__off; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -21754,7 +21754,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -21874,7 +21874,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -21883,22 +21883,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = 0; /* disable decrement */ @@ -21906,7 +21906,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 1; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22091,7 +22091,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -22100,22 +22100,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22123,7 +22123,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 1; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 1.0f; /* disable decrement */ + auto_size_ctl.empty_reserve = 1.0; /* disable decrement */ result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22315,7 +22315,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -22324,22 +22324,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 1.0f; + auto_size_ctl.upper_hr_threshold = 1.0; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22347,7 +22347,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 1; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22541,7 +22541,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 2 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -22550,22 +22550,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.0f; /* disable size increases */ + auto_size_ctl.lower_hr_threshold = 0.0; /* disable size increases */ - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 1.0f; /* disable size decreases */ + auto_size_ctl.upper_hr_threshold = 1.0; /* disable size decreases */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22573,7 +22573,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22661,7 +22661,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.25f; + auto_size_ctl.min_clean_fraction = 0.25; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -22670,22 +22670,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 1.0f; /* disable size increment */ + auto_size_ctl.increment = 1.0; /* disable size increment */ auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 1.0f; /* disable size decrement */ + auto_size_ctl.decrement = 1.0; /* disable size decrement */ auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22693,7 +22693,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22781,7 +22781,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = FALSE; auto_size_ctl.initial_size = 2 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 6 * 1024 * 1024; /* no resize */ auto_size_ctl.min_size = 6 * 1024 * 1024; /* no resize */ @@ -22790,22 +22790,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22813,7 +22813,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -22901,7 +22901,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.25f; + auto_size_ctl.min_clean_fraction = 0.25; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -22910,22 +22910,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 1.0f; /* disable size increment */ + auto_size_ctl.increment = 1.0; /* disable size increment */ auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 1.0f; /* disable size decrement */ + auto_size_ctl.upper_hr_threshold = 1.0; /* disable size decrement */ - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -22933,7 +22933,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23021,7 +23021,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -23030,22 +23030,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.0f; /* disable size increment */ + auto_size_ctl.lower_hr_threshold = 0.0; /* disable size increment */ - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 1.0f; /* disable size decrement */ + auto_size_ctl.decrement = 1.0; /* disable size decrement */ auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23053,7 +23053,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23141,7 +23141,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 4 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 16 * 1024 * 1024; auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -23150,22 +23150,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__off; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23173,7 +23173,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23288,7 +23288,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 64 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 256 * 1024; auto_size_ctl.min_size = 32 * 1024; @@ -23297,22 +23297,22 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__threshold; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (2 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 1.0f; - auto_size_ctl.flash_threshold = 0.25f; + auto_size_ctl.flash_multiple = 1.0; + auto_size_ctl.flash_threshold = 0.25; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = TRUE; auto_size_ctl.max_decrement = (1 * 1024); @@ -23320,7 +23320,7 @@ check_auto_cache_resize_disable(unsigned paged) auto_size_ctl.epochs_before_eviction = 3; auto_size_ctl.apply_empty_reserve = TRUE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23458,7 +23458,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (512 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (14 * 1024 * 1024), /* size_t min_size = */ (512 * 1024), @@ -23467,23 +23467,23 @@ check_auto_cache_resize_epoch_markers(unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.1f, + /* double decrement = */ 0.1, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -23491,7 +23491,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f}; + /* double empty_reserve = */ 0.05}; if (paged) TESTING("automatic cache resize epoch marker management (paged aggr)") @@ -23545,7 +23545,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -23554,22 +23554,22 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23577,7 +23577,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.epochs_before_eviction = 10; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23709,7 +23709,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -23718,22 +23718,22 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23741,7 +23741,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.epochs_before_eviction = 1; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23827,7 +23827,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -23836,22 +23836,22 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23859,7 +23859,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.epochs_before_eviction = 1; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -23905,7 +23905,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -23914,22 +23914,22 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -23937,7 +23937,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.epochs_before_eviction = 10; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -24014,7 +24014,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.set_initial_size = TRUE; auto_size_ctl.initial_size = 8 * 1024 * 1024; - auto_size_ctl.min_clean_fraction = 0.5f; + auto_size_ctl.min_clean_fraction = 0.5; auto_size_ctl.max_size = 8 * 1024 * 1024; auto_size_ctl.min_size = 512 * 1024; @@ -24023,22 +24023,22 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.incr_mode = H5C_incr__off; - auto_size_ctl.lower_hr_threshold = 0.75f; + auto_size_ctl.lower_hr_threshold = 0.75; - auto_size_ctl.increment = 2.0f; + auto_size_ctl.increment = 2.0; auto_size_ctl.apply_max_increment = TRUE; auto_size_ctl.max_increment = (4 * 1024 * 1024); auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - auto_size_ctl.flash_multiple = 2.0f; - auto_size_ctl.flash_threshold = 0.5f; + auto_size_ctl.flash_multiple = 2.0; + auto_size_ctl.flash_threshold = 0.5; auto_size_ctl.decr_mode = H5C_decr__off; - auto_size_ctl.upper_hr_threshold = 0.995f; + auto_size_ctl.upper_hr_threshold = 0.995; - auto_size_ctl.decrement = 0.5f; + auto_size_ctl.decrement = 0.5; auto_size_ctl.apply_max_decrement = FALSE; auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24046,7 +24046,7 @@ check_auto_cache_resize_epoch_markers(unsigned paged) auto_size_ctl.epochs_before_eviction = 10; auto_size_ctl.apply_empty_reserve = FALSE; - auto_size_ctl.empty_reserve = 0.05f; + auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &auto_size_ctl); @@ -24146,7 +24146,7 @@ check_auto_cache_resize_input_errs(unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (512 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (16 * 1024 * 1024), /* size_t min_size = */ (512 * 1024), @@ -24155,23 +24155,23 @@ check_auto_cache_resize_input_errs(unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.1f, + /* double decrement = */ 0.1, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -24179,7 +24179,7 @@ check_auto_cache_resize_input_errs(unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f}; + /* double empty_reserve = */ 0.05}; H5C_auto_size_ctl_t invalid_auto_size_ctl; H5C_auto_size_ctl_t test_auto_size_ctl; @@ -24249,7 +24249,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24258,22 +24258,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.7f; + invalid_auto_size_ctl.lower_hr_threshold = 0.7; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24281,7 +24281,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(NULL, &invalid_auto_size_ctl); @@ -24318,7 +24318,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24327,22 +24327,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.7f; + invalid_auto_size_ctl.lower_hr_threshold = 0.7; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24350,7 +24350,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24388,7 +24388,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.initial_size = 16 * 1024 * 1024 + 1; /* INVALID */ - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24397,22 +24397,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24420,7 +24420,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24456,7 +24456,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.initial_size = 1 * 1024 * 1024 - 1; /* INVALID */ - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24465,22 +24465,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24488,7 +24488,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24525,7 +24525,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 1.00001f; /* INVALID */ + invalid_auto_size_ctl.min_clean_fraction = 1.00001; /* INVALID */ invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24534,22 +24534,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24557,7 +24557,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24592,7 +24592,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = -0.00001f; /* INVALID */ + invalid_auto_size_ctl.min_clean_fraction = -0.00001; /* INVALID */ invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24601,22 +24601,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24624,7 +24624,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24661,7 +24661,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = H5C__MAX_MAX_CACHE_SIZE + 1; /* INVALID */ @@ -24671,22 +24671,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24694,7 +24694,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24729,7 +24729,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 1 * 1024 * 1024; /* INVALID */ invalid_auto_size_ctl.min_size = 1 * 1024 * 1024 + 1; /*PAIR */ @@ -24738,22 +24738,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24761,7 +24761,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24796,7 +24796,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = H5C__MIN_MAX_CACHE_SIZE - 1; @@ -24805,22 +24805,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24828,7 +24828,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24865,7 +24865,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24875,22 +24875,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24898,7 +24898,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -24933,7 +24933,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -24943,22 +24943,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -24966,7 +24966,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25003,7 +25003,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25012,22 +25012,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = (enum H5C_cache_incr_mode) - 1; /* INVALID */ - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25035,7 +25035,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25070,7 +25070,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25079,22 +25079,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = (enum H5C_cache_incr_mode)2; /* INVALID */ - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25102,7 +25102,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25139,7 +25139,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25148,22 +25148,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.7f; + invalid_auto_size_ctl.lower_hr_threshold = 0.7; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 1.01f; /* INVALID */ + invalid_auto_size_ctl.upper_hr_threshold = 1.01; /* INVALID */ - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25171,7 +25171,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25206,7 +25206,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25215,22 +25215,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.8f; /* INVALID */ + invalid_auto_size_ctl.lower_hr_threshold = 0.8; /* INVALID */ - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.7f; /* INVALID */ + invalid_auto_size_ctl.upper_hr_threshold = 0.7; /* INVALID */ - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25238,7 +25238,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25273,7 +25273,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.5f; + invalid_auto_size_ctl.min_clean_fraction = 0.5; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25282,22 +25282,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = -0.0001f; /* INVALID */ + invalid_auto_size_ctl.lower_hr_threshold = -0.0001; /* INVALID */ - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25305,7 +25305,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25342,7 +25342,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25351,22 +25351,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 0.99999f; /* INVALID */ + invalid_auto_size_ctl.increment = 0.99999; /* INVALID */ invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.5f; + invalid_auto_size_ctl.decrement = 0.5; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25374,7 +25374,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25411,7 +25411,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25420,22 +25420,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = (enum H5C_cache_flash_incr_mode) - 1; /* INVALID */ - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25443,7 +25443,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25480,7 +25480,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25489,22 +25489,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - invalid_auto_size_ctl.flash_multiple = 0.09f; /* INVALID */ - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 0.09; /* INVALID */ + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25512,7 +25512,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25547,7 +25547,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25556,22 +25556,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - invalid_auto_size_ctl.flash_multiple = 10.01f; /* INVALID */ - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 10.01; /* INVALID */ + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25579,7 +25579,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25616,7 +25616,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25625,22 +25625,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - invalid_auto_size_ctl.flash_multiple = 1.0f; - invalid_auto_size_ctl.flash_threshold = 0.09f; /* INVALID */ + invalid_auto_size_ctl.flash_multiple = 1.0; + invalid_auto_size_ctl.flash_threshold = 0.09; /* INVALID */ invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25648,7 +25648,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25683,7 +25683,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25692,22 +25692,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__add_space; - invalid_auto_size_ctl.flash_multiple = 1.0f; - invalid_auto_size_ctl.flash_threshold = 1.001f; /* INVALID */ + invalid_auto_size_ctl.flash_multiple = 1.0; + invalid_auto_size_ctl.flash_threshold = 1.001; /* INVALID */ invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25715,7 +25715,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25752,7 +25752,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25761,22 +25761,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = (enum H5C_cache_decr_mode) - 1; /* INVALID */ - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25784,7 +25784,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25819,7 +25819,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25828,22 +25828,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = (enum H5C_cache_decr_mode)4; /* INVALID */ - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25851,7 +25851,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25888,7 +25888,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25897,22 +25897,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 1.000001f; /* INVALID */ + invalid_auto_size_ctl.decrement = 1.000001; /* INVALID */ invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25920,7 +25920,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -25955,7 +25955,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -25964,22 +25964,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = -0.000001f; /* INVALID */ + invalid_auto_size_ctl.decrement = -0.000001; /* INVALID */ invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -25987,7 +25987,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -26024,7 +26024,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -26033,22 +26033,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__age_out; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -26056,7 +26056,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 0; /* INVALID */ invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -26091,7 +26091,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -26100,22 +26100,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -26123,7 +26123,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = H5C__MAX_EPOCH_MARKERS + 1; /* INVALID */ invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -26160,7 +26160,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -26169,22 +26169,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__age_out; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -26192,7 +26192,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = 3; invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = -0.0000001f; /* INVALID */ + invalid_auto_size_ctl.empty_reserve = -0.0000001; /* INVALID */ result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -26227,7 +26227,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.set_initial_size = TRUE; invalid_auto_size_ctl.initial_size = 4 * 1024 * 1024; - invalid_auto_size_ctl.min_clean_fraction = 0.1f; + invalid_auto_size_ctl.min_clean_fraction = 0.1; invalid_auto_size_ctl.max_size = 16 * 1024 * 1024; invalid_auto_size_ctl.min_size = 1 * 1024 * 1024; @@ -26236,22 +26236,22 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.incr_mode = H5C_incr__threshold; - invalid_auto_size_ctl.lower_hr_threshold = 0.75f; + invalid_auto_size_ctl.lower_hr_threshold = 0.75; - invalid_auto_size_ctl.increment = 2.0f; + invalid_auto_size_ctl.increment = 2.0; invalid_auto_size_ctl.apply_max_increment = TRUE; invalid_auto_size_ctl.max_increment = (2 * 1024 * 1024); invalid_auto_size_ctl.flash_incr_mode = H5C_flash_incr__off; - invalid_auto_size_ctl.flash_multiple = 2.0f; - invalid_auto_size_ctl.flash_threshold = 0.5f; + invalid_auto_size_ctl.flash_multiple = 2.0; + invalid_auto_size_ctl.flash_threshold = 0.5; invalid_auto_size_ctl.decr_mode = H5C_decr__age_out_with_threshold; - invalid_auto_size_ctl.upper_hr_threshold = 0.999f; + invalid_auto_size_ctl.upper_hr_threshold = 0.999; - invalid_auto_size_ctl.decrement = 0.9f; + invalid_auto_size_ctl.decrement = 0.9; invalid_auto_size_ctl.apply_max_decrement = TRUE; invalid_auto_size_ctl.max_decrement = (1 * 1024 * 1024); @@ -26259,7 +26259,7 @@ check_auto_cache_resize_input_errs(unsigned paged) invalid_auto_size_ctl.epochs_before_eviction = H5C__MAX_EPOCH_MARKERS + 1; /* INVALID */ invalid_auto_size_ctl.apply_empty_reserve = TRUE; - invalid_auto_size_ctl.empty_reserve = 0.05f; + invalid_auto_size_ctl.empty_reserve = 0.05; result = H5C_set_cache_auto_resize_config(cache_ptr, &invalid_auto_size_ctl); @@ -26387,7 +26387,7 @@ check_auto_cache_resize_aux_fcns(unsigned paged) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (1 * 1024 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (16 * 1024 * 1025), /* size_t min_size = */ (512 * 1024), @@ -26396,23 +26396,23 @@ check_auto_cache_resize_aux_fcns(unsigned paged) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__off, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__off, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.9f, + /* double decrement = */ 0.9, /* hbool_t apply_max_decrement = */ TRUE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -26420,7 +26420,7 @@ check_auto_cache_resize_aux_fcns(unsigned paged) /* int32_t epochs_before_eviction = */ 3, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.5f + /* double empty_reserve = */ 0.5 }; if (paged) @@ -34313,7 +34313,7 @@ cedds__H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t *file_ptr) /* hbool_t set_initial_size = */ TRUE, /* size_t initial_size = */ (2 * 1024 * 1024), - /* double min_clean_fraction = */ 0.5f, + /* double min_clean_fraction = */ 0.5, /* size_t max_size = */ (8 * 1024 * 1024), /* size_t min_size = */ (1 * 1024 * 1024), @@ -34322,23 +34322,23 @@ cedds__H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t *file_ptr) /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, - /* double lower_hr_threshold = */ 0.75f, + /* double lower_hr_threshold = */ 0.75, - /* double increment = */ 2.0f, + /* double increment = */ 2.0, /* hbool_t apply_max_increment = */ TRUE, /* size_t max_increment = */ (4 * 1024 * 1024), /* enum H5C_cache_flash_incr_mode */ /* flash_incr_mode = */ H5C_flash_incr__off, - /* double flash_multiple = */ 2.0f, - /* double flash_threshold = */ 0.5f, + /* double flash_multiple = */ 2.0, + /* double flash_threshold = */ 0.5, /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out, - /* double upper_hr_threshold = */ 0.995f, + /* double upper_hr_threshold = */ 0.995, - /* double decrement = */ 0.5f, + /* double decrement = */ 0.5, /* hbool_t apply_max_decrement = */ FALSE, /* size_t max_decrement = */ (1 * 1024 * 1024), @@ -34346,7 +34346,7 @@ cedds__H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t *file_ptr) /* int32_t epochs_before_eviction = */ 1, /* hbool_t apply_empty_reserve = */ TRUE, - /* double empty_reserve = */ 0.05f}; + /* double empty_reserve = */ 0.05}; if (pass) { diff --git a/test/chunk_info.c b/test/chunk_info.c index 7104941..a1c4160 100644 --- a/test/chunk_info.c +++ b/test/chunk_info.c @@ -482,10 +482,10 @@ test_get_chunk_info_highest_v18(hid_t fapl) unsigned flt_msk = 0; /* Filter mask */ unsigned read_flt_msk = 0; /* Filter mask after direct read */ int fillvalue = -1; /* Fill value */ - int aggression = 9; /* Compression aggression setting */ hsize_t offset[2] = {0, 0}; /* Offset coordinates of a chunk */ #ifdef H5_HAVE_FILTER_DEFLATE - const Bytef *z_src = (const Bytef *)(direct_buf); + int aggression = 9; /* Compression aggression setting */ + const Bytef *z_src = (const Bytef *)(direct_buf); Bytef * z_dst; /* Destination buffer */ uLongf z_dst_nbytes = (uLongf)DEFLATE_SIZE_ADJUST(CHK_SIZE); uLong z_src_nbytes = (uLong)CHK_SIZE; @@ -568,7 +568,8 @@ test_get_chunk_info_highest_v18(hid_t fapl) } #else /* Allocate input (non-compressed) buffer */ - inbuf = HDcalloc(1, CHK_SIZE); + if (NULL == (inbuf = HDcalloc(1, CHK_SIZE))) + TEST_ERROR HDmemcpy(inbuf, direct_buf, CHK_SIZE); #endif /* end H5_HAVE_FILTER_DEFLATE */ @@ -1490,21 +1491,24 @@ typedef struct chunk_iter_info_t { uint32_t nbytes; } chunk_iter_info_t; +typedef struct chunk_iter_udata_t { + chunk_iter_info_t *chunk_info; + int last_index; +} chunk_iter_udata_t; + static int iter_cb(const hsize_t *offset, uint32_t filter_mask, haddr_t addr, uint32_t nbytes, void *op_data) { - chunk_iter_info_t **chunk_info = (chunk_iter_info_t **)op_data; + chunk_iter_udata_t *cidata = (chunk_iter_udata_t *)op_data; + int idx = cidata->last_index + 1; - (*chunk_info)->offset[0] = offset[0]; - (*chunk_info)->offset[1] = offset[1]; - (*chunk_info)->filter_mask = filter_mask; - (*chunk_info)->addr = addr; - (*chunk_info)->nbytes = nbytes; + cidata->chunk_info[idx].offset[0] = offset[0]; + cidata->chunk_info[idx].offset[1] = offset[1]; + cidata->chunk_info[idx].filter_mask = filter_mask; + cidata->chunk_info[idx].addr = addr; + cidata->chunk_info[idx].nbytes = nbytes; - /* printf("offset: [%lld, %lld], addr: %ld, size: %d, filter mask: %d\n", offset[0], offset[1], addr, - * nbytes, filter_mask); */ - - *chunk_info += 1; + cidata->last_index++; return H5_ITER_CONT; } @@ -1564,8 +1568,9 @@ test_basic_query(hid_t fapl) haddr_t addr = 0; /* Address of an allocated/written chunk */ hsize_t chk_index = 0; /* Index of a chunk */ hsize_t ii, jj; /* Array indices */ - chunk_iter_info_t chunk_infos[2]; /* chunk infos filled up by iterator */ - chunk_iter_info_t *cptr; /* pointer to array of chunks */ + chunk_iter_info_t chunk_infos[2]; /* Chunk infos filled up by iterator */ + chunk_iter_info_t *cptr; /* Pointer to array of chunks */ + chunk_iter_udata_t udata; /* udata for iteration */ herr_t ret; /* Temporary returned value for verifying failure */ TESTING("basic operations"); @@ -1674,12 +1679,13 @@ test_basic_query(hid_t fapl) if (verify_empty_chunk_info(dset, offset) == FAIL) FAIL_PUTS_ERROR("Verification of H5Dget_chunk_info_by_coord on empty chunk failed\n"); - /* iterate over all chunks */ - cptr = &(chunk_infos[0]); - if (H5Dchunk_iter(dset, &iter_cb, &cptr) < 0) + /* Iterate over all chunks */ + udata.chunk_info = chunk_infos; + udata.last_index = -1; + if (H5Dchunk_iter(dset, H5P_DEFAULT, &iter_cb, &udata) < 0) TEST_ERROR; - VERIFY(cptr, &(chunk_infos[2]), "Iterator did not iterate all chunks"); + VERIFY(udata.last_index, 1, "Iterator did not iterate all chunks"); VERIFY(chunk_infos[0].offset[0], 0, "Offset mismatch"); VERIFY(chunk_infos[0].offset[1], 0, "Offset mismatch"); VERIFY(chunk_infos[0].filter_mask, 0, "Filter mismatch"); @@ -1688,17 +1694,17 @@ test_basic_query(hid_t fapl) VERIFY(chunk_infos[1].offset[0], 1, "Offset mismatch"); VERIFY(chunk_infos[1].offset[1], 1, "Offset mismatch"); - /* iterate and stop after one iteration */ + /* Iterate and stop after one iteration */ cptr = &(chunk_infos[0]); - if (H5Dchunk_iter(dset, &iter_cb_stop, &cptr) < 0) + if (H5Dchunk_iter(dset, H5P_DEFAULT, &iter_cb_stop, &cptr) < 0) TEST_ERROR; VERIFY(cptr, &(chunk_infos[1]), "Verification of halted iterator failed\n"); - /* iterate and fail after one iteration */ + /* Iterate and fail after one iteration */ cptr = &(chunk_infos[0]); H5E_BEGIN_TRY { - ret = H5Dchunk_iter(dset, &iter_cb_fail, &cptr); + ret = H5Dchunk_iter(dset, H5P_DEFAULT, &iter_cb_fail, &cptr); } H5E_END_TRY; if (ret >= 0) diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c index 4c3233d..8777096 100644 --- a/test/cmpd_dset.c +++ b/test/cmpd_dset.c @@ -110,8 +110,8 @@ typedef struct { long long r, s, t; } stype4; -#define NX 100u -#define NY 2000u +#define NX 100U +#define NY 2000U #define PACK_NMEMBS 100 /*------------------------------------------------------------------------- diff --git a/test/cve_2020_10810.h5 b/test/cve_2020_10810.h5 new file mode 100644 index 0000000..5cface3 Binary files /dev/null and b/test/cve_2020_10810.h5 differ diff --git a/test/dsets.c b/test/dsets.c index 3a17575..922f370 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -83,6 +83,8 @@ const char *FILENAME[] = {"dataset", /* 0 */ "power2up", /* 24 */ "version_bounds", /* 25 */ "alloc_0sized", /* 26 */ + "h5s_block", /* 27 */ + "h5s_plist", /* 28 */ NULL}; #define OHMIN_FILENAME_A "ohdr_min_a" @@ -1394,10 +1396,10 @@ test_conv_buffer(hid_t fid) cf->a[j][k][l] = 10 * (j + 1) + l + k; for (j = 0; j < DIM2; j++) - cf->b[j] = 100.0f * (float)(j + 1) + 0.01f * (float)j; + cf->b[j] = 100.0F * (float)(j + 1) + 0.01F * (float)j; for (j = 0; j < DIM3; j++) - cf->c[j] = 100.0f * (float)(j + 1) + 0.02f * (float)j; + cf->c[j] = 100.0F * (float)(j + 1) + 0.02F * (float)j; /* Create data space */ if ((space = H5Screate(H5S_SCALAR)) < 0) @@ -3322,8 +3324,8 @@ test_nbit_float(hid_t file) /* orig_data[] are initialized to be within the range that can be represented by * dataset datatype (no precision loss during datatype conversion) */ - float orig_data[2][5] = {{188384.0f, 19.103516f, -1.0831790e9f, -84.242188f, 5.2045898f}, - {-49140.0f, 2350.25f, -3.2110596e-1f, 6.4998865e-5f, -0.0f}}; + float orig_data[2][5] = {{188384.0F, 19.103516F, -1.0831790e9F, -84.242188F, 5.2045898F}, + {-49140.0F, 2350.25F, -3.2110596e-1F, 6.4998865e-5F, -0.0F}}; float new_data[2][5]; size_t precision, offset; size_t i, j; @@ -11640,7 +11642,7 @@ test_unfiltered_edge_chunks(hid_t fapl) TEST_ERROR /* Add "count" filter */ - if (H5Pset_filter(dcpl, H5Z_FILTER_COUNT, 0u, (size_t)0, NULL) < 0) + if (H5Pset_filter(dcpl, H5Z_FILTER_COUNT, 0U, (size_t)0, NULL) < 0) TEST_ERROR /* Disable filters on partial chunks */ @@ -14971,6 +14973,370 @@ error: } /* end test_object_header_minimization_dcpl() */ /*----------------------------------------------------------------------------- + * Function: test_h5s_block + * + * Purpose: Test the H5S_BLOCK feature. + * + * Return: Success/pass: 0 + * Failure/error: -1 + * + * Programmer: Quincey Koziol + * 3 November 2020 + * + *----------------------------------------------------------------------------- + */ +static herr_t +test_h5s_block(void) +{ + hid_t file_id = H5I_INVALID_HID; /* File ID */ + char filename[FILENAME_BUF_SIZE] = ""; + hid_t dset_id = H5I_INVALID_HID; /* Dataset ID */ + hsize_t dims[1] = {20}; /* Dataset's dataspace size */ + hsize_t start = 2; /* Starting offset of hyperslab selection */ + hsize_t count = 10; /* Count of hyperslab selection */ + hid_t file_space_id = H5I_INVALID_HID; /* File dataspace ID */ + int buf[20]; /* Memory buffer for I/O */ + unsigned u; /* Local index variable */ + herr_t ret; + + TESTING("contiguous memory buffers with H5S_BLOCK"); + + /*********/ + /* SETUP */ + /*********/ + if (NULL == h5_fixname(FILENAME[27], H5P_DEFAULT, filename, sizeof(filename))) + TEST_ERROR + if (H5I_INVALID_HID == (file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))) + FAIL_STACK_ERROR + if ((file_space_id = H5Screate_simple(1, dims, NULL)) < 0) + FAIL_STACK_ERROR + if ((dset_id = H5Dcreate2(file_id, "dset", H5T_NATIVE_INT, file_space_id, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + for (u = 0; u < 20; u++) + buf[u] = (int)u; + + /*********/ + /* TESTS */ + /*********/ + + /* Check error cases */ + H5E_BEGIN_TRY + { + ret = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_BLOCK, H5P_DEFAULT, buf); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + + /* Write the entire dataset */ + if (H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Reset the memory buffer */ + HDmemset(buf, 0, sizeof(buf)); + + /* Read the entire dataset */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < 20; u++) + if (buf[u] != (int)u) + TEST_ERROR + + /* Read a hyperslab from the file to the first 10 elements of the buffer */ + if (H5Sselect_hyperslab(file_space_id, H5S_SELECT_SET, &start, NULL, &count, NULL) < 0) + FAIL_STACK_ERROR + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, file_space_id, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + + /* Verify that reading 0 elements is handled correctly and doesn't modify buffer */ + if (H5Sselect_none(file_space_id) < 0) + FAIL_STACK_ERROR + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, file_space_id, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + + /************/ + /* TEARDOWN */ + /************/ + if (FAIL == H5Sclose(file_space_id)) + FAIL_STACK_ERROR + if (FAIL == H5Dclose(dset_id)) + FAIL_STACK_ERROR + if (FAIL == H5Fclose(file_id)) + FAIL_STACK_ERROR + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Sclose(file_space_id); + H5Dclose(dset_id); + H5Fclose(file_id); + } + H5E_END_TRY; + + return FAIL; +} /* end test_h5s_block() */ + +/*----------------------------------------------------------------------------- + * Function: test_h5s_plist + * + * Purpose: Test the H5S_PLIST feature. + * + * Return: Success/pass: 0 + * Failure/error: -1 + * + * Programmer: Quincey Koziol + * 28 January 2021 + * + *----------------------------------------------------------------------------- + */ +static herr_t +test_h5s_plist(void) +{ + hid_t file_id = H5I_INVALID_HID; /* File ID */ + char filename[FILENAME_BUF_SIZE] = ""; + hid_t dset_id = H5I_INVALID_HID; /* Dataset ID */ + hsize_t dims[1] = {20}; /* Dataset's dataspace size */ + hid_t dxpl_id = H5I_INVALID_HID; /* Dataset xfer property list ID */ + hid_t dxpl_id_copy = H5I_INVALID_HID; /* Copy of dataset xfer property list ID */ + hsize_t start = 2; /* Starting offset of hyperslab selection */ + hsize_t stride = 1; /* Stride of hyperslab selection */ + hsize_t count = 10; /* Count of hyperslab selection */ + hsize_t start2 = 14; /* Starting offset of hyperslab selection */ + hsize_t count2 = 4; /* Count of hyperslab selection */ + hsize_t block = 1; /* Block size of hyperslab selection */ + hid_t file_space_id = H5I_INVALID_HID; /* File dataspace ID */ + int buf[20]; /* Memory buffer for I/O */ + unsigned u; /* Local index variable */ + herr_t ret; + + TESTING("dataset's dataspace selection for I/O in DXPL with H5S_PLIST"); + + /*********/ + /* SETUP */ + /*********/ + if (NULL == h5_fixname(FILENAME[28], H5P_DEFAULT, filename, sizeof(filename))) + TEST_ERROR + if (H5I_INVALID_HID == (file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))) + FAIL_STACK_ERROR + if ((file_space_id = H5Screate_simple(1, dims, NULL)) < 0) + FAIL_STACK_ERROR + if ((dset_id = H5Dcreate2(file_id, "dset", H5T_NATIVE_INT, file_space_id, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + if ((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) + FAIL_STACK_ERROR + + for (u = 0; u < 20; u++) + buf[u] = (int)u; + + /*********/ + /* TESTS */ + /*********/ + + /* Check error cases */ + H5E_BEGIN_TRY + { + /* Bad rank */ + ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id, 0, H5S_SELECT_SET, &start, &stride, &count, + &block); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + H5E_BEGIN_TRY + { + /* Bad selection operator */ + ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_NOOP, &start, &stride, &count, + &block); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + H5E_BEGIN_TRY + { + /* Bad start pointer */ + ret = + H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, NULL, &stride, &count, &block); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + H5E_BEGIN_TRY + { + /* Bad stride value (stride of NULL is OK) */ + stride = 0; + ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, &start, &stride, &count, + &block); + stride = 1; + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + H5E_BEGIN_TRY + { + /* Bad count pointer */ + ret = + H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, &start, &stride, NULL, &block); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + + /* Block pointer is allowed to be NULL */ + + H5E_BEGIN_TRY + { + /* H5S_PLIST for memory dataspace */ + ret = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_PLIST, H5S_ALL, H5P_DEFAULT, buf); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + + /* Write the entire dataset */ + if (H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Reset the memory buffer */ + HDmemset(buf, 0, sizeof(buf)); + + /* Read the entire dataset */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_ALL, H5P_DEFAULT, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < 20; u++) + if (buf[u] != (int)u) + TEST_ERROR + + /* Reset the memory buffer */ + HDmemset(buf, 0, sizeof(buf)); + + /* Set valid selection in DXPL */ + if (H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_SET, &start, &stride, &count, &block) < + 0) + FAIL_STACK_ERROR + + /* Read a hyperslab from the file to the first 10 elements of the buffer */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + + /* Reset the memory buffer */ + HDmemset(buf, 0, sizeof(buf)); + + /* Check for copying property list w/selection */ + if ((dxpl_id_copy = H5Pcopy(dxpl_id)) < 0) + FAIL_STACK_ERROR + + /* Read a hyperslab from the file to the first 10 elements of the buffer */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id_copy, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + + /* Attempt to 'OR' block with invalid dimensions into the selection */ + H5E_BEGIN_TRY + { + ret = H5Pset_dataset_io_hyperslab_selection(dxpl_id_copy, 2, H5S_SELECT_OR, &start, &stride, &count, + &block); + } + H5E_END_TRY; + if (ret == SUCCEED) + TEST_ERROR + + /* Set new valid selection in DXPL */ + if (H5Pset_dataset_io_hyperslab_selection(dxpl_id_copy, 1, H5S_SELECT_SET, &start, &stride, &count, + &block) < 0) + FAIL_STACK_ERROR + + /* Read a hyperslab from the file to the first 10 elements of the buffer */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id_copy, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + + /* Close the copy */ + if (FAIL == H5Pclose(dxpl_id_copy)) + FAIL_STACK_ERROR + dxpl_id_copy = H5I_INVALID_HID; + + /* 'OR' valid block into the existing selection in original DXPL */ + if (H5Pset_dataset_io_hyperslab_selection(dxpl_id, 1, H5S_SELECT_OR, &start2, &stride, &count2, &block) < + 0) + FAIL_STACK_ERROR + + /* Read a disjoint hyperslab from the file to the first 10 elements of the buffer */ + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_BLOCK, H5S_PLIST, dxpl_id, buf) < 0) + FAIL_STACK_ERROR + + /* Verify the data read in */ + for (u = 0; u < count; u++) + if (buf[u] != (int)(u + start)) + TEST_ERROR + for (u = 0; u < count2; u++) + if (buf[u + count] != (int)(u + start2)) + TEST_ERROR + + /************/ + /* TEARDOWN */ + /************/ + if (FAIL == H5Pclose(dxpl_id)) + FAIL_STACK_ERROR + if (FAIL == H5Sclose(file_space_id)) + FAIL_STACK_ERROR + if (FAIL == H5Dclose(dset_id)) + FAIL_STACK_ERROR + if (FAIL == H5Fclose(file_id)) + FAIL_STACK_ERROR + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Pclose(dxpl_id_copy); + H5Pclose(dxpl_id); + H5Sclose(file_space_id); + H5Dclose(dset_id); + H5Fclose(file_id); + } + H5E_END_TRY; + + return FAIL; +} /* end test_h5s_plist() */ + +/*----------------------------------------------------------------------------- * Function: test_0sized_dset_metadata_alloc * * Purpose: Tests the metadata allocation for 0-sized datasets. @@ -15417,6 +15783,8 @@ main(void) /* Tests that use their own file */ nerrors += (test_object_header_minimization_dcpl() < 0 ? 1 : 0); + nerrors += (test_h5s_block() < 0 ? 1 : 0); + nerrors += (test_h5s_plist() < 0 ? 1 : 0); /* Run misc tests */ nerrors += (dls_01_main() < 0 ? 1 : 0); diff --git a/test/dt_arith.c b/test/dt_arith.c index 7b79102..91e31d5 100644 --- a/test/dt_arith.c +++ b/test/dt_arith.c @@ -53,7 +53,7 @@ const char *FILENAME[] = {"dt_arith1", "dt_arith2", NULL}; * endian. If local variable `endian' is H5T_ORDER_BE then the result will * be I, otherwise the result will be Z-(I+1). */ -#define ENDIAN(Z, I, E) (H5T_ORDER_BE == E ? (I) : (Z) - ((I) + 1)) +#define ENDIAN(Z, I, E) (H5T_ORDER_BE == (E) ? (I) : (Z) - ((I) + 1)) typedef enum dtype_t { INT_SCHAR, @@ -3058,10 +3058,10 @@ test_conv_flt_1(const char *name, int run_test, hid_t src, hid_t dst) /* Check the software results against the hardware */ for (j = 0; j < nelmts; j++) { underflow = 0; - hw_f = 911.0f; - hw_d = 911.0f; + hw_f = 911.0F; + hw_d = 911.0F; #if H5_SIZEOF_LONG_DOUBLE != H5_SIZEOF_DOUBLE - hw_ld = 911.0f; + hw_ld = 911.0L; #endif /* The hardware conversion */ diff --git a/test/dtransform.c b/test/dtransform.c index 9445d83..743103f 100644 --- a/test/dtransform.c +++ b/test/dtransform.c @@ -32,30 +32,30 @@ hid_t dset_id_int_chunk = -1; hid_t dset_id_float_chunk = -1; const float windchillFfloat[ROWS][COLS] = { - {36.0f, 31.0f, 25.0f, 19.0f, 13.0f, 7.0f, 1.0f, -5.0f, -11.0f, -16.0f, -22.0f, -28.0f, -34.0f, -40.0f, - -46.0f, -52.0f, -57.0f, -63.0f}, - {34.0f, 27.0f, 21.0f, 15.0f, 9.0f, 3.0f, -4.0f, -10.0f, -16.0f, -22.0f, -28.0f, -35.0f, -41.0f, -47.0f, - -53.0f, -59.0f, -66.0f, -72.0f}, - {32.0f, 25.0f, 19.0f, 13.0f, 6.0f, 0.0f, -7.0f, -13.0f, -19.0f, -26.0f, -32.0f, -39.0f, -45.0f, -51.0f, - -58.0f, -64.0f, -71.0f, -77.0f}, - {30.0f, 24.0f, 17.0f, 11.0f, 4.0f, -2.0f, -9.0f, -15.0f, -22.0f, -29.0f, -35.0f, -42.0f, -48.0f, -55.0f, - -61.0f, -68.0f, -74.0f, -81.0f}, - {29.0f, 23.0f, 16.0f, 9.0f, 3.0f, -4.0f, -11.0f, -17.0f, -24.0f, -31.0f, -37.0f, -44.0f, -51.0f, -58.0f, - -64.0f, -71.0f, -78.0f, -84.0f}, - {28.0f, 22.0f, 15.0f, 8.0f, 1.0f, -5.0f, -12.0f, -19.0f, -26.0f, -33.0f, -39.0f, -46.0f, -53.0f, -60.0f, - -67.0f, -73.0f, -80.0f, -87.0f}, - {28.0f, 21.0f, 14.0f, 7.0f, 0.0f, -7.0f, -14.0f, -21.0f, -27.0f, -34.0f, -41.0f, -48.0f, -55.0f, -62.0f, - -69.0f, -76.0f, -82.0f, -89.0f}, - {27.0f, 20.0f, 13.0f, 6.0f, -1.0f, -8.0f, -15.0f, -22.0f, -29.0f, -36.0f, -43.0f, -50.0f, -57.0f, -64.0f, - -71.0f, -78.0f, -84.0f, -91.0f}, - {26.0f, 19.0f, 12.0f, 5.0f, -2.0f, -9.0f, -16.0f, -23.0f, -30.0f, -37.0f, -44.0f, -51.0f, -58.0f, -65.0f, - -72.0f, -79.0f, -86.0f, -93.0f}, - {26.0f, 19.0f, 12.0f, 4.0f, -3.0f, -10.0f, -17.0f, -24.0f, -31.0f, -38.0f, -45.0f, -52.0f, -60.0f, -67.0f, - -74.0f, -81.0f, -88.0f, -95.0f}, - {25.0f, 18.0f, 11.0f, 4.0f, -3.0f, -11.0f, -18.0f, -25.0f, -32.0f, -39.0f, -46.0f, -54.0f, -61.0f, -68.0f, - -75.0f, -82.0f, -89.0f, -97.0f}, - {25.0f, 17.0f, 10.0f, 3.0f, -4.0f, -11.0f, -19.0f, -26.0f, -33.0f, -40.0f, -48.0f, -55.0f, -62.0f, -69.0f, - -76.0f, -84.0f, -91.0f, -98.0f}}; + {36.0F, 31.0F, 25.0F, 19.0F, 13.0F, 7.0F, 1.0F, -5.0F, -11.0F, -16.0F, -22.0F, -28.0F, -34.0F, -40.0F, + -46.0F, -52.0F, -57.0F, -63.0F}, + {34.0F, 27.0F, 21.0F, 15.0F, 9.0F, 3.0F, -4.0F, -10.0F, -16.0F, -22.0F, -28.0F, -35.0F, -41.0F, -47.0F, + -53.0F, -59.0F, -66.0F, -72.0F}, + {32.0F, 25.0F, 19.0F, 13.0F, 6.0F, 0.0F, -7.0F, -13.0F, -19.0F, -26.0F, -32.0F, -39.0F, -45.0F, -51.0F, + -58.0F, -64.0F, -71.0F, -77.0F}, + {30.0F, 24.0F, 17.0F, 11.0F, 4.0F, -2.0F, -9.0F, -15.0F, -22.0F, -29.0F, -35.0F, -42.0F, -48.0F, -55.0F, + -61.0F, -68.0F, -74.0F, -81.0F}, + {29.0F, 23.0F, 16.0F, 9.0F, 3.0F, -4.0F, -11.0F, -17.0F, -24.0F, -31.0F, -37.0F, -44.0F, -51.0F, -58.0F, + -64.0F, -71.0F, -78.0F, -84.0F}, + {28.0F, 22.0F, 15.0F, 8.0F, 1.0F, -5.0F, -12.0F, -19.0F, -26.0F, -33.0F, -39.0F, -46.0F, -53.0F, -60.0F, + -67.0F, -73.0F, -80.0F, -87.0F}, + {28.0F, 21.0F, 14.0F, 7.0F, 0.0F, -7.0F, -14.0F, -21.0F, -27.0F, -34.0F, -41.0F, -48.0F, -55.0F, -62.0F, + -69.0F, -76.0F, -82.0F, -89.0F}, + {27.0F, 20.0F, 13.0F, 6.0F, -1.0F, -8.0F, -15.0F, -22.0F, -29.0F, -36.0F, -43.0F, -50.0F, -57.0F, -64.0F, + -71.0F, -78.0F, -84.0F, -91.0F}, + {26.0F, 19.0F, 12.0F, 5.0F, -2.0F, -9.0F, -16.0F, -23.0F, -30.0F, -37.0F, -44.0F, -51.0F, -58.0F, -65.0F, + -72.0F, -79.0F, -86.0F, -93.0F}, + {26.0F, 19.0F, 12.0F, 4.0F, -3.0F, -10.0F, -17.0F, -24.0F, -31.0F, -38.0F, -45.0F, -52.0F, -60.0F, -67.0F, + -74.0F, -81.0F, -88.0F, -95.0F}, + {25.0F, 18.0F, 11.0F, 4.0F, -3.0F, -11.0F, -18.0F, -25.0F, -32.0F, -39.0F, -46.0F, -54.0F, -61.0F, -68.0F, + -75.0F, -82.0F, -89.0F, -97.0F}, + {25.0F, 17.0F, 10.0F, 3.0F, -4.0F, -11.0F, -19.0F, -26.0F, -33.0F, -40.0F, -48.0F, -55.0F, -62.0F, -69.0F, + -76.0F, -84.0F, -91.0F, -98.0F}}; const int transformData[ROWS][COLS] = {{36, 31, 25, 19, 13, 7, 1, 5, 11, 16, 22, 28, 34, 40, 46, 52, 57, 63}, {34, 27, 21, 15, 9, 3, 4, 10, 16, 22, 28, 35, 41, 47, 53, 59, 66, 1}, @@ -77,9 +77,9 @@ const int transformData[ROWS][COLS] = {{36, 31, 25, 19, 13, 7, 1, 5, 11, 16, 22, for (i = 0; i < ROWS; i++) \ for (j = 0; j < COLS; j++) { \ if (!((((VAR1)[i][j] >= (TYPE)((VAR2)[i][j])) && \ - (((VAR1)[i][j] - TOL) < (TYPE)((VAR2)[i][j]))) || \ + (((VAR1)[i][j] - (TOL)) < (TYPE)((VAR2)[i][j]))) || \ (((VAR1)[i][j] <= (TYPE)((VAR2)[i][j])) && \ - (((VAR1)[i][j] + TOL) > (TYPE)((VAR2)[i][j]))))) { \ + (((VAR1)[i][j] + (TOL)) > (TYPE)((VAR2)[i][j]))))) { \ H5_FAILED(); \ HDfprintf(stderr, " ERROR: Conversion failed to match computed data\n"); \ goto error; \ @@ -94,8 +94,8 @@ const int transformData[ROWS][COLS] = {{36, 31, 25, 19, 13, 7, 1, 5, 11, 16, 22, \ for (i = 0; i < ROWS; i++) \ for (j = 0; j < COLS; j++) { \ - if (!(((VAR1)[i][j] <= ((TYPE)(VAR2)[i][j] + TOL)) && \ - ((VAR1)[i][j] >= ((TYPE)(VAR2)[i][j] - TOL)))) { \ + if (!(((VAR1)[i][j] <= ((TYPE)(VAR2)[i][j] + (TOL))) && \ + ((VAR1)[i][j] >= ((TYPE)(VAR2)[i][j] - (TOL))))) { \ H5_FAILED(); \ HDfprintf(stderr, " ERROR: Conversion failed to match computed data\n"); \ goto error; \ @@ -540,19 +540,19 @@ test_poly(const hid_t dxpl_id_polynomial) for (row = 0; row < ROWS; row++) for (col = 0; col < COLS; col++) { - windchillC = (int)((5.0f / 9.0f) * (windchillFfloat[row][col] - 32)); - polyflres[row][col] = ((2.0f + (float)windchillC) * (((float)windchillC - 8.0f) / 2.0f)); + windchillC = (int)((5.0F / 9.0F) * (windchillFfloat[row][col] - 32)); + polyflres[row][col] = ((2.0F + (float)windchillC) * (((float)windchillC - 8.0F) / 2.0F)); } TESTING("data transform, polynomial transform (int->float)") if (H5Dread(dset_id_int, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, dxpl_id_polynomial, polyflread) < 0) TEST_ERROR - COMPARE(float, polyflread, polyflres, 2.0f) + COMPARE(float, polyflread, polyflres, 2.0F) for (row = 0; row < ROWS; row++) for (col = 0; col < COLS; col++) { - windchillC = (int)((5.0f / 9.0f) * (windchillFfloat[row][col] - 32)); + windchillC = (int)((5.0F / 9.0F) * (windchillFfloat[row][col] - 32)); polyflres[row][col] = (float)((2 + windchillC) * ((windchillC - 8) / 2)); } @@ -582,6 +582,7 @@ test_specials(hid_t file) const char *special4 = "-x"; const char *special5 = "+x"; const char *special6 = "2e+1*x"; + const char *special7 = "x"; TESTING("data transform of some special cases") @@ -729,6 +730,32 @@ test_specials(hid_t file) if (H5Dclose(dset_id) < 0) TEST_ERROR + /*----------------------------- + * Operation 7: x + * This operation will be + * treated if no function has + * been specified. + *----------------------------*/ + if (H5Pset_data_transform(dxpl_id, special7) < 0) + TEST_ERROR; + + for (row = 0; row < ROWS; row++) + for (col = 0; col < COLS; col++) + data_res[row][col] = transformData[row][col]; + + if ((dset_id = H5Dcreate2(file, "/special7", H5T_NATIVE_INT, dataspace, H5P_DEFAULT, H5P_DEFAULT, + H5P_DEFAULT)) < 0) + TEST_ERROR + if (H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl_id, transformData) < 0) + TEST_ERROR + if (H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, read_buf) < 0) + TEST_ERROR + + COMPARE_INT(read_buf, data_res) + + if (H5Dclose(dset_id) < 0) + TEST_ERROR + if (H5Pclose(dxpl_id) < 0) TEST_ERROR if (H5Sclose(dataspace) < 0) @@ -752,7 +779,7 @@ test_copy(const hid_t dxpl_id_c_to_f_copy, const hid_t dxpl_id_polynomial_copy) for (row = 0; row < ROWS; row++) for (col = 0; col < COLS; col++) { - windchillC = (int)((5.0f / 9.0f) * (windchillFfloat[row][col] - 32)); + windchillC = (int)((5.0F / 9.0F) * (windchillFfloat[row][col] - 32)); polyflres[row][col] = (float)((2 + windchillC) * ((windchillC - 8) / 2)); } @@ -786,7 +813,7 @@ test_trivial(const hid_t dxpl_id_simple) TEST_ERROR for (row = 0; row < ROWS; row++) for (col = 0; col < COLS; col++) { - if ((windchillFfloatread[row][col] - 4.8f) > FLOAT_TOL) + if ((windchillFfloatread[row][col] - 4.8F) > FLOAT_TOL) FAIL_PUTS_ERROR(" ERROR: Conversion failed to match computed data\n"); } @@ -843,7 +870,7 @@ test_getset(const hid_t dxpl_id_c_to_f) for (row = 0; row < ROWS; row++) for (col = 0; col < COLS; col++) { - if ((windchillFfloatread[row][col] - 4.8f) > FLOAT_TOL) + if ((windchillFfloatread[row][col] - 4.8F) > FLOAT_TOL) FAIL_PUTS_ERROR(" ERROR: Conversion failed to match computed data\n") } diff --git a/test/dtypes.c b/test/dtypes.c index 2a18302..8b3101c 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -70,7 +70,7 @@ FAIL_STACK_ERROR \ if ((NMEMBS) != H5I_nmembers(H5I_DATATYPE)) { \ H5_FAILED(); \ - HDprintf(" #dtype ids expected: %lld; found: %lld\n", (long long)NMEMBS, \ + HDprintf(" #dtype ids expected: %lld; found: %lld\n", (long long)(NMEMBS), \ (long long)H5I_nmembers(H5I_DATATYPE)); \ goto error; \ } @@ -6683,13 +6683,13 @@ static int test_int_float_except(void) { #if H5_SIZEOF_INT == 4 && H5_SIZEOF_FLOAT == 4 - float buf[CONVERT_SIZE] = {(float)INT_MIN - 172.0f, (float)INT_MAX - 32.0f, (float)INT_MAX - 68.0f, - (float)4.5f}; + float buf[CONVERT_SIZE] = {(float)INT_MIN - 172.0F, (float)INT_MAX - 32.0F, (float)INT_MAX - 68.0F, + (float)4.5F}; int buf_int[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 127, 4}; - float buf_float[CONVERT_SIZE] = {(float)INT_MIN, (float)INT_MAX + 1.0f, (float)INT_MAX - 127.0f, 4}; + float buf_float[CONVERT_SIZE] = {(float)INT_MIN, (float)INT_MAX + 1.0F, (float)INT_MAX - 127.0F, 4}; int * intp; /* Pointer to buffer, as integers */ int buf2[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 72, 0}; - float buf2_float[CONVERT_SIZE] = {(float)INT_MIN, (float)INT_MAX, (float)INT_MAX - 127.0f, (float)0.0f}; + float buf2_float[CONVERT_SIZE] = {(float)INT_MIN, (float)INT_MAX, (float)INT_MAX - 127.0F, (float)0.0F}; int buf2_int[CONVERT_SIZE] = {INT_MIN, INT_MAX, INT_MAX - 127, 0}; float *floatp; /* Pointer to buffer #2, as floats */ hid_t dxpl; /* Dataset transfer property list */ diff --git a/test/enc_dec_plist.c b/test/enc_dec_plist.c index 9b4879e..60b229a 100644 --- a/test/enc_dec_plist.c +++ b/test/enc_dec_plist.c @@ -350,7 +350,7 @@ main(void) TESTING("DXPL Encoding/Decoding"); - if ((H5Pset_btree_ratios(dxpl, 0.2f, 0.6f, 0.2f)) < 0) + if ((H5Pset_btree_ratios(dxpl, 0.2, 0.6, 0.2)) < 0) FAIL_STACK_ERROR if ((H5Pset_hyper_vector_size(dxpl, 5)) < 0) FAIL_STACK_ERROR @@ -544,7 +544,7 @@ main(void) FAIL_STACK_ERROR if ((H5Pset_alignment(fapl, 2, 1024)) < 0) FAIL_STACK_ERROR - if ((H5Pset_cache(fapl, 1024, 128, 10485760, 0.3f)) < 0) + if ((H5Pset_cache(fapl, 1024, 128, 10485760, 0.3)) < 0) FAIL_STACK_ERROR if ((H5Pset_elink_file_cache_size(fapl, 10485760)) < 0) FAIL_STACK_ERROR diff --git a/test/error_test.c b/test/error_test.c index cf1e82c..f4dc340 100644 --- a/test/error_test.c +++ b/test/error_test.c @@ -319,7 +319,7 @@ long_desc_cb(unsigned H5_ATTR_UNUSED n, const H5E_error2_t *err_desc, void *clie * 'full_desc' in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static herr_t test_long_desc(void) { @@ -375,7 +375,7 @@ error: return -1; } /* end test_long_desc() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: dump_error diff --git a/test/event_set.c b/test/event_set.c index 6568663..5df49e9 100644 --- a/test/event_set.c +++ b/test/event_set.c @@ -94,6 +94,71 @@ error: } /*------------------------------------------------------------------------- + * Function: test_es_none + * + * Purpose: Tests for passing H5ES_NONE to H5ES routines + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Quincey Koziol + * Friday, February 26, 2021 + * + *------------------------------------------------------------------------- + */ +static int +test_es_none(void) +{ + TESTING("event set H5ES_NONE"); + + /* Wait */ + if (H5ESwait(H5ES_NONE, 0, NULL, NULL) < 0) + TEST_ERROR; + + /* Cancel */ + if (H5EScancel(H5ES_NONE, NULL, NULL) < 0) + TEST_ERROR; + + /* Get count */ + if (H5ESget_count(H5ES_NONE, NULL) < 0) + TEST_ERROR; + + /* Get op counter */ + if (H5ESget_op_counter(H5ES_NONE, NULL) < 0) + TEST_ERROR; + + /* Get error status */ + if (H5ESget_err_status(H5ES_NONE, NULL) < 0) + TEST_ERROR; + + /* Get error count */ + if (H5ESget_err_count(H5ES_NONE, NULL) < 0) + TEST_ERROR; + + /* Get error info */ + if (H5ESget_err_info(H5ES_NONE, 0, NULL, NULL) < 0) + TEST_ERROR; + + /* Register insert function */ + if (H5ESregister_insert_func(H5ES_NONE, NULL, NULL) < 0) + TEST_ERROR; + + /* Register complete function */ + if (H5ESregister_complete_func(H5ES_NONE, NULL, NULL) < 0) + TEST_ERROR; + + /* Close */ + if (H5ESclose(H5ES_NONE) < 0) + TEST_ERROR; + + PASSED(); + return 0; + +error: + return 1; +} + +/*------------------------------------------------------------------------- * Function: main * * Purpose: Tests event sets @@ -118,6 +183,7 @@ main(void) /* Tests */ nerrors += test_es_create(); + nerrors += test_es_none(); /* Cleanup */ h5_cleanup(FILENAME, fapl_id); diff --git a/test/fheap.c b/test/fheap.c index cb9c080..86a555d 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -553,7 +553,7 @@ get_fill_size(const fheap_test_param_t *tparam) * test_desc in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static int begin_test(fheap_test_param_t *tparam, const char *base_desc, fheap_heap_ids_t *keep_ids, size_t *fill_size) { @@ -581,7 +581,7 @@ begin_test(fheap_test_param_t *tparam, const char *base_desc, fheap_heap_ids_t * /* Success */ return (0); } /* end begin_test() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: reopen_file diff --git a/test/file_image.c b/test/file_image.c index 0373468..0d031f5 100644 --- a/test/file_image.c +++ b/test/file_image.c @@ -712,7 +712,7 @@ error: * 'member_file_name' in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static int test_get_file_image(const char *test_banner, const int file_name_num, hid_t fapl, hbool_t user) { @@ -976,7 +976,7 @@ test_get_file_image(const char *test_banner, const int file_name_num, hid_t fapl error: return 1; } /* end test_get_file_image() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /****************************************************************************** * Function: test_get_file_image_error_rejection diff --git a/test/fillval.c b/test/fillval.c index 4215c89..8de6ef1 100644 --- a/test/fillval.c +++ b/test/fillval.c @@ -1050,7 +1050,7 @@ test_rdwr_cases(hid_t file, hid_t dcpl, const char *dname, void *_fillval, H5D_f for (u = 0; u < nelmts; u++) { buf_c[u].a = 1111.11F; buf_c[u].x = 2222; - buf_c[u].y = 3333.3333F; + buf_c[u].y = 3333.3333; buf_c[u].z = 'd'; } if (H5Dwrite(dset2, ctype_id, mspace, fspace, H5P_DEFAULT, buf_c) < 0) @@ -1304,7 +1304,7 @@ test_rdwr(hid_t fapl, const char *base_name, H5D_layout_t layout) if (H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) goto error; HDmemset(&fill_ctype, 0, sizeof(fill_ctype)); - fill_ctype.y = 4444.4444F; + fill_ctype.y = 4444.4444; if (H5Pset_fill_value(dcpl, ctype_id, &fill_ctype) < 0) goto error; nerrors += test_rdwr_cases(file, dcpl, "dset11", &fill_ctype, H5D_FILL_TIME_ALLOC, layout, @@ -1370,7 +1370,7 @@ test_rdwr(hid_t fapl, const char *base_name, H5D_layout_t layout) if (H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) goto error; HDmemset(&fill_ctype, 0, sizeof(fill_ctype)); - fill_ctype.y = 4444.4444F; + fill_ctype.y = 4444.4444; if (H5Pset_fill_value(dcpl, ctype_id, &fill_ctype) < 0) goto error; nerrors += test_rdwr_cases(file, dcpl, "dset12", &fill_ctype, H5D_FILL_TIME_ALLOC, layout, H5T_COMPOUND, diff --git a/test/gheap.c b/test/gheap.c index 95594ee..567fd65 100644 --- a/test/gheap.c +++ b/test/gheap.c @@ -503,7 +503,7 @@ test_ooo_indices(hid_t fapl) GHEAP_REPEATED_ERR(" Unable to insert object into global heap") /* Check that the index is as expected */ - if (obj[j].idx != ((1000 * i) + j - (1000 * ((~i & 1)))) % ((1u << 16) - 1) + 1) + if (obj[j].idx != ((1000 * i) + j - (1000 * ((~i & 1)))) % ((1U << 16) - 1) + 1) GHEAP_REPEATED_ERR(" Unexpected global heap index"); } diff --git a/test/h5test.c b/test/h5test.c index 755ae93..09fb5b5 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -1305,7 +1305,7 @@ h5_dump_info_object(MPI_Info info) * temp in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") h5_stat_size_t h5_get_file_size(const char *filename, hid_t fapl) { @@ -1410,7 +1410,7 @@ h5_get_file_size(const char *filename, hid_t fapl) return (-1); } /* end get_file_size() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /* * This routine is designed to provide equivalent functionality to 'printf' diff --git a/test/hyperslab.c b/test/hyperslab.c index 1f57e3b..1c55259 100644 --- a/test/hyperslab.c +++ b/test/hyperslab.c @@ -585,10 +585,10 @@ test_multifill(size_t nx) for (i = 0; i < nx; i++) { src[i].left = 1111111; - src[i].mid = 12345.6789F; + src[i].mid = 12345.6789; src[i].right = 2222222; dst[i].left = 3333333; - dst[i].mid = 98765.4321F; + dst[i].mid = 98765.4321; dst[i].right = 4444444; } /* end for */ @@ -597,7 +597,7 @@ test_multifill(size_t nx) * over and over again. */ fill.left = 55555555; - fill.mid = 3.1415927F; + fill.mid = 3.1415927; fill.right = 66666666; src_stride = 0; diff --git a/test/null_vol_connector.c b/test/null_vol_connector.c index 2b375d8..6555763 100644 --- a/test/null_vol_connector.c +++ b/test/null_vol_connector.c @@ -116,6 +116,7 @@ static const H5VL_class_t null_vol_g = { { /* introspect_cls */ NULL, /* get_conn_cls */ + NULL, /* get_cap_flags */ NULL, /* opt_query */ }, { diff --git a/test/ohdr.c b/test/ohdr.c index b7af77f..d28b11e 100644 --- a/test/ohdr.c +++ b/test/ohdr.c @@ -457,6 +457,59 @@ error: } /* test_ohdr_swmr() */ /* + * Tests bad object header messages. + * + * Currently tests for CVE-2020-10810 fixes but can be expanded to handle + * other CVE badness. + */ + +/* This is a generated file that can be obtained from: + * + * https://nvd.nist.gov/vuln/detail/CVE-2020-10810 + * + * It was formerly named H5AC_unpin_entry_POC + */ +#define CVE_2020_10810_FILENAME "cve_2020_10810.h5" + +static herr_t +test_ohdr_badness(hid_t fapl) +{ + hid_t fid = H5I_INVALID_HID; + + /* CVE-2020-10810 involved a malformed fsinfo message + * This test ensures the fundamental problem is fixed. Running it under + * valgrind et al. will ensure that the memory leaks and invalid access + * are fixed. + */ + TESTING("Fix for CVE-2020-10810"); + + H5E_BEGIN_TRY + { + /* This should fail due to the malformed fsinfo message. It should + * fail gracefully and not segfault. + */ + fid = H5Fopen(CVE_2020_10810_FILENAME, H5F_ACC_RDWR, fapl); + } + H5E_END_TRY; + + if (fid >= 0) + FAIL_PUTS_ERROR("should not have been able to open malformed file"); + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Fclose(fid); + } + H5E_END_TRY; + + return FAIL; +} + +/* * To test objects with unknown messages in a file with: * a) H5O_BOGUS_VALID_ID: * --the bogus_id is within the range of H5O_msg_class_g[] @@ -488,7 +541,7 @@ test_unknown(unsigned bogus_id, char *filename, hid_t fapl) done in the source directory. */ HDstrncpy(testfile, FILE_BOGUS, TESTFILE_LEN); testfile[TESTFILE_LEN - 1] = '\0'; - HDstrncat(testfile, ".copy", 5); + HDstrncat(testfile, ".copy", sizeof(testfile) - HDstrlen(testfile) - 1); /* Make a copy of the data file from svn. */ if (h5_make_local_copy(FILE_BOGUS, testfile) < 0) @@ -2047,6 +2100,9 @@ main(void) } /* high */ } /* low */ + /* Verify bad ohdr message fixes work */ + test_ohdr_badness(fapl); + /* Verify symbol table messages are cached */ if (h5_verify_cached_stabs(FILENAME, fapl) < 0) TEST_ERROR diff --git a/test/pool.c b/test/pool.c index 9ce1846..c508025 100644 --- a/test/pool.c +++ b/test/pool.c @@ -34,7 +34,7 @@ #define MPOOL_LARGE_BLOCK (MPOOL_PAGE_SIZE * 3) #define MPOOL_NUM_SMALL_BLOCKS 64 #define MPOOL_SMALL_BLOCK 1 -#define MPOOL_NUM_RANDOM 10 * 1024 +#define MPOOL_NUM_RANDOM (10 * 1024) #define MPOOL_RANDOM_MAX_SIZE (MPOOL_PAGE_SIZE * 2) /*------------------------------------------------------------------------- diff --git a/test/set_extent.c b/test/set_extent.c index 5a07362..3078c2d 100644 --- a/test/set_extent.c +++ b/test/set_extent.c @@ -39,7 +39,7 @@ const char *FILENAME[] = {"set_extent1", "set_extent2", "set_extent3", "set_exte #define CONFIG_EARLY_ALLOC 0x04u #define CONFIG_UNFILT_EDGE 0x08u #define CONFIG_ALL (CONFIG_COMPRESS + CONFIG_FILL + CONFIG_EARLY_ALLOC + CONFIG_UNFILT_EDGE) -#define FILL_VALUE -1 +#define FILL_VALUE (-1) #define DO_RANKS_PRINT_CONFIG(TEST) \ { \ HDprintf(" Config:\n"); \ @@ -134,11 +134,11 @@ main(void) TEST_ERROR /* Set chunk cache so only part of the chunks can be cached on fapl */ - if (H5Pset_cache(fapl, 0, (size_t)8, 256 * sizeof(int), 0.75F) < 0) + if (H5Pset_cache(fapl, 0, (size_t)8, 256 * sizeof(int), 0.75) < 0) TEST_ERROR /* Disable chunk caching on fapl2 */ - if (H5Pset_cache(fapl2, 0, (size_t)0, (size_t)0, 0.0F) < 0) + if (H5Pset_cache(fapl2, 0, (size_t)0, (size_t)0, 0.0) < 0) TEST_ERROR /* Set the "use the latest version of the format" bounds for creating objects in the file */ diff --git a/test/swmr_common.c b/test/swmr_common.c index 46c80cf..3d35227 100644 --- a/test/swmr_common.c +++ b/test/swmr_common.c @@ -111,7 +111,7 @@ choose_dataset(unsigned *levelp, unsigned *offsetp, hbool_t verbose) ++ncalls; if ((ncalls % 1000) == 0 && verbose) { - fprintf(stderr, "%s: call %u chose level %u offset %u\n", __func__, ncalls, level, offset); + HDfprintf(stderr, "%s: call %u chose level %u offset %u\n", __func__, ncalls, level, offset); } if (levelp != NULL) *levelp = level; diff --git a/test/swmr_common.h b/test/swmr_common.h index 3a3f41d..c8c033a 100644 --- a/test/swmr_common.h +++ b/test/swmr_common.h @@ -64,7 +64,7 @@ H5TEST_DLLVAR unsigned symbol_count[NLEVELS]; extern "C" { #endif -H5TEST_DLL symbol_info_t *choose_dataset(unsigned *, unsigned *, hbool_t); +H5TEST_DLL symbol_info_t *choose_dataset(unsigned *levelp, unsigned *offsetp, hbool_t verbose); H5TEST_DLL hid_t create_symbol_datatype(void); H5TEST_DLL int generate_name(char *name_buf, unsigned level, unsigned count); H5TEST_DLL int generate_symbols(void); diff --git a/test/tattr.c b/test/tattr.c index b602222..756e139 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -95,8 +95,7 @@ int attr_data2[ATTR2_DIM1][ATTR2_DIM2] = {{7614, -416}, {197814, -3}}; /* Test d #define ATTR3_DIM2 2 #define ATTR3_DIM3 2 double attr_data3[ATTR3_DIM1][ATTR3_DIM2][ATTR3_DIM3] = { - {{2.3F, -26.1F}, {0.123F, -10.0F}}, - {{973.23F, -0.91827F}, {2.0F, 23.0F}}}; /* Test data for 3rd attribute */ + {{2.3, -26.1}, {0.123, -10.0}}, {{973.23, -0.91827}, {2.0, 23.0}}}; /* Test data for 3rd attribute */ #define ATTR4_NAME "Attr4" #define ATTR4_RANK 2 @@ -113,8 +112,8 @@ struct attr4_struct { double d; char c; } attr_data4[ATTR4_DIM1][ATTR4_DIM2] = { - {{3, -26.1F, 'd'}, {-100000, 0.123F, '3'}}, - {{-23, 981724.2F, 'Q'}, {0, 2.0F, '\n'}}}; /* Test data for 4th attribute */ + {{3, -26.1, 'd'}, {-100000, 0.123, '3'}}, + {{-23, 981724.2, 'Q'}, {0, 2.0, '\n'}}}; /* Test data for 4th attribute */ #define ATTR5_NAME "Attr5" #define ATTR5_RANK 0 diff --git a/test/tconfig.c b/test/tconfig.c index e3c6a2c..101de9a 100644 --- a/test/tconfig.c +++ b/test/tconfig.c @@ -37,8 +37,9 @@ /* verify if the sizeof(type) matches size defined in macro. */ /* Needs this extra step so that we can print the macro name. */ #define vrfy_macrosize(type, macro, macroname) \ - if (sizeof(type) != macro) \ - TestErrPrintf("Error: sizeof(%s) is %zu but %s is %d\n", #type, sizeof(type), macroname, (int)macro); + if (sizeof(type) != (macro)) \ + TestErrPrintf("Error: sizeof(%s) is %zu but %s is %d\n", #type, sizeof(type), macroname, \ + (int)(macro)); /* local routine prototypes */ void test_config_ctypes(void); diff --git a/test/test_usecases.sh.in b/test/test_usecases.sh.in index bb53697..eaa875e 100644 --- a/test/test_usecases.sh.in +++ b/test/test_usecases.sh.in @@ -22,10 +22,16 @@ # exit codes are okay (0). srcdir=@srcdir@ +bindir=@bindir@ + +# If the bindir directory is not set just use current (.). +if test -z "$bindir"; then + bindir=. +fi # Check to see if the VFD specified by the HDF5_DRIVER environment variable # supports SWMR. -./swmr_check_compat_vfd +$bindir/swmr_check_compat_vfd rc=$? if [[ $rc != 0 ]] ; then echo @@ -85,7 +91,7 @@ TOOLTEST() { # Run test. TESTING $program $@ ( - $RUNSERIAL ./$program "$@" + $RUNSERIAL $bindir/$program "$@" ) >$actual 2>$actual_err exit_code=$? @@ -178,14 +184,14 @@ fi # main body for p in $USECASES_PROGRAMS; do - TOOLTEST ./$p - TOOLTEST ./$p -z 256 + TOOLTEST $p + TOOLTEST $p -z 256 tmpfile=/tmp/datatfile.$$ - TOOLTEST ./$p -f $tmpfile; rm -f $tmpfile - TOOLTEST ./$p -l w - TOOLTEST ./$p -l r + TOOLTEST $p -f $tmpfile; rm -f $tmpfile + TOOLTEST $p -l w + TOOLTEST $p -l r # use case 1.9, testing with multi-planes chunks - TOOLTEST ./$p -z 256 -y 5 # 5 planes chunks + TOOLTEST $p -z 256 -y 5 # 5 planes chunks # cleanup temp datafile if test -z "$HDF5_NOCLEANUP"; then rm -f $p.h5 diff --git a/test/testcheck_version.sh.in b/test/testcheck_version.sh.in index 43d1b46..6378ee5 100644 --- a/test/testcheck_version.sh.in +++ b/test/testcheck_version.sh.in @@ -15,7 +15,7 @@ # Tests for the H5check_version function. # # Programmer: Albert Cheng -# Sep 28, 2009 +# Sep 28, 2009 srcdir=@srcdir@ @@ -24,7 +24,7 @@ srcdir=@srcdir@ Shared_Lib=@enable_shared@ Static_Lib=@enable_static@ Static_exec=@STATIC_EXEC@ -h5haveexitcode=yes # default is yes +h5haveexitcode=yes # default is yes CMP='cmp -s' DIFF='diff -c' @@ -103,10 +103,10 @@ WarnMesg2(){ # mismatch). # # Expected results: -# Value of $HDF5_DISABLE_VERSION_CHECK -# unset "" -1 0 1 2 3 -# Matched OK OK OK OK OK OK OK -# Mismatched W/A W/A W/A W/A W2/OK OK W2/OK +# Value of $HDF5_DISABLE_VERSION_CHECK +# unset "" -1 0 1 2 3 +# Matched OK OK OK OK OK OK OK +# Mismatched W/A W/A W/A W/A W2/OK OK W2/OK # Result codes: # OK: No warning, exit 0. # W/A: Warning, abort and exit non-0. @@ -130,42 +130,42 @@ TESTING() { xxh5versrelease=$h5versrelease if [ "$h5DisableVersion" = unset ]; then - envcmd="" # noop + envcmd="" # noop else - envcmd="env HDF5_DISABLE_VERSION_CHECK=$h5DisableVersion" + envcmd="env HDF5_DISABLE_VERSION_CHECK=$h5DisableVersion" fi if [ "$wrongversionnumbers" = none ]; then - # OK: No warning, exit 0 - cp /dev/null $expect - expect_code=0 + # OK: No warning, exit 0 + cp /dev/null $expect + expect_code=0 else - arguments=-t"$wrongversionnumbers" - # calculate mismatched version numbers by listing. - case $wrongversionnumbers in - "M") xxh5versmajor=`expr $h5versmajor + 1` - ;; - "m") xxh5versminor=`expr $h5versminor + 1` - ;; - "r") xxh5versrelease=`expr $h5versrelease + 1` - ;; - esac - case "$h5DisableVersion" in - 1) - # W2/OK: Different Warning, exit 0. - WarnMesg2 > $expect - expect_code=0 - ;; - [2-9]|[1-9][0-9]*) - # OK: No warning, exit 0 - cp /dev/null $expect - expect_code=0 - ;; - *) # W/A: Warning, abort and exit non-0. - WarnMesg > $expect - expect_code=6 # Signal Abort exit code (128+6) - ;; - esac + arguments=-t"$wrongversionnumbers" + # calculate mismatched version numbers by listing. + case $wrongversionnumbers in + "M") xxh5versmajor=`expr $h5versmajor + 1` + ;; + "m") xxh5versminor=`expr $h5versminor + 1` + ;; + "r") xxh5versrelease=`expr $h5versrelease + 1` + ;; + esac + case "$h5DisableVersion" in + 1) + # W2/OK: Different Warning, exit 0. + WarnMesg2 > $expect + expect_code=0 + ;; + [2-9]|[1-9][0-9]*) + # OK: No warning, exit 0 + cp /dev/null $expect + expect_code=0 + ;; + *) # W/A: Warning, abort and exit non-0. + WarnMesg > $expect + expect_code=6 # Signal Abort exit code (128+6) + ;; + esac fi # Run test. @@ -177,23 +177,23 @@ TESTING() { cat $actual_err >> $actual if [ $h5haveexitcode = 'yes' -a \( $expect_code -ne $ret_code \) ]; then - echo "*FAILED*" - echo " Expected exit code ($expect_code) differs from actual code ($ret_code)" - nerrors="`expr $nerrors + 1`" + echo "*FAILED*" + echo " Expected exit code ($expect_code) differs from actual code ($ret_code)" + nerrors="`expr $nerrors + 1`" elif $CMP $expect $actual; then - echo " PASSED" + echo " PASSED" else - echo "*FAILED*" - echo " Expected result differs from actual result" - nerrors="`expr $nerrors + 1`" - test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' + echo "*FAILED*" + echo " Expected result differs from actual result" + nerrors="`expr $nerrors + 1`" + test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' fi # Clean up output file. # Also clean the core file generated by H5check_version's abort. if test -z "$HDF5_NOCLEANUP"; then - $RM $expect $actual $actual_err - $RM core + $RM $expect $actual $actual_err + $RM core fi } @@ -201,15 +201,15 @@ TESTING() { # Echo parameters for debugging if verbose mode is on. DEBUGPRINT() { if [ -n "$debugmode" ]; then - echo $* + echo $* fi } # MAIN Body nerrors=0 -verbose=yes # default on -debugmode= # default off +verbose=yes # default on +debugmode= # default off H5_HAVE_EMBEDDED_LIBINFO=`grep '#define H5_HAVE_EMBEDDED_LIBINFO ' ../src/H5pubconf.h` h5libsettings=../src/libhdf5.settings @@ -240,13 +240,13 @@ fi # Three Categories of tests: # Normal: where the version numbers all matched (wrong_version == none). # Mismatched version numbers (could be Major or minor version -# or release numbers or a combination of all three.) +# or release numbers or a combination of all three.) # Test all the above with different values of the environment variable, # HDF5_DISABLE_VERSION_CHECK, as unset, "", -1, 0, 1, 2, 3 for val_disable_version_check in unset "" -1 0 1 2 3; do - for wrong_version in none M m r; do - TESTING "$val_disable_version_check" "$wrong_version" + for wrong_version in none M m; do + TESTING "$val_disable_version_check" "$wrong_version" done done diff --git a/test/testhdf5.h b/test/testhdf5.h index 5fb01a8..ba5fa71 100644 --- a/test/testhdf5.h +++ b/test/testhdf5.h @@ -136,7 +136,7 @@ "%s \n", \ (where), (int)__LINE__, __FILE__, x); \ } \ - if (HDstrcmp(x, val)) { \ + if (HDstrcmp(x, val) != 0) { \ TestErrPrintf("*** UNEXPECTED VALUE from %s should be %s, but is %s at line %4d " \ "in %s\n", \ where, val, x, (int)__LINE__, __FILE__); \ diff --git a/test/testswmr.sh.in b/test/testswmr.sh.in index 2df23c6..37e8f9c 100644 --- a/test/testswmr.sh.in +++ b/test/testswmr.sh.in @@ -17,6 +17,7 @@ # Albert Cheng, 2009/07/22 srcdir=@srcdir@ +bindir=@bindir@ ############################################################################### ## test parameters @@ -97,9 +98,14 @@ if test -z "$srcdir"; then srcdir=. fi +# If the bindir directory is not set just use current (.). +if test -z "$bindir"; then + bindir=. +fi + # Check to see if the VFD specified by the HDF5_DRIVER environment variable # supports SWMR. -./swmr_check_compat_vfd +$bindir/swmr_check_compat_vfd rc=$? if [ $rc -ne 0 ] ; then echo @@ -172,7 +178,7 @@ do echo "###############################################################################" # Launch the Generator without SWMR_WRITE echo launch the swmr_generator - ./swmr_generator $compress $index_type + $bindir/swmr_generator $compress $index_type if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -180,7 +186,7 @@ do # Launch the Generator with SWMR_WRITE echo launch the swmr_generator with SWMR_WRITE - ./swmr_generator -s $compress $index_type + $bindir/swmr_generator -s $compress $index_type if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -204,7 +210,7 @@ do # Launch the Writer echo launch the swmr_start_writer seed="" # Put -r <random seed> command here - ./swmr_start_write $compress $index_type $Nrecords $seed 2>&1 |tee swmr_writer.out & + $bindir/swmr_start_write $compress $index_type $Nrecords $seed 2>&1 |tee swmr_writer.out & pid_writer=$! $DPRINT pid_writer=$pid_writer @@ -220,7 +226,7 @@ do while [ $n -lt $Nreaders ]; do #seed="-r ${seeds[$n]}" seed="" - ./swmr_reader $Nsecs_add $seed 2>&1 |tee swmr_reader.out.$n & + $bindir/swmr_reader $Nsecs_add $seed 2>&1 |tee swmr_reader.out.$n & pid_readers="$pid_readers $!" n=`expr $n + 1` done @@ -265,7 +271,7 @@ do # Launch the Generator echo launch the swmr_generator - ./swmr_generator -s $compress $index_type + $bindir/swmr_generator -s $compress $index_type if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -277,7 +283,7 @@ do # Launch the Writer echo launch the swmr_writer seed="" # Put -r <random seed> command here - ./swmr_writer -o $Nrecords $seed 2>&1 |tee swmr_writer.out & + $bindir/swmr_writer -o $Nrecords $seed 2>&1 |tee swmr_writer.out & pid_writer=$! $DPRINT pid_writer=$pid_writer @@ -292,7 +298,7 @@ do while [ $n -lt $Nreaders ]; do #seed="-r ${seeds[$n]}" seed="" - ./swmr_reader $Nsecs_add $seed 2>&1 |tee swmr_reader.out.$n & + $bindir/swmr_reader $Nsecs_add $seed 2>&1 |tee swmr_reader.out.$n & pid_readers="$pid_readers $!" n=`expr $n + 1` done @@ -340,7 +346,7 @@ do # Launch the Remove Writer echo launch the swmr_remove_writer seed="" # Put -r <random seed> command here - ./swmr_remove_writer -o $Nrecs_rem $seed 2>&1 |tee swmr_writer.out & + $bindir/swmr_remove_writer -o $Nrecs_rem $seed 2>&1 |tee swmr_writer.out & pid_writer=$! $DPRINT pid_writer=$pid_writer @@ -355,7 +361,7 @@ do while [ $n -lt $Nreaders ]; do #seed="-r ${seeds[$n]}" seed="" - ./swmr_remove_reader $Nsecs_rem $seed 2>&1 |tee swmr_reader.out.$n & + $bindir/swmr_remove_reader $Nsecs_rem $seed 2>&1 |tee swmr_reader.out.$n & pid_readers="$pid_readers $!" n=`expr $n + 1` done @@ -400,7 +406,7 @@ do # Launch the Generator echo launch the swmr_generator - ./swmr_generator $compress $index_type + $bindir/swmr_generator $compress $index_type if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -409,7 +415,7 @@ do # Launch the Writer (not in parallel - just to rebuild the datasets) echo launch the swmr_writer seed="" # Put -r <random seed> command here - ./swmr_writer $Nrecords $seed + $bindir/swmr_writer $Nrecords $seed if test $? -ne 0; then echo writer had error nerrors=`expr $nerrors + 1` @@ -421,7 +427,7 @@ do # Launch the Add/Remove Writer echo launch the swmr_addrem_writer seed="" # Put -r <random seed> command here - ./swmr_addrem_writer $Nrecords $seed 2>&1 |tee swmr_writer.out & + $bindir/swmr_addrem_writer $Nrecords $seed 2>&1 |tee swmr_writer.out & pid_writer=$! $DPRINT pid_writer=$pid_writer @@ -436,7 +442,7 @@ do while [ $n -lt $Nreaders ]; do #seed="-r ${seeds[$n]}" seed="" - ./swmr_remove_reader $Nsecs_addrem $seed 2>&1 |tee swmr_reader.out.$n & + $bindir/swmr_remove_reader $Nsecs_addrem $seed 2>&1 |tee swmr_reader.out.$n & pid_readers="$pid_readers $!" n=`expr $n + 1` done @@ -484,7 +490,7 @@ do # created by the generator. echo launch the swmr_generator seed="" # Put -r <random seed> command here - ./swmr_generator $compress $index_type $seed + $bindir/swmr_generator $compress $index_type $seed if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -494,7 +500,7 @@ do rm -f $WRITER_MESSAGE # Launch the Sparse writer echo launch the swmr_sparse_writer - nice -n 20 ./swmr_sparse_writer $Nrecs_spa 2>&1 |tee swmr_writer.out & + nice -n 20 $bindir/swmr_sparse_writer $Nrecs_spa 2>&1 |tee swmr_writer.out & pid_writer=$! $DPRINT pid_writer=$pid_writer @@ -507,7 +513,7 @@ do echo launch $Nrdrs_spa swmr_sparse_readers while [ $n -lt $Nrdrs_spa ]; do # The sparse reader spits out a LOT of data so it's set to 'quiet' - ./swmr_sparse_reader -q $Nrecs_spa 2>&1 |tee swmr_reader.out.$n & + $bindir/swmr_sparse_reader -q $Nrecs_spa 2>&1 |tee swmr_reader.out.$n & pid_readers="$pid_readers $!" n=`expr $n + 1` done diff --git a/test/testvdsswmr.sh.in b/test/testvdsswmr.sh.in index 9673aa3..5399903 100644 --- a/test/testvdsswmr.sh.in +++ b/test/testvdsswmr.sh.in @@ -17,6 +17,7 @@ # Dana Robinson, November 2015 srcdir=@srcdir@ +bindir=@bindir@ ############################################################################### ## test parameters @@ -30,7 +31,7 @@ nerrors=0 ## definitions for message file to coordinate test runs ############################################################################### WRITER_MESSAGE=SWMR_WRITER_MESSAGE # The message file created by writer that the open is complete - # This should be the same as the define in "./swmr_common.h" + # This should be the same as the define in "$bindir/swmr_common.h" MESSAGE_TIMEOUT=300 # Message timeout length in secs # This should be the same as the define in "./h5test.h" @@ -83,9 +84,14 @@ if test -z "$srcdir"; then srcdir=. fi +# If the bindir directory is not set just use current (.). +if test -z "$bindir"; then + bindir=. +fi + # Check to see if the VFD specified by the HDF5_DRIVER environment variable # supports SWMR. -./swmr_check_compat_vfd +$bindir/swmr_check_compat_vfd rc=$? if [ $rc -ne 0 ] ; then echo @@ -148,7 +154,7 @@ echo "########################################################################## # Launch the file generator echo launch the generator -./vds_swmr_gen +$bindir/vds_swmr_gen if test $? -ne 0; then echo generator had error nerrors=`expr $nerrors + 1` @@ -166,7 +172,7 @@ echo "launch the $Nwriters SWMR VDS writers (1 per source)" pid_writers="" n=0 while [ $n -lt $Nwriters ]; do - ./vds_swmr_writer $n & + $bindir/vds_swmr_writer $n & pid_writers="$pid_writers $!" n=`expr $n + 1` done @@ -181,7 +187,7 @@ echo launch $Nreaders SWMR readers pid_readers="" n=0 while [ $n -lt $Nreaders ]; do - ./vds_swmr_reader & + $bindir/vds_swmr_reader & pid_readers="$pid_readers $!" n=`expr $n + 1` done diff --git a/test/tfile.c b/test/tfile.c index d85d188..656e956 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -125,7 +125,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 */ +#define FSP_SIZE1G (1024 * 1024 * 1024) /* File space page size */ /* Declaration for test_libver_macros2() */ #define FILE6 "tfile6.h5" /* Test file */ diff --git a/test/timer.c b/test/timer.c index bb474ca..11b7427 100644 --- a/test/timer.c +++ b/test/timer.c @@ -43,55 +43,55 @@ test_time_formatting(void) TESTING("Time string formats"); /* < 0, N/A */ - s = H5_timer_get_time_string(-1.0F); + s = H5_timer_get_time_string(-1.0); if (NULL == s || HDstrcmp(s, "N/A") != 0) TEST_ERROR; HDfree(s); /* 0 0 */ - s = H5_timer_get_time_string(0.0F); + s = H5_timer_get_time_string(0.0); if (NULL == s || HDstrcmp(s, "0.0 s") != 0) TEST_ERROR; HDfree(s); /* < 1 us nanoseconds */ - s = H5_timer_get_time_string(123.0E-9F); + s = H5_timer_get_time_string(123.0E-9); if (NULL == s || HDstrcmp(s, "123 ns") != 0) TEST_ERROR; HDfree(s); /* < 1 ms microseconds */ - s = H5_timer_get_time_string(23.456E-6F); + s = H5_timer_get_time_string(23.456E-6); if (NULL == s || HDstrcmp(s, "23.5 us") != 0) TEST_ERROR; HDfree(s); /* < 1 s milliseconds */ - s = H5_timer_get_time_string(4.56789E-3F); + s = H5_timer_get_time_string(4.56789E-3); if (NULL == s || HDstrcmp(s, "4.6 ms") != 0) TEST_ERROR; HDfree(s); /* < 1 min seconds */ - s = H5_timer_get_time_string(3.14F); + s = H5_timer_get_time_string(3.14); if (NULL == s || HDstrcmp(s, "3.14 s") != 0) TEST_ERROR; HDfree(s); /* < 1 hr mins, secs */ - s = H5_timer_get_time_string(2521.0F); + s = H5_timer_get_time_string(2521.0); if (NULL == s || HDstrcmp(s, "42 m 1 s") != 0) TEST_ERROR; HDfree(s); /* < 1 d hrs, mins, secs */ - s = H5_timer_get_time_string(9756.0F); + s = H5_timer_get_time_string(9756.0); if (NULL == s || HDstrcmp(s, "2 h 42 m 36 s") != 0) TEST_ERROR; HDfree(s); /* > 1 d days, hrs, mins, secs */ - s = H5_timer_get_time_string(280802.0F); + s = H5_timer_get_time_string(280802.0); if (NULL == s || HDstrcmp(s, "3 d 6 h 0 m 2 s") != 0) TEST_ERROR; HDfree(s); diff --git a/test/tmeta.c b/test/tmeta.c index 2609703..e70db16 100644 --- a/test/tmeta.c +++ b/test/tmeta.c @@ -22,9 +22,9 @@ #include "testhdf5.h" #include "H5Fprivate.h" -#define TEST_INT16_VALUE -7641 +#define TEST_INT16_VALUE (-7641) #define TEST_UINT16_VALUE 45002 -#define TEST_INT32_VALUE -981236 +#define TEST_INT32_VALUE (-981236) #define TEST_UINT32_VALUE 3476589 uint8_t compar_buffer[] = { diff --git a/test/tmisc.c b/test/tmisc.c index 302da0d..b267330 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -5276,7 +5276,7 @@ test_misc28(void) * bytes). */ fapl = H5Pcreate(H5P_FILE_ACCESS); CHECK(fapl, FAIL, "H5Pcreate"); - ret = H5Pset_cache(fapl, MISC28_NSLOTS, MISC28_NSLOTS, MISC28_SIZE, 0.75F); + ret = H5Pset_cache(fapl, MISC28_NSLOTS, MISC28_NSLOTS, MISC28_SIZE, 0.75); CHECK(ret, FAIL, "H5Pset_cache"); /* Create the dcpl and set the chunk size */ diff --git a/test/tsohm.c b/test/tsohm.c index fcbb06a..b4ece0b 100644 --- a/test/tsohm.c +++ b/test/tsohm.c @@ -622,7 +622,7 @@ size1_helper(hid_t file, const char *filename, hid_t fapl_id, hbool_t test_file_ HDprintf("Can't read data\n"); \ goto error; \ } \ - if ((rdata.i1 != wdata.i1) || (rdata.i2 != wdata.i2) || HDstrcmp(rdata.str, wdata.str)) { \ + if ((rdata.i1 != wdata.i1) || (rdata.i2 != wdata.i2) || HDstrcmp(rdata.str, wdata.str) != 0) { \ H5_FAILED(); \ AT(); \ HDprintf("incorrect read data\n"); \ diff --git a/test/tunicode.c b/test/tunicode.c index 52341bb..1b696ac 100644 --- a/test/tunicode.c +++ b/test/tunicode.c @@ -33,7 +33,7 @@ #define RANK 1 #define COMP_INT_VAL 7 -#define COMP_FLOAT_VAL -42.0F +#define COMP_FLOAT_VAL (-42.0F) #define COMP_DOUBLE_VAL 42.0F /* Test function prototypes */ diff --git a/test/tvltypes.c b/test/tvltypes.c index 50b2d7a..03a8ad3 100644 --- a/test/tvltypes.c +++ b/test/tvltypes.c @@ -2526,10 +2526,10 @@ test_vltypes_fill_value(void) hsize_t small_dims[] = {SPACE4_DIM_SMALL}; hsize_t large_dims[] = {SPACE4_DIM_LARGE}; size_t dset_elmts = 0; /* Number of elements in a particular dataset */ - const dtype1_struct fill1 = {1, 2, "foobar", "", NULL, "\0", "dead", - 3, 4.0F, 100.0F, 1.0F, "liquid", "meter"}; - const dtype1_struct wdata = {3, 4, "", NULL, "\0", "foo", "two", 6, 8.0F, 200.0F, 2.0F, "solid", "yard"}; - dtype1_struct * rbuf = NULL; /* Buffer for reading data */ + const dtype1_struct fill1 = {1, 2, "foobar", "", NULL, "\0", "dead", + 3, 4.0, 100.0, 1.0, "liquid", "meter"}; + const dtype1_struct wdata = {3, 4, "", NULL, "\0", "foo", "two", 6, 8.0, 200.0, 2.0, "solid", "yard"}; + dtype1_struct * rbuf = NULL; /* Buffer for reading data */ size_t mem_used = 0; /* Memory used during allocation */ H5D_layout_t layout; /* Dataset storage layout */ char dset_name1[64], dset_name2[64]; /* Dataset names */ diff --git a/test/vds.c b/test/vds.c index 88ac4eb..ac9bb5d 100644 --- a/test/vds.c +++ b/test/vds.c @@ -78,12 +78,12 @@ char vds_test_str_g[128] = ""; #endif /* VDS_TEST_VERBOSE */ /* I/O test config flags */ -#define TEST_IO_CLOSE_SRC 0x01u -#define TEST_IO_DIFFERENT_FILE 0x02u -#define TEST_IO_REOPEN_VIRT 0x04u -#define TEST_IO_FCLOSE_SEMI 0x08u -#define TEST_IO_FCLOSE_STRONG 0x10u -#define TEST_IO_NTESTS 0x20u +#define TEST_IO_CLOSE_SRC 0x01U +#define TEST_IO_DIFFERENT_FILE 0x02U +#define TEST_IO_REOPEN_VIRT 0x04U +#define TEST_IO_FCLOSE_SEMI 0x08U +#define TEST_IO_FCLOSE_STRONG 0x10U +#define TEST_IO_NTESTS 0x20U #define LIST_DOUBLE_SIZE (H5D_VIRTUAL_DEF_LIST_SIZE + 1) diff --git a/test/vfd.c b/test/vfd.c index 8484bfd..f4cb988 100644 --- a/test/vfd.c +++ b/test/vfd.c @@ -859,7 +859,7 @@ error: * 'first_name' in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static herr_t test_family_opens(char *fname, hid_t fa_pl) { @@ -924,7 +924,7 @@ test_family_opens(char *fname, hid_t fa_pl) error: return -1; } /* end test_family_opens() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: test_family @@ -1150,7 +1150,7 @@ error: * 'newname_individual', etc. in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static herr_t test_family_compat(void) { @@ -1236,7 +1236,7 @@ error: return -1; } /* end test_family_compat() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: test_family_member_fapl @@ -1376,7 +1376,7 @@ error: * 'sf_name' in the code below, but early (4.4.7, at least) gcc only * allows diagnostic pragmas to be toggled outside of functions. */ -H5_GCC_DIAG_OFF("format-nonliteral") +H5_GCC_CLANG_DIAG_OFF("format-nonliteral") static herr_t test_multi_opens(char *fname) { @@ -1396,7 +1396,7 @@ test_multi_opens(char *fname) return (fid >= 0 ? FAIL : SUCCEED); } /* end test_multi_opens() */ -H5_GCC_DIAG_ON("format-nonliteral") +H5_GCC_CLANG_DIAG_ON("format-nonliteral") /*------------------------------------------------------------------------- * Function: test_multi diff --git a/test/vol.c b/test/vol.c index d975243..c7586d5 100644 --- a/test/vol.c +++ b/test/vol.c @@ -20,6 +20,12 @@ /* Headers needed */ #include "h5test.h" +#include "H5Iprivate.h" /* IDs */ +#define H5T_FRIEND /* Suppress error about including H5Tpkg */ +#include "H5Tpkg.h" /* Datatypes */ +#define H5VL_FRIEND /* Suppress error about including H5VLpkg */ +#define H5VL_TESTING +#include "H5VLpkg.h" /* Virtual Object Layer */ /* Filename */ const char *FILENAME[] = {"native_vol_test", NULL}; @@ -35,6 +41,136 @@ const char *FILENAME[] = {"native_vol_test", NULL}; #define N_ELEMENTS 10 +/* A VOL class struct to verify registering optional operations */ +static int reg_opt_curr_op_val; +static herr_t reg_opt_op_optional(void *obj, H5VL_optional_args_t *args, hid_t dxpl_id, void **req); +static herr_t reg_opt_link_optional(void *obj, const H5VL_loc_params_t *loc_params, + H5VL_optional_args_t *args, hid_t dxpl_id, void **req); +static herr_t reg_opt_datatype_get(void *obj, H5VL_datatype_get_args_t *args, hid_t dxpl_id, void **req); +#define REG_OPT_VOL_NAME "reg_opt" +#define REG_OPT_VOL_VALUE ((H5VL_class_value_t)502) +static const H5VL_class_t reg_opt_vol_g = { + H5VL_VERSION, /* VOL class struct version */ + REG_OPT_VOL_VALUE, /* value */ + REG_OPT_VOL_NAME, /* name */ + 0, /* version */ + 0, /* capability flags */ + NULL, /* initialize */ + NULL, /* terminate */ + { + /* info_cls */ + (size_t)0, /* size */ + NULL, /* copy */ + NULL, /* compare */ + NULL, /* free */ + NULL, /* to_str */ + NULL, /* from_str */ + }, + { + /* wrap_cls */ + NULL, /* get_object */ + NULL, /* get_wrap_ctx */ + NULL, /* wrap_object */ + NULL, /* unwrap_object */ + NULL, /* free_wrap_ctx */ + }, + { + /* attribute_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* read */ + NULL, /* write */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_op_optional, /* optional */ + NULL /* close */ + }, + { + /* dataset_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* read */ + NULL, /* write */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_op_optional, /* optional */ + NULL /* close */ + }, + { + /* datatype_cls */ + NULL, /* commit */ + NULL, /* open */ + reg_opt_datatype_get, /* get */ + NULL, /* specific */ + reg_opt_op_optional, /* optional */ + NULL /* close */ + }, + { + /* file_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_op_optional, /* optional */ + NULL /* close */ + }, + { + /* group_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_op_optional, /* optional */ + NULL /* close */ + }, + { + /* link_cls */ + NULL, /* create */ + NULL, /* copy */ + NULL, /* move */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_link_optional /* optional */ + }, + { + /* object_cls */ + NULL, /* open */ + NULL, /* copy */ + NULL, /* get */ + NULL, /* specific */ + reg_opt_link_optional /* optional */ + }, + { + /* introspect_cls */ + NULL, /* get_conn_cls */ + NULL, /* get_cap_flags */ + NULL, /* opt_query */ + }, + { + /* request_cls */ + NULL, /* wait */ + NULL, /* notify */ + NULL, /* cancel */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* free */ + }, + { + /* blob_cls */ + NULL, /* put */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, + { + /* token_cls */ + NULL, /* cmp */ + NULL, /* to_str */ + NULL /* from_str */ + }, + NULL /* optional */ +}; + #define FAKE_VOL_NAME "fake" #define FAKE_VOL_VALUE ((H5VL_class_value_t)501) @@ -90,6 +226,136 @@ static const H5VL_class_t fake_vol_g = { }, { /* datatype_cls */ + NULL, /* commit */ + NULL, /* open */ + reg_opt_datatype_get, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* file_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* group_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* link_cls */ + NULL, /* create */ + NULL, /* copy */ + NULL, /* move */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, + { + /* object_cls */ + NULL, /* open */ + NULL, /* copy */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, + { + /* introspect_cls */ + NULL, /* get_conn_cls */ + NULL, /* get_cap_flags */ + NULL, /* opt_query */ + }, + { + /* request_cls */ + NULL, /* wait */ + NULL, /* notify */ + NULL, /* cancel */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* free */ + }, + { + /* blob_cls */ + NULL, /* put */ + NULL, /* get */ + NULL, /* specific */ + NULL /* optional */ + }, + { + /* token_cls */ + NULL, /* cmp */ + NULL, /* to_str */ + NULL /* from_str */ + }, + NULL /* optional */ +}; + +static herr_t fake_async_get_cap_flags(const void *info, unsigned *cap_flags); + +#define FAKE_ASYNC_VOL_NAME "fake_async" +#define FAKE_ASYNC_VOL_VALUE ((H5VL_class_value_t)503) + +/* A VOL class struct that describes a VOL class with no + * functionality except to set the async capability flag. + */ +static const H5VL_class_t fake_async_vol_g = { + H5VL_VERSION, /* VOL class struct version */ + FAKE_ASYNC_VOL_VALUE, /* value */ + FAKE_ASYNC_VOL_NAME, /* name */ + 0, /* connector version */ + H5VL_CAP_FLAG_ASYNC, /* capability flags */ + NULL, /* initialize */ + NULL, /* terminate */ + { + /* info_cls */ + (size_t)0, /* size */ + NULL, /* copy */ + NULL, /* compare */ + NULL, /* free */ + NULL, /* to_str */ + NULL, /* from_str */ + }, + { + /* wrap_cls */ + NULL, /* get_object */ + NULL, /* get_wrap_ctx */ + NULL, /* wrap_object */ + NULL, /* unwrap_object */ + NULL, /* free_wrap_ctx */ + }, + { + /* attribute_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* read */ + NULL, /* write */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* dataset_cls */ + NULL, /* create */ + NULL, /* open */ + NULL, /* read */ + NULL, /* write */ + NULL, /* get */ + NULL, /* specific */ + NULL, /* optional */ + NULL /* close */ + }, + { + /* datatype_cls */ NULL, /* commit */ NULL, /* open */ NULL, /* get */ @@ -134,8 +400,9 @@ static const H5VL_class_t fake_vol_g = { }, { /* introspect_cls */ - NULL, /* get_conn_cls */ - NULL, /* opt_query */ + NULL, /* get_conn_cls */ + fake_async_get_cap_flags, /* get_cap_flags */ + NULL, /* opt_query */ }, { /* request_cls */ @@ -163,6 +430,146 @@ static const H5VL_class_t fake_vol_g = { }; /*------------------------------------------------------------------------- + * Function: reg_opt_op_optional_verify + * + * Purpose: Common verification routine for dynamic optional operations + * + * Return: Success: 0 + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +static herr_t +reg_opt_op_optional_verify(void *obj, H5VL_optional_args_t *args) +{ + int *o = (int *)obj; + int *op_args; + + /* Check for receiving correct operation value */ + if (args->op_type != reg_opt_curr_op_val) + return -1; + + /* Check that the object is correct */ + if ((-1) != *o) + return -1; + + /* Update the object, with the operation value */ + *o = args->op_type; + + /* Check that the argument is correct */ + op_args = args->args; + if (NULL == op_args) + return -1; + if ((-1) != *op_args) + return -1; + + /* Update the argument return parameter */ + *op_args = args->op_type; + + return 0; +} /* end reg_opt_op_optional_verify() */ + +/*------------------------------------------------------------------------- + * Function: reg_opt_op_optional + * + * Purpose: Common callback to perform a connector-specific operation + * on an object + * + * Return: Success: 0 + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +static herr_t +reg_opt_op_optional(void *obj, H5VL_optional_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + /* Invoke the common value verification routine */ + return reg_opt_op_optional_verify(obj, args); +} /* end reg_opt_op_optional() */ + +/*------------------------------------------------------------------------- + * Function: reg_opt_link_optional + * + * Purpose: Callback to perform a connector-specific operation + * on a link + * + * Return: Success: 0 + * Failure: -1 + * + *------------------------------------------------------------------------- + */ +static herr_t +reg_opt_link_optional(void *obj, const H5VL_loc_params_t *loc_params, H5VL_optional_args_t *args, + hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) +{ + /* Check for receiving correct loc_params info */ + if (loc_params->type != H5VL_OBJECT_BY_NAME) + return -1; + if (loc_params->obj_type != H5I_GROUP) + return -1; + if (HDstrcmp(loc_params->loc_data.loc_by_name.name, ".") != 0) + return -1; + if (loc_params->loc_data.loc_by_name.lapl_id != H5P_LINK_ACCESS_DEFAULT) + return -1; + + /* Invoke the common value verification routine */ + return reg_opt_op_optional_verify(obj, args); +} /* end reg_opt_link_optional() */ + +/*------------------------------------------------------------------------- + * Function: reg_opt_datatype_get + * + * Purpose: Handles the datatype get callback + * + * Note: This is _strictly_ a testing fixture to support the + * exercise_reg_opt_oper() testing routine. It fakes just + * enough of the named datatype VOL callback for the + * H5VL_register_using_vol_id() call in that test routine to + * succeed. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +reg_opt_datatype_get(void H5_ATTR_UNUSED *obj, H5VL_datatype_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, + void H5_ATTR_UNUSED **req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + if (H5VL_DATATYPE_GET_BINARY_SIZE == args->op_type) { + if (H5Tencode(H5T_NATIVE_INT, NULL, args->args.get_binary_size.size) < 0) + ret_value = FAIL; + } /* end if */ + else if (H5VL_DATATYPE_GET_BINARY == args->op_type) { + if (H5Tencode(H5T_NATIVE_INT, args->args.get_binary.buf, &args->args.get_binary.buf_size) < 0) + ret_value = FAIL; + } /* end if */ + else + ret_value = FAIL; + + return ret_value; +} /* end reg_opt_datatype_get() */ + +/*------------------------------------------------------------------------- + * Function: fake_async_get_cap_flags + * + * Purpose: Return the capability flags for the 'fake async' connector + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +fake_async_get_cap_flags(const void H5_ATTR_UNUSED *info, unsigned *cap_flags) +{ + *cap_flags = fake_async_vol_g.cap_flags; + + return SUCCEED; +} /* end fake_async_get_cap_flags() */ + +/*------------------------------------------------------------------------- * Function: test_vol_registration() * * Purpose: Tests if we can load, register, and close a simple @@ -1176,6 +1583,519 @@ error: } /* end test_basic_datatype_operation() */ +typedef herr_t (*reg_opt_obj_oper_t)(const char *app_file, const char *app_func, unsigned app_line, + hid_t obj_id, H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +typedef herr_t (*reg_opt_link_oper_t)(const char *app_file, const char *app_func, unsigned app_line, + hid_t obj_id, const char *name, hid_t lapl_id, + H5VL_optional_args_t *args, hid_t dxpl_id, hid_t es_id); +typedef union { + reg_opt_obj_oper_t obj_op; + reg_opt_link_oper_t link_op; +} reg_opt_oper_t; + +/*------------------------------------------------------------------------- + * Function: exercise_reg_opt_oper() + * + * Purpose: Exercise a particular optional operation for a type. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +exercise_reg_opt_oper(hid_t fake_vol_id, hid_t reg_opt_vol_id, H5VL_subclass_t subcls, + const char *subcls_name, H5I_type_t id_type, reg_opt_oper_t reg_opt_op) +{ + char op_name[256]; /* Operation name to register */ + hid_t obj_id = H5I_INVALID_HID; + H5VL_object_t * vol_obj; + H5VL_optional_args_t vol_cb_args; + int fake_obj, fake_arg; + int op_val = -1, op_val2 = -1; + int find_op_val; + herr_t ret = SUCCEED; + + /* Test registering optional operation */ + HDsnprintf(op_name, sizeof(op_name), "%s-op1", subcls_name); + if (H5VLregister_opt_operation(subcls, op_name, &op_val) < 0) + TEST_ERROR; + + /* Verify that the reserved amount of optional operations is obeyed */ + /* (The first optional operation registered should be at the lower limit) */ + if (op_val != H5VL_RESERVED_NATIVE_OPTIONAL) + TEST_ERROR; + + /* Look up 1st registered optional operation */ + find_op_val = 0; + if (H5VLfind_opt_operation(subcls, op_name, &find_op_val) < 0) + TEST_ERROR; + + /* Verify that the operation was looked up successfully */ + if (op_val != find_op_val) + TEST_ERROR; + + /* Test registering second optional operation */ + HDsnprintf(op_name, sizeof(op_name), "%s-op2", subcls_name); + if (H5VLregister_opt_operation(subcls, op_name, &op_val2) < 0) + TEST_ERROR; + + /* Verify that the reserved amount of optional operations is obeyed */ + /* (The 2nd optional operation registered should be at the lower limit + 1) */ + if (op_val2 != (H5VL_RESERVED_NATIVE_OPTIONAL + 1)) + TEST_ERROR; + + /* Look up 2nd registered optional operation */ + find_op_val = 0; + if (H5VLfind_opt_operation(subcls, op_name, &find_op_val) < 0) + TEST_ERROR; + + /* Verify that the operation was looked up successfully */ + if (op_val2 != find_op_val) + TEST_ERROR; + + /* Push a new API context on the stack */ + /* (Necessary for the named datatype construction routines) */ + if (H5VL_SUBCLS_DATATYPE == subcls) + H5CX_push(); + + /* Create fake object on fake VOL connector */ + if (H5I_INVALID_HID == (obj_id = H5VL_register_using_vol_id(id_type, &fake_obj, fake_vol_id, TRUE))) + TEST_ERROR; + + /* Pop the API context off the stack */ + if (H5VL_SUBCLS_DATATYPE == subcls) + H5CX_pop(FALSE); + + /* Attempt to issue operation on fake VOL connector */ + fake_obj = -1; + fake_arg = -1; + vol_cb_args.op_type = op_val; + vol_cb_args.args = &fake_arg; + H5E_BEGIN_TRY + { + if (H5VL_SUBCLS_LINK == subcls || H5VL_SUBCLS_OBJECT == subcls) + ret = (*reg_opt_op.link_op)(__FILE__, __func__, __LINE__, obj_id, ".", H5P_DEFAULT, &vol_cb_args, + H5P_DEFAULT, H5ES_NONE); + else + ret = (*reg_opt_op.obj_op)(__FILE__, __func__, __LINE__, obj_id, &vol_cb_args, H5P_DEFAULT, + H5ES_NONE); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to perform an optional operation with a NULL callback"); + if ((-1) != fake_obj) + FAIL_PUTS_ERROR("'fake_obj' changed during failed operation?"); + if ((-1) != fake_arg) + FAIL_PUTS_ERROR("'fake_arg' changed during failed operation?"); + + /* Named datatypes must be destroyed differently */ + if (H5VL_SUBCLS_DATATYPE == subcls) { + H5T_t *dt; + + /* Destroy fake datatype object */ + if (NULL == (dt = H5I_remove(obj_id))) + TEST_ERROR; + if (H5VL_free_object(dt->vol_obj) < 0) + TEST_ERROR; + dt->vol_obj = NULL; + if (H5T_close(dt) < 0) + TEST_ERROR; + } /* end if */ + else { + /* Destroy fake object */ + if (NULL == (vol_obj = H5I_remove(obj_id))) + TEST_ERROR; + if (H5VL_free_object(vol_obj) < 0) + TEST_ERROR; + } /* end else */ + + /* Push a new API context on the stack */ + /* (Necessary for the named datatype construction routines) */ + if (H5VL_SUBCLS_DATATYPE == subcls) + H5CX_push(); + + /* Create fake object on reg_opt VOL connector */ + if (H5I_INVALID_HID == (obj_id = H5VL_register_using_vol_id(id_type, &fake_obj, reg_opt_vol_id, TRUE))) + TEST_ERROR; + + /* Pop the API context off the stack */ + if (H5VL_SUBCLS_DATATYPE == subcls) + H5CX_pop(FALSE); + + /* Issue first operation */ + fake_obj = -1; + fake_arg = -1; + reg_opt_curr_op_val = op_val; + vol_cb_args.op_type = op_val; + vol_cb_args.args = &fake_arg; + if (H5VL_SUBCLS_LINK == subcls || H5VL_SUBCLS_OBJECT == subcls) + ret = (*reg_opt_op.link_op)(__FILE__, __func__, __LINE__, obj_id, ".", H5P_DEFAULT, &vol_cb_args, + H5P_DEFAULT, H5ES_NONE); + else + ret = + (*reg_opt_op.obj_op)(__FILE__, __func__, __LINE__, obj_id, &vol_cb_args, H5P_DEFAULT, H5ES_NONE); + if (ret < 0) + TEST_ERROR; + + /* Verify that fake object & argument were modified correctly */ + if (op_val != fake_obj) + FAIL_PUTS_ERROR("'fake_obj' not updated"); + if (op_val != fake_arg) + FAIL_PUTS_ERROR("'fake_arg' not updated"); + + /* Issue second operation */ + fake_obj = -1; + fake_arg = -1; + reg_opt_curr_op_val = op_val2; + vol_cb_args.op_type = op_val2; + vol_cb_args.args = &fake_arg; + if (H5VL_SUBCLS_LINK == subcls || H5VL_SUBCLS_OBJECT == subcls) + ret = (*reg_opt_op.link_op)(__FILE__, __func__, __LINE__, obj_id, ".", H5P_DEFAULT, &vol_cb_args, + H5P_DEFAULT, H5ES_NONE); + else + ret = + (*reg_opt_op.obj_op)(__FILE__, __func__, __LINE__, obj_id, &vol_cb_args, H5P_DEFAULT, H5ES_NONE); + if (ret < 0) + TEST_ERROR; + + /* Verify that fake object & argument were modified correctly */ + if (op_val2 != fake_obj) + FAIL_PUTS_ERROR("'fake_obj' not updated"); + if (op_val2 != fake_arg) + FAIL_PUTS_ERROR("'fake_arg' not updated"); + + /* Named datatypes must be destroyed differently */ + if (H5VL_SUBCLS_DATATYPE == subcls) { + H5T_t *dt; + + /* Destroy fake datatype object */ + if (NULL == (dt = H5I_remove(obj_id))) + TEST_ERROR; + if (H5VL_free_object(dt->vol_obj) < 0) + TEST_ERROR; + dt->vol_obj = NULL; + if (H5T_close(dt) < 0) + TEST_ERROR; + } /* end if */ + else { + /* Destroy fake object */ + if (NULL == (vol_obj = H5I_remove(obj_id))) + TEST_ERROR; + if (H5VL_free_object(vol_obj) < 0) + TEST_ERROR; + } /* end else */ + + /* Unregister 2nd registered optional operation */ + if (H5VLunregister_opt_operation(subcls, op_name) < 0) + TEST_ERROR; + + return SUCCEED; + +error: + return FAIL; +} /* end exercise_reg_opt_oper() */ + +/*------------------------------------------------------------------------- + * Function: test_register_opt_operation() + * + * Purpose: Tests if we can load, register, and close a simple + * VOL connector. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +test_register_opt_operation(void) +{ + hid_t fake_vol_id = H5I_INVALID_HID; + hid_t reg_opt_vol_id = H5I_INVALID_HID; + struct { + H5VL_subclass_t subcls; + const char * subcls_name; + H5I_type_t id_type; + reg_opt_oper_t reg_opt_op; + } test_params[] = {{H5VL_SUBCLS_ATTR, "attr", H5I_ATTR, {.obj_op = H5VLattr_optional_op}}, + {H5VL_SUBCLS_DATASET, "dataset", H5I_DATASET, {.obj_op = H5VLdataset_optional_op}}, + {H5VL_SUBCLS_DATATYPE, "datatype", H5I_DATATYPE, {.obj_op = H5VLdatatype_optional_op}}, + {H5VL_SUBCLS_FILE, "file", H5I_FILE, {.obj_op = H5VLfile_optional_op}}, + {H5VL_SUBCLS_GROUP, "group", H5I_GROUP, {.obj_op = H5VLgroup_optional_op}}, + {H5VL_SUBCLS_LINK, "link", H5I_GROUP, {.link_op = H5VLlink_optional_op}}, + {H5VL_SUBCLS_OBJECT, "object", H5I_GROUP, {.link_op = H5VLobject_optional_op}}}; + int op_val = -1; + unsigned u; + herr_t ret = SUCCEED; + + TESTING("dynamically registering optional operations"); + + /* Register the VOL connectors for testing */ + if ((fake_vol_id = H5VLregister_connector(&fake_vol_g, H5P_DEFAULT)) < 0) + TEST_ERROR; + if ((reg_opt_vol_id = H5VLregister_connector(®_opt_vol_g, H5P_DEFAULT)) < 0) + TEST_ERROR; + + /* Test registering invalid optional VOL subclass operations */ + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_NONE, "fail", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'NONE' VOL subclass"); + if ((-1) != op_val) + FAIL_PUTS_ERROR("'op_val' changed during failed operation?"); + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_INFO, "fail2", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'INFO' VOL subclass"); + if ((-1) != op_val) + FAIL_PUTS_ERROR("'op_val' changed during failed operation?"); + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_WRAP, "fail3", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'WRAP' VOL subclass"); + if ((-1) != op_val) + FAIL_PUTS_ERROR("'op_val' changed during failed operation?"); + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_BLOB, "fail4", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'BLOB' VOL subclass"); + if ((-1) != op_val) + FAIL_PUTS_ERROR("'op_val' changed during failed operation?"); + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_TOKEN, "fail5", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation for the 'TOKEN' VOL subclass"); + if ((-1) != op_val) + FAIL_PUTS_ERROR("'op_val' changed during failed operation?"); + + /* Test registering valid optional VOL subclass operation with NULL op_val ptr*/ + H5E_BEGIN_TRY + { + ret = H5VLregister_opt_operation(H5VL_SUBCLS_FILE, "fail6", NULL); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to register an optional operation with a NULL 'op_val'"); + + /* Try finding a non-existent optional VOL subclass operation */ + H5E_BEGIN_TRY + { + ret = H5VLfind_opt_operation(H5VL_SUBCLS_DATASET, "fail", &op_val); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to find a non-existent optional operation"); + + /* Try unregistering a non-existent optional VOL subclass operation */ + H5E_BEGIN_TRY + { + ret = H5VLunregister_opt_operation(H5VL_SUBCLS_DATASET, "fail"); + } + H5E_END_TRY; + if (FAIL != ret) + FAIL_PUTS_ERROR("should not be able to unregister a non-existent optional operation"); + + /* Optional operations on requests are supported (but difficult to test further) */ + if (H5VLregister_opt_operation(H5VL_SUBCLS_REQUEST, "req_op", &op_val) < 0) + TEST_ERROR; + + /* Register & test calling optional operations for each valid VOL subclass */ + /* (Table-driven, with test_params array) */ + for (u = 0; u < NELMTS(test_params); u++) + /* Exercise appropriate callback, for each VOL subclass */ + if (exercise_reg_opt_oper(fake_vol_id, reg_opt_vol_id, test_params[u].subcls, + test_params[u].subcls_name, test_params[u].id_type, + test_params[u].reg_opt_op) < 0) + TEST_ERROR; + + /* Unregister the VOL connectors */ + if (H5VLunregister_connector(fake_vol_id) < 0) + TEST_ERROR; + if (H5VLunregister_connector(reg_opt_vol_id) < 0) + TEST_ERROR; + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5VLunregister_connector(fake_vol_id); + H5VLunregister_connector(reg_opt_vol_id); + } + H5E_END_TRY; + + return FAIL; +} /* end test_register_opt_operation() */ + +/*------------------------------------------------------------------------- + * Function: test_async_vol_props() + * + * Purpose: Test properties related to asynchronous VOL connector operation + * + * Note: Overrides the HDF5_VOL_CONNECTOR environment variable, to + * provide stable testing environment. + * + * Return: SUCCEED/FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +test_async_vol_props(void) +{ + hid_t fapl_id = H5I_INVALID_HID; + hid_t vol_id = H5I_INVALID_HID; + H5VL_pass_through_info_t passthru_info; + unsigned cap_flags = 0; + char * conn_env_str = NULL; + + TESTING("Async VOL props"); + + /* Retrieve the file access property for testing */ + fapl_id = h5_fileaccess(); + + /* Test 'capability flags' property */ + + /* Test query w/NULL for cap_flags parameter */ + if (H5Pget_vol_cap_flags(fapl_id, NULL) < 0) + FAIL_STACK_ERROR; + + /* Override possible environment variable & re-initialize default VOL connector */ + conn_env_str = HDgetenv("HDF5_VOL_CONNECTOR"); + if (conn_env_str) { + if (NULL == (conn_env_str = HDstrdup(conn_env_str))) + TEST_ERROR + if (HDunsetenv("HDF5_VOL_CONNECTOR") < 0) + TEST_ERROR + if (H5VL__reparse_def_vol_conn_variable_test() < 0) + TEST_ERROR + } /* end if */ + + /* Test query w/default VOL, which should indicate no async, since native connector + * doesn't support async. + */ + if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0) + FAIL_STACK_ERROR; + if ((cap_flags & H5VL_CAP_FLAG_ASYNC) > 0) + TEST_ERROR + if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) == 0) + TEST_ERROR + + /* Close FAPL */ + if (H5Pclose(fapl_id) < 0) + FAIL_STACK_ERROR; + + /* Register a fake VOL connector that sets the async capability flag */ + if ((vol_id = H5VLregister_connector(&fake_async_vol_g, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Set environment variable to use 'fake async' connector & re-init default connector */ + if (HDsetenv("HDF5_VOL_CONNECTOR", "fake_async", TRUE) < 0) + TEST_ERROR + if (H5VL__reparse_def_vol_conn_variable_test() < 0) + TEST_ERROR + + /* Retrieve the file access property again */ + fapl_id = h5_fileaccess(); + + /* Test query w/fake async VOL, which should succeed */ + cap_flags = 0; + if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0) + FAIL_STACK_ERROR; + if ((cap_flags & H5VL_CAP_FLAG_ASYNC) == 0) + TEST_ERROR + if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) > 0) + TEST_ERROR + + /* Reset environment variable & re-init default connector */ + if (HDunsetenv("HDF5_VOL_CONNECTOR") < 0) + TEST_ERROR + if (H5VL__reparse_def_vol_conn_variable_test() < 0) + TEST_ERROR + + /* Close FAPL */ + if (H5Pclose(fapl_id) < 0) + FAIL_STACK_ERROR; + + /* Retrieve the file access property again */ + fapl_id = h5_fileaccess(); + + /* Set the VOL connector for the FAPL to the fake async connector */ + if (H5Pset_vol(fapl_id, vol_id, NULL) < 0) + FAIL_STACK_ERROR; + + /* Test query w/fake async VOL, which should succeed */ + cap_flags = 0; + if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0) + FAIL_STACK_ERROR; + if ((cap_flags & H5VL_CAP_FLAG_ASYNC) == 0) + TEST_ERROR + if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) > 0) + TEST_ERROR + + /* Stack the [internal] passthrough VOL connector on top of the fake async connector */ + passthru_info.under_vol_id = vol_id; + passthru_info.under_vol_info = NULL; + if (H5Pset_vol(fapl_id, H5VL_PASSTHRU, &passthru_info) < 0) + FAIL_STACK_ERROR; + + /* Test query w/passthru -> fake async VOL, which should succeed */ + cap_flags = 0; + if (H5Pget_vol_cap_flags(fapl_id, &cap_flags) < 0) + FAIL_STACK_ERROR; + if ((cap_flags & H5VL_CAP_FLAG_ASYNC) == 0) + TEST_ERROR + if ((cap_flags & H5VL_CAP_FLAG_NATIVE_FILES) > 0) + TEST_ERROR + + /* Unregister the fake async VOL ID */ + if (H5VLunregister_connector(vol_id) < 0) + TEST_ERROR; + + /* Close FAPL */ + if (H5Pclose(fapl_id) < 0) + FAIL_STACK_ERROR; + + /* Restore environment variable, if there was one */ + if (conn_env_str) { + if (HDsetenv("HDF5_VOL_CONNECTOR", conn_env_str, TRUE) < 0) + TEST_ERROR + HDfree(conn_env_str); + + if (H5VL__reparse_def_vol_conn_variable_test() < 0) + TEST_ERROR + } /* end if */ + + PASSED(); + + return SUCCEED; + +error: + H5E_BEGIN_TRY + { + H5Pclose(fapl_id); + H5VLunregister_connector(vol_id); + } + H5E_END_TRY; + HDfree(conn_env_str); + + return FAIL; +} /* end test_async_vol_props() */ + /*------------------------------------------------------------------------- * Function: main * @@ -1201,6 +2121,7 @@ main(void) HDputs("Testing basic Virtual Object Layer (VOL) functionality."); nerrors += test_vol_registration() < 0 ? 1 : 0; + nerrors += test_register_opt_operation() < 0 ? 1 : 0; nerrors += test_native_vol_init() < 0 ? 1 : 0; nerrors += test_basic_file_operation(env_h5_drvr) < 0 ? 1 : 0; nerrors += test_basic_group_operation() < 0 ? 1 : 0; @@ -1209,6 +2130,7 @@ main(void) nerrors += test_basic_object_operation() < 0 ? 1 : 0; nerrors += test_basic_link_operation() < 0 ? 1 : 0; nerrors += test_basic_datatype_operation() < 0 ? 1 : 0; + nerrors += test_async_vol_props() < 0 ? 1 : 0; if (nerrors) { HDprintf("***** %d Virtual Object Layer TEST%s FAILED! *****\n", nerrors, nerrors > 1 ? "S" : ""); diff --git a/testpar/t_filters_parallel.c b/testpar/t_filters_parallel.c index 694992a..78af0fb 100644 --- a/testpar/t_filters_parallel.c +++ b/testpar/t_filters_parallel.c @@ -62,6 +62,7 @@ static void test_write_filtered_dataset_single_no_selection(void); static void test_write_filtered_dataset_all_no_selection(void); static void test_write_filtered_dataset_point_selection(void); static void test_write_filtered_dataset_interleaved_write(void); +static void test_write_transformed_filtered_dataset_no_overlap(void); static void test_write_3d_filtered_dataset_no_overlap_separate_pages(void); static void test_write_3d_filtered_dataset_no_overlap_same_pages(void); static void test_write_3d_filtered_dataset_overlap(void); @@ -79,6 +80,7 @@ static void test_read_filtered_dataset_single_no_selection(void); static void test_read_filtered_dataset_all_no_selection(void); static void test_read_filtered_dataset_point_selection(void); static void test_read_filtered_dataset_interleaved_read(void); +static void test_read_transformed_filtered_dataset_no_overlap(void); static void test_read_3d_filtered_dataset_no_overlap_separate_pages(void); static void test_read_3d_filtered_dataset_no_overlap_same_pages(void); static void test_read_3d_filtered_dataset_overlap(void); @@ -120,6 +122,7 @@ static void (*tests[])(void) = { test_write_filtered_dataset_all_no_selection, test_write_filtered_dataset_point_selection, test_write_filtered_dataset_interleaved_write, + test_write_transformed_filtered_dataset_no_overlap, test_write_3d_filtered_dataset_no_overlap_separate_pages, test_write_3d_filtered_dataset_no_overlap_same_pages, test_write_3d_filtered_dataset_overlap, @@ -135,6 +138,7 @@ static void (*tests[])(void) = { test_read_filtered_dataset_all_no_selection, test_read_filtered_dataset_point_selection, test_read_filtered_dataset_interleaved_read, + test_read_transformed_filtered_dataset_no_overlap, test_read_3d_filtered_dataset_no_overlap_separate_pages, test_read_3d_filtered_dataset_no_overlap_same_pages, test_read_3d_filtered_dataset_overlap, @@ -428,7 +432,7 @@ test_write_filtered_dataset_no_overlap(void) /* Select hyperslab in the file */ filespace = H5Dget_space(dset_id); - VRFY((dset_id >= 0), "File dataspace retrieval succeeded"); + VRFY((filespace >= 0), "File dataspace retrieval succeeded"); VRFY((H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, stride, count, block) >= 0), "Hyperslab selection succeeded"); @@ -1288,6 +1292,177 @@ test_write_filtered_dataset_interleaved_write(void) } /* + * Tests parallel write of transformed and filtered data + * in the case where only one process is writing to a + * particular chunk in the operation. Normally, a data + * transform function will cause the parallel library to + * break to independent I/O and this isn't allowed when + * there are filters in the pipeline. However, in this + * case the parallel library recognizes that the used + * data transform function "x" is the same as not applying + * the transform function. Therefore it does not apply + * the transform function resulting in not breaking to + * independent I/O. + * + * Programmer: Jan-Willem Blokland + * 08/20/2021 + */ +static void +test_write_transformed_filtered_dataset_no_overlap(void) +{ + C_DATATYPE *data = NULL; + C_DATATYPE *read_buf = NULL; + C_DATATYPE *correct_buf = NULL; + hsize_t dataset_dims[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t chunk_dims[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t sel_dims[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t start[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t stride[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t count[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t block[WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + size_t i, data_size, correct_buf_size; + hid_t file_id = -1, dset_id = -1, plist_id = -1; + hid_t filespace = -1, memspace = -1; + + if (MAINPROCESS) + HDputs("Testing write to unshared transformed and filtered chunks"); + + CHECK_CUR_FILTER_AVAIL(); + + /* Set up file access property list with parallel I/O access */ + plist_id = H5Pcreate(H5P_FILE_ACCESS); + VRFY((plist_id >= 0), "FAPL creation succeeded"); + + VRFY((H5Pset_fapl_mpio(plist_id, comm, info) >= 0), "Set FAPL MPIO succeeded"); + + VRFY((H5Pset_libver_bounds(plist_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) >= 0), + "Set libver bounds succeeded"); + + file_id = H5Fopen(filenames[0], H5F_ACC_RDWR, plist_id); + VRFY((file_id >= 0), "Test file open succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "FAPL close succeeded"); + + /* Create the dataspace for the dataset */ + dataset_dims[0] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS; + dataset_dims[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS; + chunk_dims[0] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + chunk_dims[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + sel_dims[0] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + sel_dims[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS; + + filespace = H5Screate_simple(WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS, dataset_dims, NULL); + VRFY((filespace >= 0), "File dataspace creation succeeded"); + + memspace = H5Screate_simple(WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS, sel_dims, NULL); + VRFY((memspace >= 0), "Memory dataspace creation succeeded"); + + /* Create chunked dataset */ + plist_id = H5Pcreate(H5P_DATASET_CREATE); + VRFY((plist_id >= 0), "DCPL creation succeeded"); + + VRFY((H5Pset_chunk(plist_id, WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS, chunk_dims) >= 0), + "Chunk size set"); + + /* Add test filter to the pipeline */ + VRFY((set_dcpl_filter(plist_id) >= 0), "Filter set"); + + dset_id = H5Dcreate2(file_id, WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME, HDF5_DATATYPE_NAME, + filespace, H5P_DEFAULT, plist_id, H5P_DEFAULT); + VRFY((dset_id >= 0), "Dataset creation succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "DCPL close succeeded"); + VRFY((H5Sclose(filespace) >= 0), "File dataspace close succeeded"); + + /* Each process defines the dataset selection in memory and writes + * it to the hyperslab in the file + */ + count[0] = 1; + count[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS / + (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + stride[0] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + stride[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + block[0] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + block[1] = (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + start[0] = ((hsize_t)mpi_rank * (hsize_t)WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS * count[0]); + start[1] = 0; + + if (VERBOSE_MED) { + HDprintf("Process %d is writing with count[ %" PRIuHSIZE ", %" PRIuHSIZE " ], stride[ %" PRIuHSIZE + ", %" PRIuHSIZE " ], start[ %" PRIuHSIZE ", %" PRIuHSIZE " ], block size[ %" PRIuHSIZE + ", %" PRIuHSIZE " ]\n", + mpi_rank, count[0], count[1], stride[0], stride[1], start[0], start[1], block[0], block[1]); + HDfflush(stdout); + } + + /* Select hyperslab in the file */ + filespace = H5Dget_space(dset_id); + VRFY((filespace >= 0), "File dataspace retrieval succeeded"); + + VRFY((H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, stride, count, block) >= 0), + "Hyperslab selection succeeded"); + + /* Fill data buffer */ + data_size = sel_dims[0] * sel_dims[1] * sizeof(*data); + correct_buf_size = dataset_dims[0] * dataset_dims[1] * sizeof(*correct_buf); + + data = (C_DATATYPE *)HDcalloc(1, data_size); + VRFY((NULL != data), "HDcalloc succeeded"); + + correct_buf = (C_DATATYPE *)HDcalloc(1, correct_buf_size); + VRFY((NULL != correct_buf), "HDcalloc succeeded"); + + for (i = 0; i < data_size / sizeof(*data); i++) + data[i] = (C_DATATYPE)GEN_DATA(i); + + for (i = 0; i < correct_buf_size / sizeof(*correct_buf); i++) + correct_buf[i] = (C_DATATYPE)((i % (dataset_dims[0] / (hsize_t)mpi_size * dataset_dims[1])) + + (i / (dataset_dims[0] / (hsize_t)mpi_size * dataset_dims[1]))); + + /* Create property list for collective dataset write and data transform */ + plist_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((plist_id >= 0), "DXPL creation succeeded"); + + VRFY((H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE) >= 0), "Set DXPL MPIO succeeded"); + + /* Set data transform expression */ + VRFY((H5Pset_data_transform(plist_id, "x") >= 0), "Set data transform expression succeeded"); + + VRFY((H5Dwrite(dset_id, HDF5_DATATYPE_NAME, memspace, filespace, plist_id, data) >= 0), + "Dataset write succeeded"); + + if (data) + HDfree(data); + + VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + + /* Verify the correct data was written */ + read_buf = (C_DATATYPE *)HDcalloc(1, correct_buf_size); + VRFY((NULL != read_buf), "HDcalloc succeeded"); + + dset_id = H5Dopen2(file_id, "/" WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME, H5P_DEFAULT); + VRFY((dset_id >= 0), "Dataset open succeeded"); + + VRFY((H5Dread(dset_id, HDF5_DATATYPE_NAME, H5S_ALL, H5S_ALL, plist_id, read_buf) >= 0), + "Dataset read succeeded"); + + VRFY((0 == HDmemcmp(read_buf, correct_buf, correct_buf_size)), "Data verification succeeded"); + + if (correct_buf) + HDfree(correct_buf); + if (read_buf) + HDfree(read_buf); + + VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + VRFY((H5Sclose(filespace) >= 0), "File dataspace close succeeded"); + VRFY((H5Sclose(memspace) >= 0), "Memory dataspace close succeeded"); + VRFY((H5Pclose(plist_id) >= 0), "DXPL close succeeded"); + VRFY((H5Fclose(file_id) >= 0), "File close succeeded"); + + return; +} + +/* * Tests parallel write of filtered data in the case where * the dataset has 3 dimensions and each process writes * to its own "page" in the 3rd dimension. @@ -4224,6 +4399,232 @@ test_read_3d_filtered_dataset_no_overlap_separate_pages(void) } /* + * Tests parallel read of transformed and filtered data in the + * case where only one process is reading from a particular + * chunk in the operation. Normally, a data transform function + * will cause the parallel library to break to independent I/O + * and this isn't allowed when there are filters in the pipeline. + * However, in this case the parallel library recognizes that + * the used data transform function "x" is the same as not + * applying the transform function. Therefore it does not apply + * the transform function resulting in not breaking to + * independent I/O. + * + * The MAINPROCESS rank will first write out all of the + * data to the dataset. Then, each rank reads a part of + * the dataset and contributes its piece to a global buffer + * that is checked for consistency. + * + * Programmer: Jan-Willem Blokland + * 08/20/2021 + */ +static void +test_read_transformed_filtered_dataset_no_overlap(void) +{ + C_DATATYPE *read_buf = NULL; + C_DATATYPE *correct_buf = NULL; + C_DATATYPE *global_buf = NULL; + hsize_t dataset_dims[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t chunk_dims[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t sel_dims[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t start[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t stride[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t count[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t block[READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS]; + hsize_t flat_dims[1]; + size_t i, read_buf_size, correct_buf_size; + hid_t file_id = -1, dset_id = -1, plist_id = -1; + hid_t filespace = -1, memspace = -1; + int * recvcounts = NULL; + int * displs = NULL; + + if (MAINPROCESS) + HDputs("Testing read from unshared transformed and filtered chunks"); + + CHECK_CUR_FILTER_AVAIL(); + + dataset_dims[0] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS; + dataset_dims[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS; + + /* Setup the buffer for writing and for comparison */ + correct_buf_size = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS * + (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS * sizeof(*correct_buf); + + correct_buf = (C_DATATYPE *)HDcalloc(1, correct_buf_size); + VRFY((NULL != correct_buf), "HDcalloc succeeded"); + + for (i = 0; i < correct_buf_size / sizeof(*correct_buf); i++) + correct_buf[i] = (C_DATATYPE)((i % (dataset_dims[0] / (hsize_t)mpi_size * dataset_dims[1])) + + (i / (dataset_dims[0] / (hsize_t)mpi_size * dataset_dims[1]))); + + if (MAINPROCESS) { + plist_id = H5Pcreate(H5P_FILE_ACCESS); + VRFY((plist_id >= 0), "FAPL creation succeeded"); + + VRFY((H5Pset_libver_bounds(plist_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) >= 0), + "Set libver bounds succeeded"); + + file_id = H5Fopen(filenames[0], H5F_ACC_RDWR, plist_id); + VRFY((file_id >= 0), "Test file open succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "FAPL close succeeded"); + + /* Create the dataspace for the dataset */ + filespace = + H5Screate_simple(READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS, dataset_dims, NULL); + VRFY((filespace >= 0), "File dataspace creation succeeded"); + + /* Create chunked dataset */ + chunk_dims[0] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + chunk_dims[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + + plist_id = H5Pcreate(H5P_DATASET_CREATE); + VRFY((plist_id >= 0), "DCPL creation succeeded"); + + VRFY( + (H5Pset_chunk(plist_id, READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS, chunk_dims) >= 0), + "Chunk size set"); + + /* Add test filter to the pipeline */ + VRFY((set_dcpl_filter(plist_id) >= 0), "Filter set"); + + dset_id = H5Dcreate2(file_id, READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME, + HDF5_DATATYPE_NAME, filespace, H5P_DEFAULT, plist_id, H5P_DEFAULT); + VRFY((dset_id >= 0), "Dataset creation succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "DCPL close succeeded"); + VRFY((H5Sclose(filespace) >= 0), "File dataspace close succeeded"); + + /* Create property list for collective dataset read */ + plist_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((plist_id >= 0), "DXPL creation succeeded"); + + /* Set data transform expression */ + VRFY((H5Pset_data_transform(plist_id, "x") >= 0), "Set data transform expression succeeded"); + + VRFY((H5Dwrite(dset_id, HDF5_DATATYPE_NAME, H5S_ALL, H5S_ALL, plist_id, correct_buf) >= 0), + "Dataset write succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "DXPL close succeeded"); + VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + VRFY((H5Fclose(file_id) >= 0), "File close succeeded"); + } + + /* Set up file access property list with parallel I/O access */ + plist_id = H5Pcreate(H5P_FILE_ACCESS); + VRFY((plist_id >= 0), "FAPL creation succeeded"); + + VRFY((H5Pset_fapl_mpio(plist_id, comm, info) >= 0), "Set FAPL MPIO succeeded"); + + VRFY((H5Pset_libver_bounds(plist_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) >= 0), + "Set libver bounds succeeded"); + + file_id = H5Fopen(filenames[0], H5F_ACC_RDONLY, plist_id); + VRFY((file_id >= 0), "Test file open succeeded"); + + VRFY((H5Pclose(plist_id) >= 0), "FAPL close succeeded"); + + dset_id = H5Dopen2(file_id, "/" READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME, H5P_DEFAULT); + VRFY((dset_id >= 0), "Dataset open succeeded"); + + sel_dims[0] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + sel_dims[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS; + + /* Setup one-dimensional memory dataspace for reading the dataset data into a contiguous buffer */ + flat_dims[0] = sel_dims[0] * sel_dims[1]; + + memspace = H5Screate_simple(1, flat_dims, NULL); + VRFY((memspace >= 0), "Memory dataspace creation succeeded"); + + /* Select hyperslab in the file */ + filespace = H5Dget_space(dset_id); + VRFY((filespace >= 0), "File dataspace retrieval succeeded"); + + /* + * Each process defines the dataset selection in the file and reads + * it to the selection in memory + */ + count[0] = 1; + count[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS / + (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + stride[0] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + stride[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + block[0] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS; + block[1] = (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS; + start[0] = ((hsize_t)mpi_rank * (hsize_t)READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS * count[0]); + start[1] = 0; + + if (VERBOSE_MED) { + HDprintf("Process %d is reading with count[ %" PRIuHSIZE ", %" PRIuHSIZE " ], stride[ %" PRIuHSIZE + ", %" PRIuHSIZE " ], start[ %" PRIuHSIZE ", %" PRIuHSIZE " ], block size[ %" PRIuHSIZE + ", %" PRIuHSIZE " ]\n", + mpi_rank, count[0], count[1], stride[0], stride[1], start[0], start[1], block[0], block[1]); + HDfflush(stdout); + } + + VRFY((H5Sselect_hyperslab(filespace, H5S_SELECT_SET, start, stride, count, block) >= 0), + "Hyperslab selection succeeded"); + + /* Create property list for collective dataset read and data transform */ + plist_id = H5Pcreate(H5P_DATASET_XFER); + VRFY((plist_id >= 0), "DXPL creation succeeded"); + + VRFY((H5Pset_dxpl_mpio(plist_id, H5FD_MPIO_COLLECTIVE) >= 0), "Set DXPL MPIO succeeded"); + + /* Set data transform expression */ + VRFY((H5Pset_data_transform(plist_id, "x") >= 0), "Set data transform expression succeeded"); + + read_buf_size = flat_dims[0] * sizeof(*read_buf); + + read_buf = (C_DATATYPE *)HDcalloc(1, read_buf_size); + VRFY((NULL != read_buf), "HDcalloc succeeded"); + + VRFY((H5Dread(dset_id, HDF5_DATATYPE_NAME, memspace, filespace, plist_id, read_buf) >= 0), + "Dataset read succeeded"); + + global_buf = (C_DATATYPE *)HDcalloc(1, correct_buf_size); + VRFY((NULL != global_buf), "HDcalloc succeeded"); + + /* Collect each piece of data from all ranks into a global buffer on all ranks */ + recvcounts = (int *)HDcalloc(1, (size_t)mpi_size * sizeof(*recvcounts)); + VRFY((NULL != recvcounts), "HDcalloc succeeded"); + + for (i = 0; i < (size_t)mpi_size; i++) + recvcounts[i] = (int)flat_dims[0]; + + displs = (int *)HDcalloc(1, (size_t)mpi_size * sizeof(*displs)); + VRFY((NULL != displs), "HDcalloc succeeded"); + + for (i = 0; i < (size_t)mpi_size; i++) + displs[i] = (int)(i * flat_dims[0]); + + VRFY((MPI_SUCCESS == MPI_Allgatherv(read_buf, (int)flat_dims[0], C_DATATYPE_MPI, global_buf, recvcounts, + displs, C_DATATYPE_MPI, comm)), + "MPI_Allgatherv succeeded"); + + VRFY((0 == HDmemcmp(global_buf, correct_buf, correct_buf_size)), "Data verification succeeded"); + + if (displs) + HDfree(displs); + if (recvcounts) + HDfree(recvcounts); + if (global_buf) + HDfree(global_buf); + if (read_buf) + HDfree(read_buf); + if (correct_buf) + HDfree(correct_buf); + + VRFY((H5Dclose(dset_id) >= 0), "Dataset close succeeded"); + VRFY((H5Sclose(filespace) >= 0), "File dataspace close succeeded"); + VRFY((H5Sclose(memspace) >= 0), "Memory dataspace close succeeded"); + VRFY((H5Pclose(plist_id) >= 0), "DXPL close succeeded"); + VRFY((H5Fclose(file_id) >= 0), "File close succeeded"); + + return; +} + +/* * Tests parallel read of filtered data in the case where * the dataset has 3 dimensions and each process reads from * each "page" in the 3rd dimension. However, no chunk on a diff --git a/testpar/t_filters_parallel.h b/testpar/t_filters_parallel.h index 3804c09..7eb34ed 100644 --- a/testpar/t_filters_parallel.h +++ b/testpar/t_filters_parallel.h @@ -138,6 +138,16 @@ typedef struct { #define INTERLEAVED_WRITE_FILTERED_DATASET_NCOLS \ (INTERLEAVED_WRITE_FILTERED_DATASET_CH_NCOLS * DIM1_SCALE_FACTOR) +/* Defines for the unshared transformed and filtered chunks write test */ +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME "unshared_transformed_filtered_chunks_write" +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS 2 +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS (mpi_size * DIM0_SCALE_FACTOR) +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS (mpi_size * DIM1_SCALE_FACTOR) +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS \ + (WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS / mpi_size) +#define WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS \ + (WRITE_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS / mpi_size) + /* Defines for the 3D unshared filtered dataset separate page write test */ #define WRITE_UNSHARED_FILTERED_CHUNKS_3D_SEP_PAGE_DATASET_NAME \ "3D_unshared_filtered_chunks_separate_pages_write" @@ -280,6 +290,16 @@ typedef struct { #define INTERLEAVED_READ_FILTERED_DATASET_NCOLS \ (INTERLEAVED_READ_FILTERED_DATASET_CH_NCOLS * DIM1_SCALE_FACTOR) +/* Defines for the unshared transformed and filtered chunks read test */ +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_NAME "unshared_transformed_filtered_chunks_read" +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_DATASET_DIMS 2 +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS (mpi_size * DIM0_SCALE_FACTOR) +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS (mpi_size * DIM1_SCALE_FACTOR) +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NROWS \ + (READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NROWS / mpi_size) +#define READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_CH_NCOLS \ + (READ_UNSHARED_TRANSFORMED_FILTERED_CHUNKS_NCOLS / mpi_size) + /* Defines for the 3D unshared filtered dataset separate page read test */ #define READ_UNSHARED_FILTERED_CHUNKS_3D_SEP_PAGE_DATASET_NAME \ "3D_unshared_filtered_chunks_separate_pages_read" diff --git a/tools/lib/h5diff_array.c b/tools/lib/h5diff_array.c index 43ded12..2d6c66c 100644 --- a/tools/lib/h5diff_array.c +++ b/tools/lib/h5diff_array.c @@ -104,9 +104,9 @@ static hbool_t not_comparable; per = -1; \ not_comparable = FALSE; \ both_zero = FALSE; \ - if (H5_DBL_ABS_EQUAL(0, (double)A) && H5_DBL_ABS_EQUAL(0, (double)B)) \ + if (H5_DBL_ABS_EQUAL(0, (double)(A)) && H5_DBL_ABS_EQUAL(0, (double)(B))) \ both_zero = TRUE; \ - if (!H5_DBL_ABS_EQUAL(0, (double)A)) \ + if (!H5_DBL_ABS_EQUAL(0, (double)(A))) \ per = (double)ABS((double)((B) - (A)) / (double)(A)); \ else \ not_comparable = TRUE; \ @@ -117,9 +117,9 @@ static hbool_t not_comparable; per = -1; \ not_comparable = FALSE; \ both_zero = FALSE; \ - if (H5_DBL_ABS_EQUAL(0, (double)A) && H5_DBL_ABS_EQUAL(0, (double)B)) \ + if (H5_DBL_ABS_EQUAL(0, (double)(A)) && H5_DBL_ABS_EQUAL(0, (double)(B))) \ both_zero = TRUE; \ - if (!H5_DBL_ABS_EQUAL(0, (double)A)) \ + if (!H5_DBL_ABS_EQUAL(0, (double)(A))) \ per = ABS((double)((TYPE)((B) - (A))) / (double)(A)); \ else \ not_comparable = TRUE; \ diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c index 5fcaee6..abc0058 100644 --- a/tools/lib/h5tools_str.c +++ b/tools/lib/h5tools_str.c @@ -258,7 +258,8 @@ h5tools_str_fmt(h5tools_str_t *str /*in,out*/, size_t start, const char *fmt) HDassert(temp); } - HDstrncpy(temp, str->s + start, n); + HDstrncpy(temp, str->s + start, n - 1); + temp[n - 1] = '\0'; } /* Reset the output string and append a formatted version */ diff --git a/tools/libtest/Makefile.am b/tools/libtest/Makefile.am index a93e25d..1a08a01 100644 --- a/tools/libtest/Makefile.am +++ b/tools/libtest/Makefile.am @@ -1,16 +1,16 @@ # -# Read-Only S3 Virtual File Driver (VFD) -# Copyright (c) 2017-2018, The HDF Group. -# +# Copyright by The HDF Group. # All rights reserved. # # NOTICE: -# All information contained herein is, and remains, the property of The HDF -# Group. The intellectual and technical concepts contained herein are -# proprietary to The HDF Group. Dissemination of this information or -# reproduction of this material is strictly forbidden unless prior written -# permission is obtained from The HDF Group. -## +# +# 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://www.hdfgroup.org/licenses. +# If you do not have access to either file, you may request a copy from +# help@hdfgroup.org. +# ## Makefile.am ## Run automake to generate a Makefile.in from this file. # diff --git a/tools/libtest/h5tools_test_utils.c b/tools/libtest/h5tools_test_utils.c index ba3877e..66d7ac7 100644 --- a/tools/libtest/h5tools_test_utils.c +++ b/tools/libtest/h5tools_test_utils.c @@ -69,7 +69,7 @@ * *****************************************************************************/ -H5_GCC_DIAG_OFF("format") +H5_GCC_CLANG_DIAG_OFF("format") /*---------------------------------------------------------------------------- * @@ -1255,7 +1255,7 @@ error: #undef UTIL_TEST_DEFAULT #undef UTIL_TEST_CREATE } /* test_set_configured_fapl */ -H5_GCC_DIAG_ON("format") +H5_GCC_CLANG_DIAG_ON("format") /*---------------------------------------------------------------------------- * diff --git a/tools/src/CMakeLists.txt b/tools/src/CMakeLists.txt index 8c3e361..e291f61 100644 --- a/tools/src/CMakeLists.txt +++ b/tools/src/CMakeLists.txt @@ -13,7 +13,7 @@ add_subdirectory (misc) #-- Add the h5import and test executables add_subdirectory (h5import) -#-- h5Repack executables +#-- h5repack executables add_subdirectory (h5repack) #-- Add the h5dump and test executables @@ -30,3 +30,6 @@ add_subdirectory (h5dump) #-- Add the h5format_convert and test executables add_subdirectory (h5format_convert) + +#-- h5perf executables +add_subdirectory (h5perf) diff --git a/tools/src/Makefile.am b/tools/src/Makefile.am index 397bd31..5af7d06 100644 --- a/tools/src/Makefile.am +++ b/tools/src/Makefile.am @@ -23,6 +23,6 @@ CONFIG=ordered # All subdirectories SUBDIRS=h5diff h5ls h5dump misc h5import h5repack h5jam h5copy \ - h5format_convert h5stat + h5format_convert h5stat h5perf include $(top_srcdir)/config/conclude.am diff --git a/tools/src/h5dump/h5dump.c b/tools/src/h5dump/h5dump.c index 70f03df..36114ba 100644 --- a/tools/src/h5dump/h5dump.c +++ b/tools/src/h5dump/h5dump.c @@ -82,124 +82,46 @@ struct handler_t { /* "xxx" "yyy" into "xxxyyy". */ static const char * s_opts = "a:b*c:d:ef:g:hik:l:m:n*o*pq:rs:t:uvw:xyz:A*BCD:E*F:G:HM:N:O*RS:VX:"; static struct h5_long_options l_opts[] = {{"attribute", require_arg, 'a'}, - {"attribut", require_arg, 'a'}, - {"attribu", require_arg, 'a'}, - {"attrib", require_arg, 'a'}, - {"attri", require_arg, 'a'}, - {"attr", require_arg, 'a'}, - {"att", require_arg, 'a'}, - {"at", require_arg, 'a'}, {"binary", optional_arg, 'b'}, {"count", require_arg, 'c'}, - {"coun", require_arg, 'c'}, - {"cou", require_arg, 'c'}, - {"co", require_arg, 'c'}, {"dataset", require_arg, 'd'}, - {"datase", require_arg, 'd'}, - {"datas", require_arg, 'd'}, {"escape", no_arg, 'e'}, {"filedriver", require_arg, 'f'}, - {"filedrive", require_arg, 'f'}, - {"filedriv", require_arg, 'f'}, - {"filedri", require_arg, 'f'}, - {"filedr", require_arg, 'f'}, - {"filed", require_arg, 'f'}, - {"file", require_arg, 'f'}, - {"fil", require_arg, 'f'}, - {"fi", require_arg, 'f'}, {"group", require_arg, 'g'}, - {"grou", require_arg, 'g'}, - {"gro", require_arg, 'g'}, - {"gr", require_arg, 'g'}, {"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, {"object-ids", no_arg, 'i'}, - {"object-id", no_arg, 'i'}, - {"object-i", no_arg, 'i'}, - {"object", no_arg, 'i'}, - {"objec", no_arg, 'i'}, - {"obje", no_arg, 'i'}, - {"obj", no_arg, 'i'}, - {"ob", no_arg, 'i'}, {"block", require_arg, 'k'}, - {"bloc", require_arg, 'k'}, - {"blo", require_arg, 'k'}, - {"bl", require_arg, 'k'}, {"soft-link", require_arg, 'l'}, - {"soft-lin", require_arg, 'l'}, - {"soft-li", require_arg, 'l'}, - {"soft-l", require_arg, 'l'}, - {"soft", require_arg, 'l'}, - {"sof", require_arg, 'l'}, {"format", require_arg, 'm'}, {"contents", optional_arg, 'n'}, {"output", optional_arg, 'o'}, - {"outpu", optional_arg, 'o'}, - {"outp", optional_arg, 'o'}, - {"out", optional_arg, 'o'}, - {"ou", optional_arg, 'o'}, {"properties", no_arg, 'p'}, {"sort_by", require_arg, 'q'}, {"string", no_arg, 'r'}, - {"strin", no_arg, 'r'}, {"start", require_arg, 's'}, - {"star", require_arg, 's'}, - {"sta", require_arg, 's'}, {"datatype", require_arg, 't'}, - {"datatyp", require_arg, 't'}, - {"dataty", require_arg, 't'}, - {"datat", require_arg, 't'}, {"use-dtd", no_arg, 'u'}, - {"use-dt", no_arg, 'u'}, - {"use-d", no_arg, 'u'}, - {"use-", no_arg, 'u'}, - {"use", no_arg, 'u'}, - {"us", no_arg, 'u'}, - {"u", no_arg, 'u'}, {"vds-view-first-missing", no_arg, 'v'}, {"width", require_arg, 'w'}, - {"widt", require_arg, 'w'}, - {"wid", require_arg, 'w'}, - {"wi", require_arg, 'w'}, {"xml", no_arg, 'x'}, - {"xm", no_arg, 'x'}, {"noindex", no_arg, 'y'}, {"sort_order", require_arg, 'z'}, {"onlyattr", optional_arg, 'A'}, {"superblock", no_arg, 'B'}, {"boot-block", no_arg, 'B'}, - {"boot-bloc", no_arg, 'B'}, - {"boot-blo", no_arg, 'B'}, - {"boot-bl", no_arg, 'B'}, - {"boot-b", no_arg, 'B'}, - {"boot", no_arg, 'B'}, - {"boo", no_arg, 'B'}, - {"bo", no_arg, 'B'}, {"no-compact-subset", no_arg, 'C'}, {"xml-dtd", require_arg, 'D'}, - {"xml-dt", require_arg, 'D'}, - {"xml-d", require_arg, 'D'}, {"enable-error-stack", optional_arg, 'E'}, {"form", require_arg, 'F'}, {"vds-gap-size", require_arg, 'G'}, {"header", no_arg, 'H'}, - {"heade", no_arg, 'H'}, - {"head", no_arg, 'H'}, - {"hea", no_arg, 'H'}, {"packed-bits", require_arg, 'M'}, {"any_path", require_arg, 'N'}, {"ddl", optional_arg, 'O'}, {"region", no_arg, 'R'}, {"stride", require_arg, 'S'}, - {"strid", require_arg, 'S'}, {"version", no_arg, 'V'}, - {"versio", no_arg, 'V'}, - {"versi", no_arg, 'V'}, - {"vers", no_arg, 'V'}, - {"ver", no_arg, 'V'}, - {"ve", no_arg, 'V'}, {"xml-ns", require_arg, 'X'}, - {"xml-n", require_arg, 'X'}, {"s3-cred", require_arg, '$'}, {"hdfs-attrs", require_arg, '#'}, {"vol-value", require_arg, '1'}, diff --git a/tools/src/h5dump/h5dump_ddl.c b/tools/src/h5dump/h5dump_ddl.c index 2a69ca6..638a738 100644 --- a/tools/src/h5dump/h5dump_ddl.c +++ b/tools/src/h5dump/h5dump_ddl.c @@ -1343,13 +1343,21 @@ attr_search(hid_t oid, const char *attr_name, const H5A_info_t H5_ATTR_UNUSED *a ret = FAIL; } else { + size_t buffer_space = w - 1; + HDmemset(obj_name, '\0', w); if (op_name[0] != '/') { - HDstrncat(obj_name, buf, u + 1); - if (buf[u - 1] != '/') - HDstrncat(obj_name, "/", (size_t)2); + HDstrncat(obj_name, buf, buffer_space); + buffer_space -= MIN(buffer_space, u); + + if (buf[u - 1] != '/') { + HDstrncat(obj_name, "/", buffer_space); + buffer_space -= MIN(buffer_space, 2); + } } - HDstrncat(obj_name, op_name, v + 1); + + HDstrncat(obj_name, op_name, buffer_space); + buffer_space -= MIN(buffer_space, v); handle_attributes(oid, obj_name, NULL, 0, NULL); HDfree(obj_name); @@ -1421,10 +1429,10 @@ lnk_search(const char *path, const H5L_info2_t *li, void *_op_data) else { if (k == 2) { HDstrcpy(search_name, "/"); - HDstrncat(search_name, op_name, search_len + 1); + HDstrcat(search_name, op_name); } else - HDstrncpy(search_name, op_name, search_len + 1); + HDstrcpy(search_name, op_name); search_name[search_len + k - 1] = '\0'; if (HDstrcmp(path, search_name) == 0) { diff --git a/tools/src/h5dump/h5dump_xml.c b/tools/src/h5dump/h5dump_xml.c index 5507dcc..0e881df 100644 --- a/tools/src/h5dump/h5dump_xml.c +++ b/tools/src/h5dump/h5dump_xml.c @@ -2365,14 +2365,21 @@ xml_dump_named_datatype(hid_t type, const char *name) h5tools_context_t ctx; /* print context */ h5tool_format_t * outputformat = &xml_dataformat; h5tool_format_t string_dataformat; - char * tmp; - char * dtxid; - char * parentxid; - char * t_tmp; - char * t_prefix; - char * t_name; + char * tmp = NULL; + char * dtxid = NULL; + char * parentxid = NULL; + char * t_tmp = NULL; + char * t_prefix = NULL; + char * t_name = NULL; tmp = (char *)HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2); + if (tmp == NULL) { + indentation(dump_indent); + error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); + h5tools_setstatus(EXIT_FAILURE); + goto done; + } + HDstrcpy(tmp, prefix); HDstrcat(tmp, "/"); HDstrcat(tmp, name); @@ -2627,6 +2634,13 @@ xml_dump_group(hid_t gid, const char *name) } else { tmp = (char *)HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2); + if (tmp == NULL) { + indentation(dump_indent); + error_msg("internal error (file %s:line %d)\n", __FILE__, __LINE__); + h5tools_setstatus(EXIT_FAILURE); + return; + } + HDstrcpy(tmp, prefix); par = HDstrdup(tmp); cp = HDstrrchr(par, '/'); @@ -3146,8 +3160,11 @@ xml_print_strs(hid_t did, int source) } bp = (char *)buf; - if (!is_vlstr) + if (!is_vlstr) { onestring = (char *)HDcalloc(tsiz, sizeof(char)); + if (onestring == NULL) + goto error; + } /* setup */ HDmemset(&buffer, 0, sizeof(h5tools_str_t)); @@ -3768,6 +3785,14 @@ xml_dump_dataset(hid_t did, const char *name, struct subset_t H5_ATTR_UNUSED *ss char *pstr = (char *)HDmalloc((size_t)100); tmp = (char *)HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2); + if (tmp == NULL) { + error_msg("buffer allocation failed\n"); + h5tools_setstatus(EXIT_FAILURE); + HDfree(rstr); + HDfree(pstr); + return; + } + HDstrcpy(tmp, prefix); HDstrcat(tmp, "/"); HDstrcat(tmp, name); diff --git a/tools/src/h5format_convert/h5format_convert.c b/tools/src/h5format_convert/h5format_convert.c index 3430c55..ddf129c 100644 --- a/tools/src/h5format_convert/h5format_convert.c +++ b/tools/src/h5format_convert/h5format_convert.c @@ -39,26 +39,9 @@ static int verbose_g = 0; * parameters. */ static const char * s_opts = "hVvd:n"; -static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, - {"he", no_arg, 'h'}, - {"version", no_arg, 'V'}, - {"version", no_arg, 'V'}, - {"versio", no_arg, 'V'}, - {"versi", no_arg, 'V'}, - {"vers", no_arg, 'V'}, - {"verbose", no_arg, 'v'}, - {"verbos", no_arg, 'v'}, - {"verbo", no_arg, 'v'}, - {"verb", no_arg, 'v'}, - {"dname", require_arg, 'd'}, - {"dnam", require_arg, 'd'}, - {"dna", require_arg, 'd'}, - {"dn", require_arg, 'd'}, - {"noop", no_arg, 'n'}, - {"noo", no_arg, 'n'}, - {"no", no_arg, 'n'}, - {"enable-error-stack", no_arg, 'E'}, +static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, {"version", no_arg, 'V'}, + {"verbose", no_arg, 'v'}, {"dname", require_arg, 'd'}, + {"noop", no_arg, 'n'}, {"enable-error-stack", no_arg, 'E'}, {NULL, 0, '\0'}}; /*------------------------------------------------------------------------- diff --git a/tools/src/h5import/h5import.c b/tools/src/h5import/h5import.c index 04e1c35..6517e43 100644 --- a/tools/src/h5import/h5import.c +++ b/tools/src/h5import/h5import.c @@ -3771,6 +3771,7 @@ getCompressionParameter(struct Input *in, FILE *strm) static int getExternalFilename(struct Input *in, FILE *strm) { + size_t temp_len; char temp[255]; const char *err1 = "Unable to get 'string' value.\n"; @@ -3779,8 +3780,10 @@ getExternalFilename(struct Input *in, FILE *strm) return (-1); } - in->externFilename = (char *)HDmalloc((size_t)(HDstrlen(temp) + 1) * sizeof(char)); - (void)HDstrncpy(in->externFilename, temp, HDstrlen(temp) + 1); + temp_len = HDstrlen(temp); + in->externFilename = (char *)HDmalloc((temp_len + 1) * sizeof(char)); + (void)HDstrcpy(in->externFilename, temp); + in->externFilename[temp_len] = '\0'; return (0); } diff --git a/tools/src/h5jam/h5jam.c b/tools/src/h5jam/h5jam.c index 0a2ea5d..7f3385c 100644 --- a/tools/src/h5jam/h5jam.c +++ b/tools/src/h5jam/h5jam.c @@ -34,14 +34,10 @@ char *ub_file = NULL; * parameters. The long-named ones can be partially spelled. When * adding more, make sure that they don't clash with each other. */ -static const char * s_opts = "hi:u:o:c:V"; /* add more later ? */ -static struct h5_long_options l_opts[] = { - {"help", no_arg, 'h'}, {"hel", no_arg, 'h'}, {"i", require_arg, 'i'}, /* input file */ - {"u", require_arg, 'u'}, /* user block file */ - {"o", require_arg, 'o'}, /* output file */ - {"clobber", no_arg, 'c'}, /* clobber existing UB */ - {"clobbe", no_arg, 'c'}, {"clobb", no_arg, 'c'}, {"clob", no_arg, 'c'}, - {"clo", no_arg, 'c'}, {"cl", no_arg, 'c'}, {NULL, 0, '\0'}}; +static const char * s_opts = "hi:u:o:c:V"; +static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, {"i", require_arg, 'i'}, + {"u", require_arg, 'u'}, {"o", require_arg, 'o'}, + {"clobber", no_arg, 'c'}, {NULL, 0, '\0'}}; /*------------------------------------------------------------------------- * Function: usage diff --git a/tools/src/h5jam/h5unjam.c b/tools/src/h5jam/h5unjam.c index 38d1a5e..fa23b06 100644 --- a/tools/src/h5jam/h5unjam.c +++ b/tools/src/h5jam/h5unjam.c @@ -36,13 +36,9 @@ char *ub_file = NULL; * adding more, make sure that they don't clash with each other. */ static const char * s_opts = "hu:i:o:d:V"; -static struct h5_long_options l_opts[] = { - {"help", no_arg, 'h'}, {"hel", no_arg, 'h'}, {"i", require_arg, 'i'}, /* input file */ - {"u", require_arg, 'u'}, /* user block file */ - {"o", require_arg, 'o'}, /* output file */ - {"delete", no_arg, 'd'}, /* delete ub */ - {"delet", no_arg, 'd'}, {"dele", no_arg, 'd'}, {"del", no_arg, 'd'}, - {"de", no_arg, 'd'}, {NULL, 0, '\0'}}; +static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, {"i", require_arg, 'i'}, + {"u", require_arg, 'u'}, {"o", require_arg, 'o'}, + {"delete", no_arg, 'd'}, {NULL, 0, '\0'}}; /*------------------------------------------------------------------------- * Function: usage diff --git a/tools/src/h5perf/CMakeLists.txt b/tools/src/h5perf/CMakeLists.txt new file mode 100644 index 0000000..36b0b2f --- /dev/null +++ b/tools/src/h5perf/CMakeLists.txt @@ -0,0 +1,103 @@ +cmake_minimum_required (VERSION 3.12) +project (HDF5_TOOLS_SRC_H5PERF C) + +# -------------------------------------------------------------------- +# Add the executables +# -------------------------------------------------------------------- +#-- Adding test for h5perf_serial +set (h5perf_serial_SOURCES + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/sio_perf.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/sio_engine.c +) +add_executable (h5perf_serial ${h5perf_serial_SOURCES}) +target_include_directories (h5perf_serial PRIVATE "${HDF5_TEST_SRC_DIR};${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") +if (NOT ONLY_SHARED_LIBS) + TARGET_C_PROPERTIES (h5perf_serial STATIC) + target_link_libraries (h5perf_serial PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET}) +else () + TARGET_C_PROPERTIES (h5perf_serial SHARED) + target_link_libraries (h5perf_serial PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) +endif () +set_target_properties (h5perf_serial PROPERTIES FOLDER perform) +set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5perf_serial") + +set (H5_DEP_EXECUTABLES h5perf_serial) + +#----------------------------------------------------------------------------- +# Add Target to clang-format +#----------------------------------------------------------------------------- +if (HDF5_ENABLE_FORMATTERS) + clang_format (HDF5_TOOLS_SRC_H5PERF_h5perf_serial_FORMAT h5perf_serial) +endif () + +if (H5_HAVE_PARALLEL) + if (UNIX) + #-- Adding test for perf - only on unix systems + set (perf_SOURCES + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/perf.c + ) + add_executable (perf ${perf_SOURCES}) + target_include_directories (perf PRIVATE "${HDF5_TEST_SRC_DIR};${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") + if (NOT ONLY_SHARED_LIBS) + TARGET_C_PROPERTIES (perf STATIC) + target_link_libraries (perf PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") + else () + TARGET_C_PROPERTIES (perf SHARED) + target_link_libraries (perf PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") + endif () + set_target_properties (perf PROPERTIES FOLDER perform) + set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};perf") + + set (H5_DEP_EXECUTABLES perf) + + #----------------------------------------------------------------------------- + # Add Target to clang-format + #----------------------------------------------------------------------------- + if (HDF5_ENABLE_FORMATTERS) + clang_format (HDF5_TOOLS_SRC_H5PERF_perf_FORMAT perf) + endif () + endif () + + #-- Adding test for h5perf + set (h5perf_SOURCES + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/pio_perf.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/pio_engine.c + ) + add_executable (h5perf ${h5perf_SOURCES}) + target_include_directories (h5perf PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") + if (NOT ONLY_SHARED_LIBS) + TARGET_C_PROPERTIES (h5perf STATIC) + target_link_libraries (h5perf PRIVATE ${LINK_LIBS} ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") + else () + TARGET_C_PROPERTIES (h5perf SHARED) + target_link_libraries (h5perf PRIVATE ${LINK_LIBS} ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") + endif () + set_target_properties (h5perf PROPERTIES FOLDER perform) + set_global_variable (HDF5_UTILS_TO_EXPORT "${HDF5_UTILS_TO_EXPORT};h5perf") + + set (H5_DEP_EXECUTABLES h5perf) + + #----------------------------------------------------------------------------- + # Add Target to clang-format + #----------------------------------------------------------------------------- + if (HDF5_ENABLE_FORMATTERS) + clang_format (HDF5_TOOLS_SRC_H5PERF_h5perf_FORMAT h5perf) + endif () +endif () + +#----------------------------------------------------------------------------- +# Rules for Installation of tools using make Install target +#----------------------------------------------------------------------------- +if (HDF5_EXPORTED_TARGETS) + foreach (exec ${H5_DEP_EXECUTABLES}) + INSTALL_PROGRAM_PDB (${exec} ${HDF5_INSTALL_BIN_DIR} toolsapplications) + endforeach () + + install ( + TARGETS + ${H5_DEP_EXECUTABLES} + EXPORT + ${HDF5_EXPORTED_TARGETS} + RUNTIME DESTINATION ${HDF5_INSTALL_BIN_DIR} COMPONENT toolsapplications + ) +endif () diff --git a/tools/src/h5perf/Makefile.am b/tools/src/h5perf/Makefile.am new file mode 100644 index 0000000..e8a9fdd --- /dev/null +++ b/tools/src/h5perf/Makefile.am @@ -0,0 +1,63 @@ +# +# Copyright by The HDF Group. +# Copyright by the Board of Trustees of the University of Illinois. +# All rights reserved. +# +# This file is part of HDF5. The full HDF5 copyright notice, including +# terms governing use, modification, and redistribution, is contained in +# the COPYING file, which can be found at the root of the source code +# distribution tree, or in https://www.hdfgroup.org/licenses. +# If you do not have access to either file, you may request a copy from +# help@hdfgroup.org. +## +## Makefile.am +## Run automake to generate a Makefile.in from this file. +## +# +# HDF5 Library Performance Makefile(.in) +# + +include $(top_srcdir)/config/commence.am + +AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/test -I$(top_srcdir)/tools/lib + +# bin_PROGRAMS will be installed. +if BUILD_PARALLEL_CONDITIONAL + bin_PROGRAMS=h5perf_serial perf h5perf +else + bin_PROGRAMS=h5perf_serial +endif + +# Add h5perf and h5perf_serial specific linker flags here +h5perf_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) +h5perf_serial_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) + +# Some programs are not built or run by default, but can be built by hand or by +# specifying --enable-build-all at configure time. +# Also, some of these programs should only be built in parallel. +# Currently there is no such program. +if BUILD_PARALLEL_CONDITIONAL + PARA_BUILD_ALL= +endif +if BUILD_ALL_CONDITIONAL + BUILD_ALL_PROGS=$(PARA_BUILD_ALL) +endif + +# Define programs that will be run in 'make check' +# List them in the order they should be run. +# Parallel test programs. +if BUILD_PARALLEL_CONDITIONAL + TEST_PROG_PARA=h5perf perf +endif + +h5perf_SOURCES=pio_perf.c pio_engine.c +h5perf_serial_SOURCES=sio_perf.c sio_engine.c + +# All of the programs depend on the main hdf5 library, and some of them +# depend on test or tools library. +LDADD=$(LIBHDF5) +h5perf_LDADD=$(LIBH5TOOLS) $(LIBHDF5) +h5perf_serial_LDADD=$(LIBH5TOOLS) $(LIBHDF5) +perf_LDADD=$(LIBHDF5) + +include $(top_srcdir)/config/conclude.am diff --git a/tools/src/h5perf/perf.c b/tools/src/h5perf/perf.c new file mode 100644 index 0000000..83d4ab0 --- /dev/null +++ b/tools/src/h5perf/perf.c @@ -0,0 +1,796 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Author: Albert Cheng of NCSA, May 1, 2001. + * This is derived from code given to me by Robert Ross. + * + * NOTE: This code assumes that all command line arguments make it out to all + * the processes that make up the parallel job, which isn't always the case. + * So if it doesn't work on some platform, that might be why. + */ + +#include "hdf5.h" +#include "H5private.h" + +#ifdef H5_HAVE_PARALLEL + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#ifdef H5_HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +#ifdef H5_HAVE_SYS_TIME_H +#include <sys/time.h> +#endif + +#ifdef H5_HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#ifdef H5_HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <mpi.h> +#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */ +#include <mpio.h> +#endif + +/* Macro definitions */ +/* Verify: + * if val is false (0), print mesg and if fatal is true (non-zero), die. + */ +#define H5FATAL 1 +#define VRFY(val, mesg, fatal) \ + do { \ + if (!val) { \ + printf("Proc %d: ", mynod); \ + printf("*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ + if (fatal) { \ + fflush(stdout); \ + goto die_jar_jar_die; \ + } \ + } \ + } while (0) +#define RANK 1 +#define MAX_PATH 1024 + +hsize_t dims[RANK]; /* dataset dim sizes */ +hsize_t block[RANK], stride[RANK], count[RANK]; +hsize_t start[RANK]; +hid_t fid; /* HDF5 file ID */ +hid_t acc_tpl; /* File access templates */ +hid_t sid; /* Dataspace ID */ +hid_t file_dataspace; /* File dataspace ID */ +hid_t mem_dataspace; /* memory dataspace ID */ +hid_t dataset; /* Dataset ID */ +hsize_t opt_alignment = 1; +hsize_t opt_threshold = 1; +int opt_split_vfd = 0; +char * meta_ext, *raw_ext; /* holds the meta and raw file extension if */ + /* opt_split_vfd is set */ + +/* DEFAULT VALUES FOR OPTIONS */ +int64_t opt_block = 1048576 * 16; +int opt_iter = 1; +int opt_stripe = -1; +int opt_correct = 0; +int amode = O_RDWR | O_CREAT; +char opt_file[256] = "perftest.out"; +char opt_pvfstab[256] = "notset"; +int opt_pvfstab_set = 0; + +const char *FILENAME[] = {opt_file, NULL}; + +/* function prototypes */ +static int parse_args(int argc, char **argv); + +#ifndef H5_HAVE_UNISTD_H +/* globals needed for getopt */ +extern char *optarg; +#endif + +#ifndef HDF5_PARAPREFIX +#define HDF5_PARAPREFIX "" +#endif +char * paraprefix = NULL; /* for command line option para-prefix */ +MPI_Info h5_io_info_g = MPI_INFO_NULL; /* MPI INFO object for IO */ + +static char *h5_fixname_real(const char *base_name, hid_t fapl, const char *_suffix, char *fullname, + size_t size, hbool_t nest_printf, hbool_t subst_for_superblock); + +int +main(int argc, char **argv) +{ + char * buf, *tmp, *buf2 = NULL, *tmp2 = NULL, *check; + int i, j, mynod = 0, nprocs = 1, my_correct = 1, correct, myerrno; + double stim, etim; + double write_tim = 0; + double read_tim = 0; + double read_bw, write_bw; + double max_read_tim, max_write_tim; + double min_read_tim, min_write_tim; + double ave_read_tim, ave_write_tim; + int64_t iter_jump = 0; + char filename[MAX_PATH]; + herr_t ret; /* Generic return value */ + + /* startup MPI and determine the rank of this process */ + MPI_Init(&argc, &argv); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + MPI_Comm_rank(MPI_COMM_WORLD, &mynod); + + /* parse the command line arguments */ + parse_args(argc, argv); + + if (mynod == 0) + printf("# Using hdf5-io calls.\n"); + +#ifdef H5_HAVE_UNISTD_H + /* Kind of a weird hack- if the location of the pvfstab file was + * specified on the command line, then spit out this location into + * the appropriate environment variable. + */ + if (opt_pvfstab_set) { + if ((setenv("PVFSTAB_FILE", opt_pvfstab, 1)) < 0) { + perror("setenv"); + goto die_jar_jar_die; + } + } +#endif + + /* this is how much of the file data is covered on each iteration of + * the test. used to help determine the seek offset on each + * iteration */ + iter_jump = nprocs * opt_block; + + /* setup a buffer of data to write */ + if (!(tmp = (char *)malloc((size_t)opt_block + 256))) { + perror("malloc"); + goto die_jar_jar_die; + } + buf = tmp + 128 - (((long)tmp) % 128); /* align buffer */ + + if (opt_correct) { + /* do the same buffer setup for verifiable data */ + if (!(tmp2 = (char *)malloc((size_t)opt_block + 256))) { + perror("malloc2"); + goto die_jar_jar_die; + } + buf2 = tmp + 128 - (((long)tmp) % 128); + } + + /* setup file access template with parallel IO access. */ + if (opt_split_vfd) { + hid_t mpio_pl; + + mpio_pl = H5Pcreate(H5P_FILE_ACCESS); + VRFY((acc_tpl >= 0), "", H5FATAL); + ret = H5Pset_fapl_mpio(mpio_pl, MPI_COMM_WORLD, MPI_INFO_NULL); + VRFY((ret >= 0), "", H5FATAL); + + /* set optional allocation alignment */ + if (opt_alignment * opt_threshold != 1) { + ret = H5Pset_alignment(acc_tpl, opt_threshold, opt_alignment); + VRFY((ret >= 0), "H5Pset_alignment succeeded", !H5FATAL); + } + + /* setup file access template */ + acc_tpl = H5Pcreate(H5P_FILE_ACCESS); + VRFY((acc_tpl >= 0), "", H5FATAL); + ret = H5Pset_fapl_split(acc_tpl, meta_ext, mpio_pl, raw_ext, mpio_pl); + VRFY((ret >= 0), "H5Pset_fapl_split succeeded", H5FATAL); + ret = H5Pclose(mpio_pl); + VRFY((ret >= 0), "H5Pclose mpio_pl succeeded", H5FATAL); + } + else { + /* setup file access template */ + acc_tpl = H5Pcreate(H5P_FILE_ACCESS); + VRFY((acc_tpl >= 0), "", H5FATAL); + ret = H5Pset_fapl_mpio(acc_tpl, MPI_COMM_WORLD, MPI_INFO_NULL); + VRFY((ret >= 0), "", H5FATAL); + + /* set optional allocation alignment */ + if (opt_alignment * opt_threshold != 1) { + ret = H5Pset_alignment(acc_tpl, opt_threshold, opt_alignment); + VRFY((ret >= 0), "H5Pset_alignment succeeded", !H5FATAL); + } + } + + h5_fixname_real(FILENAME[0], acc_tpl, NULL, filename, sizeof filename, FALSE, FALSE); + + /* create the parallel file */ + fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl); + VRFY((fid >= 0), "H5Fcreate succeeded", H5FATAL); + + /* define a contiquous dataset of opt_iter*nprocs*opt_block chars */ + dims[0] = (hsize_t)opt_iter * (hsize_t)nprocs * (hsize_t)opt_block; + sid = H5Screate_simple(RANK, dims, NULL); + VRFY((sid >= 0), "H5Screate_simple succeeded", H5FATAL); + dataset = H5Dcreate2(fid, "Dataset1", H5T_NATIVE_CHAR, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + VRFY((dataset >= 0), "H5Dcreate2 succeeded", H5FATAL); + + /* create the memory dataspace and the file dataspace */ + dims[0] = (hsize_t)opt_block; + mem_dataspace = H5Screate_simple(RANK, dims, NULL); + VRFY((mem_dataspace >= 0), "", H5FATAL); + file_dataspace = H5Dget_space(dataset); + VRFY((file_dataspace >= 0), "H5Dget_space succeeded", H5FATAL); + + /* now each process writes a block of opt_block chars in round robbin + * fashion until the whole dataset is covered. + */ + for (j = 0; j < opt_iter; j++) { + /* setup a file dataspace selection */ + start[0] = (hsize_t)((j * iter_jump) + (mynod * opt_block)); + stride[0] = block[0] = (hsize_t)opt_block; + count[0] = 1; + ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block); + VRFY((ret >= 0), "H5Sset_hyperslab succeeded", H5FATAL); + + if (opt_correct) /* fill in buffer for iteration */ { + for (i = mynod + j, check = buf; i < opt_block; i++, check++) + *check = (char)i; + } + + /* discover the starting time of the operation */ + MPI_Barrier(MPI_COMM_WORLD); + stim = MPI_Wtime(); + + /* write data */ + ret = H5Dwrite(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf); + VRFY((ret >= 0), "H5Dwrite dataset1 succeeded", !H5FATAL); + + /* discover the ending time of the operation */ + etim = MPI_Wtime(); + + write_tim += (etim - stim); + + /* we are done with this "write" iteration */ + } + + /* close dataset and file */ + ret = H5Dclose(dataset); + VRFY((ret >= 0), "H5Dclose succeeded", H5FATAL); + ret = H5Fclose(fid); + VRFY((ret >= 0), "H5Fclose succeeded", H5FATAL); + + /* wait for everyone to synchronize at this point */ + MPI_Barrier(MPI_COMM_WORLD); + + /* reopen the file for reading */ + fid = H5Fopen(filename, H5F_ACC_RDONLY, acc_tpl); + VRFY((fid >= 0), "", H5FATAL); + + /* open the dataset */ + dataset = H5Dopen2(fid, "Dataset1", H5P_DEFAULT); + VRFY((dataset >= 0), "H5Dopen succeeded", H5FATAL); + + /* we can re-use the same mem_dataspace and file_dataspace + * the H5Dwrite used since the dimension size is the same. + */ + + /* we are going to repeat the read the same pattern the write used */ + for (j = 0; j < opt_iter; j++) { + /* setup a file dataspace selection */ + start[0] = (hsize_t)((j * iter_jump) + (mynod * opt_block)); + stride[0] = block[0] = (hsize_t)opt_block; + count[0] = 1; + ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block); + VRFY((ret >= 0), "H5Sset_hyperslab succeeded", H5FATAL); + /* seek to the appropriate spot give the current iteration and + * rank within the MPI processes */ + + /* discover the start time */ + MPI_Barrier(MPI_COMM_WORLD); + stim = MPI_Wtime(); + + /* read in the file data */ + if (!opt_correct) { + ret = H5Dread(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf); + } + else { + ret = H5Dread(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf2); + } + myerrno = errno; + + /* discover the end time */ + etim = MPI_Wtime(); + read_tim += (etim - stim); + VRFY((ret >= 0), "H5Dwrite dataset1 succeeded", !H5FATAL); + + if (ret < 0) + HDfprintf(stderr, "node %d, read error, loc = %" PRId64 ": %s\n", mynod, mynod * opt_block, + strerror(myerrno)); + + /* if the user wanted to check correctness, compare the write + * buffer to the read buffer */ + if (opt_correct && memcmp(buf, buf2, (size_t)opt_block)) { + HDfprintf(stderr, "node %d, correctness test failed\n", mynod); + my_correct = 0; + MPI_Allreduce(&my_correct, &correct, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); + } + + /* we are done with this read iteration */ + } + + /* close dataset and file */ + ret = H5Dclose(dataset); + VRFY((ret >= 0), "H5Dclose succeeded", H5FATAL); + ret = H5Fclose(fid); + VRFY((ret >= 0), "H5Fclose succeeded", H5FATAL); + ret = H5Pclose(acc_tpl); + VRFY((ret >= 0), "H5Pclose succeeded", H5FATAL); + + /* compute the read and write times */ + MPI_Allreduce(&read_tim, &max_read_tim, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + MPI_Allreduce(&read_tim, &min_read_tim, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); + MPI_Allreduce(&read_tim, &ave_read_tim, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + + /* calculate the average from the sum */ + ave_read_tim = ave_read_tim / nprocs; + + MPI_Allreduce(&write_tim, &max_write_tim, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); + MPI_Allreduce(&write_tim, &min_write_tim, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); + MPI_Allreduce(&write_tim, &ave_write_tim, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); + + /* calculate the average from the sum */ + ave_write_tim = ave_write_tim / nprocs; + + /* print out the results on one node */ + if (mynod == 0) { + read_bw = (double)((int64_t)(opt_block * nprocs * opt_iter)) / (max_read_tim * 1000000.0); + write_bw = (double)((int64_t)(opt_block * nprocs * opt_iter)) / (max_write_tim * 1000000.0); + + printf("nr_procs = %d, nr_iter = %d, blk_sz = %ld\n", nprocs, opt_iter, (long)opt_block); + + printf("# total_size = %ld\n", (long)(opt_block * nprocs * opt_iter)); + + printf("# Write: min_time = %f, max_time = %f, mean_time = %f\n", min_write_tim, max_write_tim, + ave_write_tim); + printf("# Read: min_time = %f, max_time = %f, mean_time = %f\n", min_read_tim, max_read_tim, + ave_read_tim); + + printf("Write bandwidth = %f Mbytes/sec\n", write_bw); + printf("Read bandwidth = %f Mbytes/sec\n", read_bw); + + if (opt_correct) { + printf("Correctness test %s.\n", correct ? "passed" : "failed"); + } + } + +die_jar_jar_die: + +#ifdef H5_HAVE_UNISTD + /* Clear the environment variable if it was set earlier */ + if (opt_pvfstab_set) { + unsetenv("PVFSTAB_FILE"); + } +#endif + + free(tmp); + if (opt_correct) + free(tmp2); + + MPI_Finalize(); + + return (0); +} + +static int +parse_args(int argc, char **argv) +{ + int c; + + while ((c = getopt(argc, argv, "s:b:i:f:p:a:2:c")) != EOF) { + switch (c) { + case 's': /* stripe */ + opt_stripe = atoi(optarg); + break; + case 'b': /* block size */ + opt_block = atoi(optarg); + break; + case 'i': /* iterations */ + opt_iter = atoi(optarg); + break; + case 'f': /* filename */ + strncpy(opt_file, optarg, 255); + FILENAME[0] = opt_file; + break; + case 'p': /* pvfstab file */ + strncpy(opt_pvfstab, optarg, 255); + opt_pvfstab_set = 1; + break; + case 'a': /* aligned allocation. + * syntax: -a<alignment>/<threshold> + * e.g., -a4096/512 allocate at 4096 bytes + * boundary if request size >= 512. + */ + { + char *p; + + opt_alignment = (hsize_t)HDatoi(optarg); + if (NULL != (p = (char *)HDstrchr(optarg, '/'))) + opt_threshold = (hsize_t)HDatoi(p + 1); + } + HDfprintf(stdout, "alignment/threshold=%" PRIuHSIZE "/%" PRIuHSIZE "\n", opt_alignment, + opt_threshold); + break; + case '2': /* use 2-files, i.e., split file driver */ + opt_split_vfd = 1; + /* get meta and raw file extension. */ + /* syntax is <raw_ext>,<meta_ext> */ + meta_ext = raw_ext = optarg; + while (*raw_ext != '\0') { + if (*raw_ext == ',') { + *raw_ext = '\0'; + raw_ext++; + break; + } + raw_ext++; + } + printf("split-file-vfd used: %s,%s\n", meta_ext, raw_ext); + break; + case 'c': /* correctness */ + opt_correct = 1; + break; + case '?': /* unknown */ + default: + break; + } + } + + return (0); +} +/*------------------------------------------------------------------------- + * Function: getenv_all + * + * Purpose: Used to get the environment that the root MPI task has. + * name specifies which environment variable to look for + * val is the string to which the value of that environment + * variable will be copied. + * + * NOTE: The pointer returned by this function is only + * valid until the next call to getenv_all and the data + * stored there must be copied somewhere else before any + * further calls to getenv_all take place. + * + * Return: pointer to a string containing the value of the environment variable + * NULL if the varialbe doesn't exist in task 'root's environment. + * + * Programmer: Leon Arber + * 4/4/05 + * + * Modifications: + * Use original getenv if MPI is not initialized. This happens + * one uses the PHDF5 library to build a serial nature code. + * Albert 2006/04/07 + * + *------------------------------------------------------------------------- + */ +char * +getenv_all(MPI_Comm comm, int root, const char *name) +{ + int mpi_size, mpi_rank, mpi_initialized, mpi_finalized; + int len; + static char *env = NULL; + + HDassert(name); + + MPI_Initialized(&mpi_initialized); + MPI_Finalized(&mpi_finalized); + + if (mpi_initialized && !mpi_finalized) { + MPI_Comm_rank(comm, &mpi_rank); + MPI_Comm_size(comm, &mpi_size); + HDassert(root < mpi_size); + + /* The root task does the getenv call + * and sends the result to the other tasks */ + if (mpi_rank == root) { + env = HDgetenv(name); + if (env) { + len = (int)HDstrlen(env); + MPI_Bcast(&len, 1, MPI_INT, root, comm); + MPI_Bcast(env, len, MPI_CHAR, root, comm); + } + else { + /* len -1 indicates that the variable was not in the environment */ + len = -1; + MPI_Bcast(&len, 1, MPI_INT, root, comm); + } + } + else { + MPI_Bcast(&len, 1, MPI_INT, root, comm); + if (len >= 0) { + if (env == NULL) + env = (char *)HDmalloc((size_t)len + 1); + else if (HDstrlen(env) < (size_t)len) + env = (char *)HDrealloc(env, (size_t)len + 1); + + MPI_Bcast(env, len, MPI_CHAR, root, comm); + env[len] = '\0'; + } + else { + if (env) + HDfree(env); + env = NULL; + } + } +#ifndef NDEBUG + MPI_Barrier(comm); +#endif + } + else { + /* use original getenv */ + if (env) + HDfree(env); + env = HDgetenv(name); + } /* end if */ + + return env; +} + +/*------------------------------------------------------------------------- + * Function: h5_fixname_real + * + * Purpose: Create a file name from a file base name like `test' and + * return it through the FULLNAME (at most SIZE characters + * counting the null terminator). The full name is created by + * prepending the contents of HDF5_PREFIX (separated from the + * base name by a slash) and appending a file extension based on + * the driver supplied, resulting in something like + * `ufs:/u/matzke/test.h5'. + * + * Return: Success: The FULLNAME pointer. + * + * Failure: NULL if BASENAME or FULLNAME is the null + * pointer or if FULLNAME isn't large enough for + * the result. + * + * Programmer: Robb Matzke + * Thursday, November 19, 1998 + * + *------------------------------------------------------------------------- + */ +static char * +h5_fixname_real(const char *base_name, hid_t fapl, const char *_suffix, char *fullname, size_t size, + hbool_t nest_printf, hbool_t subst_for_superblock) +{ + const char *prefix = NULL; + const char *env = NULL; /* HDF5_DRIVER environment variable */ + char * ptr, last = '\0'; + const char *suffix = _suffix; + size_t i, j; + hid_t driver = -1; + int isppdriver = 0; /* if the driver is MPI parallel */ + + if (!base_name || !fullname || size < 1) + return NULL; + + HDmemset(fullname, 0, size); + + /* figure out the suffix */ + if (H5P_DEFAULT != fapl) { + if ((driver = H5Pget_driver(fapl)) < 0) + return NULL; + + if (suffix) { + if (H5FD_FAMILY == driver) { + if (subst_for_superblock) + suffix = "00000.h5"; + else + suffix = nest_printf ? "%%05d.h5" : "%05d.h5"; + } + else if (H5FD_MULTI == driver) { + + /* Get the environment variable, if it exists, in case + * we are using the split driver since both of those + * use the multi VFD under the hood. + */ + env = HDgetenv("HDF5_DRIVER"); +#ifdef HDF5_DRIVER + /* Use the environment variable, then the compile-time constant */ + if (!env) + env = HDF5_DRIVER; +#endif + if (env && !HDstrcmp(env, "split")) { + /* split VFD */ + if (subst_for_superblock) + suffix = "-m.h5"; + else + suffix = NULL; + } + else { + /* multi VFD */ + if (subst_for_superblock) + suffix = "-s.h5"; + else + suffix = NULL; + } + } + } + } + + /* Must first check fapl is not H5P_DEFAULT (-1) because H5FD_XXX + * could be of value -1 if it is not defined. + */ + isppdriver = H5P_DEFAULT != fapl && (H5FD_MPIO == driver); + + /* Check what prefix to use for test files. Process HDF5_PARAPREFIX and + * HDF5_PREFIX. + * Use different ones depending on parallel or serial driver used. + * (The #ifdef is needed to prevent compile failure in case MPI is not + * configured.) + */ + if (isppdriver) { + /* + * For parallel: + * First use command line option, then the environment + * variable, then try the constant + */ + static int explained = 0; + + prefix = (paraprefix ? paraprefix : getenv_all(MPI_COMM_WORLD, 0, "HDF5_PARAPREFIX")); + + if (!prefix && !explained) { + /* print hint by process 0 once. */ + int mpi_rank; + + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + + if (mpi_rank == 0) + HDprintf("*** Hint ***\n" + "You can use environment variable HDF5_PARAPREFIX to " + "run parallel test files in a\n" + "different directory or to add file type prefix. e.g.,\n" + " HDF5_PARAPREFIX=pfs:/PFS/user/me\n" + " export HDF5_PARAPREFIX\n" + "*** End of Hint ***\n"); + + explained = TRUE; +#ifdef HDF5_PARAPREFIX + prefix = HDF5_PARAPREFIX; +#endif /* HDF5_PARAPREFIX */ + } + } + else { + /* + * For serial: + * First use the environment variable, then try the constant + */ + prefix = HDgetenv("HDF5_PREFIX"); + +#ifdef HDF5_PREFIX + if (!prefix) + prefix = HDF5_PREFIX; +#endif /* HDF5_PREFIX */ + } + + /* Prepend the prefix value to the base name */ + if (prefix && *prefix) { + if (isppdriver) { + /* This is a parallel system */ + char *subdir; + + if (!HDstrcmp(prefix, HDF5_PARAPREFIX)) { + /* + * If the prefix specifies the HDF5_PARAPREFIX directory, then + * default to using the "/tmp/$USER" or "/tmp/$LOGIN" + * directory instead. + */ + char *user, *login; + + user = HDgetenv("USER"); + login = HDgetenv("LOGIN"); + subdir = (user ? user : login); + + if (subdir) { + for (i = 0; i < size && prefix[i]; i++) + fullname[i] = prefix[i]; + + fullname[i++] = '/'; + + for (j = 0; i < size && subdir[j]; ++i, ++j) + fullname[i] = subdir[j]; + } + } + + if (!fullname[0]) { + /* We didn't append the prefix yet */ + HDstrncpy(fullname, prefix, size); + fullname[size - 1] = '\0'; + } + + if (HDstrlen(fullname) + HDstrlen(base_name) + 1 < size) { + /* + * Append the base_name with a slash first. Multiple + * slashes are handled below. + */ + h5_stat_t buf; + + if (HDstat(fullname, &buf) < 0) + /* The directory doesn't exist just yet */ + if (HDmkdir(fullname, (mode_t)0755) < 0 && errno != EEXIST) + /* + * We couldn't make the "/tmp/${USER,LOGIN}" + * subdirectory. Default to PREFIX's original + * prefix value. + */ + HDstrcpy(fullname, prefix); + + HDstrcat(fullname, "/"); + HDstrcat(fullname, base_name); + } + else { + /* Buffer is too small */ + return NULL; + } + } + else { + if (HDsnprintf(fullname, size, "%s/%s", prefix, base_name) == (int)size) + /* Buffer is too small */ + return NULL; + } + } + else if (HDstrlen(base_name) >= size) { + /* Buffer is too small */ + return NULL; + } + else { + HDstrcpy(fullname, base_name); + } + + /* Append a suffix */ + if (suffix) { + if (HDstrlen(fullname) + HDstrlen(suffix) >= size) + return NULL; + + HDstrcat(fullname, suffix); + } + + /* Remove any double slashes in the filename */ + for (ptr = fullname, i = j = 0; ptr && i < size; i++, ptr++) { + if (*ptr != '/' || last != '/') + fullname[j++] = *ptr; + + last = *ptr; + } + + return fullname; +} + +/* + * Local variables: + * c-indent-level: 3 + * c-basic-offset: 3 + * tab-width: 3 + * End: + */ + +#else /* H5_HAVE_PARALLEL */ +/* dummy program since H5_HAVE_PARALLEL is not configured in */ +int +main(int H5_ATTR_UNUSED argc, char H5_ATTR_UNUSED **argv) +{ + printf("No parallel performance because parallel is not configured in\n"); + return (0); +} +#endif /* H5_HAVE_PARALLEL */ diff --git a/tools/src/h5perf/pio_engine.c b/tools/src/h5perf/pio_engine.c new file mode 100644 index 0000000..cac36d7 --- /dev/null +++ b/tools/src/h5perf/pio_engine.c @@ -0,0 +1,2745 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Author: Albert Cheng of NCSA, Oct 24, 2001. + */ + +#include "hdf5.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef H5_HAVE_UNISTD_H +#include <sys/types.h> +#include <unistd.h> +#endif + +#ifdef H5_HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +#ifdef H5_HAVE_PARALLEL + +#include <mpi.h> + +#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */ +#include <mpio.h> +#endif /* !MPI_FILE_NULL */ + +#include "pio_perf.h" + +/* Macro definitions */ + +#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 6 +#define H5DCREATE(fd, name, type, space, dcpl) H5Dcreate(fd, name, type, space, dcpl) +#define H5DOPEN(fd, name) H5Dopen(fd, name) +#else +#define H5DCREATE(fd, name, type, space, dcpl) \ + H5Dcreate2(fd, name, type, space, H5P_DEFAULT, dcpl, H5P_DEFAULT) +#define H5DOPEN(fd, name) H5Dopen2(fd, name, H5P_DEFAULT) +#endif + +/* sizes of various items. these sizes won't change during program execution */ +/* The following three must have the same type */ +#define ELMT_H5_TYPE H5T_NATIVE_UCHAR + +#define GOTOERROR(errcode) \ + { \ + ret_code = errcode; \ + goto done; \ + } +#define ERRMSG(mesg) \ + { \ + HDfprintf(stderr, "Proc %d: ", pio_mpi_rank_g); \ + HDfprintf(stderr, "*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ + } + +/* verify: if val is false (0), print mesg. */ +#define VRFY(val, mesg) \ + do { \ + if (!val) { \ + ERRMSG(mesg); \ + GOTOERROR(FAIL); \ + } \ + } while (0) + +/* POSIX I/O macros */ +#ifdef H5_HAVE_WIN32_API +/* Can't link against the library, so this test will use the older, non-Unicode + * _open() call on Windows. + */ +#define HDopen(S, F, ...) _open(S, F | _O_BINARY, __VA_ARGS__) +#endif /* H5_HAVE_WIN32_API */ +#define POSIXCREATE(fn) HDopen(fn, O_CREAT | O_TRUNC | O_RDWR, 0600) +#define POSIXOPEN(fn, F) HDopen(fn, F, 0600) +#define POSIXCLOSE(F) HDclose(F) +#define POSIXSEEK(F, L) HDlseek(F, L, SEEK_SET) +#define POSIXWRITE(F, B, S) HDwrite(F, B, S) +#define POSIXREAD(F, B, S) HDread(F, B, S) + +enum { PIO_CREATE = 1, PIO_WRITE = 2, PIO_READ = 4 }; + +/* Global variables */ +static int clean_file_g = -1; /*whether to cleanup temporary test */ +/*files. -1 is not defined; */ +/*0 is no cleanup; 1 is do cleanup */ + +/* + * In a parallel machine, the filesystem suitable for compiling is + * unlikely a parallel file system that is suitable for parallel I/O. + * There is no standard pathname for the parallel file system. /tmp + * is about the best guess. + */ +#ifndef HDF5_PARAPREFIX +#define HDF5_PARAPREFIX "" +#endif /* !HDF5_PARAPREFIX */ + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif /* !MIN */ + +/* the different types of file descriptors we can expect */ +typedef union _file_descr { + int posixfd; /* POSIX file handle*/ + MPI_File mpifd; /* MPI file */ + hid_t h5fd; /* HDF5 file */ +} file_descr; + +/* local functions */ +static char * pio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size); +static herr_t do_write(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nelmts, + size_t buf_size, void *buffer); +static herr_t do_read(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nelmts, + size_t buf_size, void *buffer /*out*/); +static herr_t do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags); +static herr_t do_fclose(iotype iot, file_descr *fd); +static void do_cleanupfile(iotype iot, char *fname); +static off_t sqrto(off_t); + +/* + * Function: do_pio + * Purpose: PIO Engine where Parallel IO are executed. + * Return: results + * Programmer: Albert Cheng, Bill Wendling 2001/12/12 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +results +do_pio(parameters param) +{ + /* return codes */ + herr_t ret_code = 0; /*return code */ + results res; + + file_descr fd; + iotype iot; + + char fname[FILENAME_MAX]; + long nf; + long ndsets; + off_t nbytes; /*number of bytes per dataset */ + off_t snbytes; /*general dataset size */ + /*for 1D, it is the actual dataset size */ + /*for 2D, it is the size of a side of the dataset square */ + char * buffer = NULL; /*data buffer pointer */ + size_t buf_size; /*general buffer size in bytes */ + /*for 1D, it is the actual buffer size */ + /*for 2D, it is the length of the buffer rectangle */ + size_t blk_size; /*data block size in bytes */ + size_t bsize; /*actual buffer size */ + + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + + /* Sanity check parameters */ + + /* IO type */ + iot = param.io_type; + + switch (iot) { + case MPIO: + fd.mpifd = MPI_FILE_NULL; + res.timers = io_time_new(MPI_CLOCK); + break; + case POSIXIO: + fd.posixfd = -1; + res.timers = io_time_new(MPI_CLOCK); + break; + case PHDF5: + fd.h5fd = -1; + res.timers = io_time_new(MPI_CLOCK); + break; + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", iot); + GOTOERROR(FAIL); + } + + ndsets = param.num_dsets; /* number of datasets per file */ + nbytes = param.num_bytes; /* number of bytes per dataset */ + buf_size = param.buf_size; + blk_size = param.blk_size; + + if (!param.dim2d) { + snbytes = nbytes; /* General dataset size */ + bsize = buf_size; /* Actual buffer size */ + } + else { + snbytes = sqrto(nbytes); /* General dataset size */ + bsize = buf_size * blk_size; /* Actual buffer size */ + } + + if (param.num_files < 0) { + HDfprintf(stderr, "number of files must be >= 0 (%ld)\n", param.num_files); + GOTOERROR(FAIL); + } + + if (ndsets < 0) { + HDfprintf(stderr, "number of datasets per file must be >= 0 (%ld)\n", ndsets); + GOTOERROR(FAIL); + } + + if (param.num_procs <= 0) { + HDfprintf(stderr, "maximum number of process to use must be > 0 (%d)\n", param.num_procs); + GOTOERROR(FAIL); + } + + /* Validate transfer buffer size & block size*/ + if (blk_size <= 0) { + HDfprintf(stderr, "Transfer block size (%zu) must be > 0\n", blk_size); + GOTOERROR(FAIL); + } + if (buf_size <= 0) { + HDfprintf(stderr, "Transfer buffer size (%zu) must be > 0\n", buf_size); + GOTOERROR(FAIL); + } + if ((buf_size % blk_size) != 0) { + HDfprintf(stderr, + "Transfer buffer size (%zu) must be a multiple of the " + "interleaved I/O block size (%zu)\n", + buf_size, blk_size); + GOTOERROR(FAIL); + } + if ((snbytes % pio_mpi_nprocs_g) != 0) { + HDfprintf(stderr, + "Dataset size (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " + "number of processes (%d)\n", + (long long)snbytes, pio_mpi_nprocs_g); + GOTOERROR(FAIL); + } + + if (!param.dim2d) { + if (((size_t)(snbytes / pio_mpi_nprocs_g) % buf_size) != 0) { + HDfprintf(stderr, + "Dataset size/process (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " + "trasfer buffer size (%zu)\n", + (long long)(snbytes / pio_mpi_nprocs_g), buf_size); + GOTOERROR(FAIL); + } + } + else { + if (((size_t)snbytes % buf_size) != 0) { + HDfprintf(stderr, + "Dataset side size (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " + "trasfer buffer size (%zu)\n", + (long long)snbytes, buf_size); + GOTOERROR(FAIL); + } + } + + /* Allocate transfer buffer */ + if ((buffer = malloc(bsize)) == NULL) { + HDfprintf(stderr, "malloc for transfer buffer size (%zu) failed\n", bsize); + GOTOERROR(FAIL); + } + + if (pio_debug_level >= 4) { + int myrank; + + MPI_Comm_rank(pio_comm_g, &myrank); + + /* output all of the times for all iterations */ + if (myrank == 0) + HDfprintf(output, "Timer details:\n"); + } + + for (nf = 1; nf <= param.num_files; nf++) { + /* + * Write performance measurement + */ + /* Open file for write */ + char base_name[256]; + + HDsprintf(base_name, "#pio_tmp_%lu", nf); + pio_create_filename(iot, base_name, fname, sizeof(fname)); + if (pio_debug_level > 0) + HDfprintf(output, "rank %d: data filename=%s\n", pio_mpi_rank_g, fname); + + /* Need barrier to make sure everyone starts at the same time */ + MPI_Barrier(pio_comm_g); + + io_time_set(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTART); + hrc = do_fopen(¶m, fname, &fd, PIO_CREATE | PIO_WRITE); + + VRFY((hrc == SUCCESS), "do_fopen failed"); + + io_time_set(res.timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTART); + hrc = do_write(&res, &fd, ¶m, ndsets, nbytes, buf_size, buffer); + io_time_set(res.timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTOP); + + VRFY((hrc == SUCCESS), "do_write failed"); + + /* Close file for write */ + hrc = do_fclose(iot, &fd); + + io_time_set(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_fclose failed"); + + if (!param.h5_write_only) { + /* + * Read performance measurement + */ + /* Need barrier to make sure everyone is done writing and has + * closed the file. Also to make sure everyone starts reading + * at the same time. + */ + MPI_Barrier(pio_comm_g); + + /* Open file for read */ + io_time_set(res.timers, HDF5_GROSS_READ_FIXED_DIMS, TSTART); + hrc = do_fopen(¶m, fname, &fd, PIO_READ); + + VRFY((hrc == SUCCESS), "do_fopen failed"); + + io_time_set(res.timers, HDF5_FINE_READ_FIXED_DIMS, TSTART); + hrc = do_read(&res, &fd, ¶m, ndsets, nbytes, buf_size, buffer); + io_time_set(res.timers, HDF5_FINE_READ_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_read failed"); + + /* Close file for read */ + hrc = do_fclose(iot, &fd); + + io_time_set(res.timers, HDF5_GROSS_READ_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_fclose failed"); + } + + /* Need barrier to make sure everyone is done with the file */ + /* before it may be removed by do_cleanupfile */ + MPI_Barrier(pio_comm_g); + do_cleanupfile(iot, fname); + } + +done: + /* clean up */ + /* release HDF5 objects */ + + /* close any opened files */ + /* no remove(fname) because that should have happened normally. */ + switch (iot) { + case POSIXIO: + if (fd.posixfd != -1) + hrc = do_fclose(iot, &fd); + break; + case MPIO: + if (fd.mpifd != MPI_FILE_NULL) + hrc = do_fclose(iot, &fd); + break; + case PHDF5: + if (fd.h5fd != -1) + hrc = do_fclose(iot, &fd); + break; + default: + break; + } + + /* release generic resources */ + if (buffer) + HDfree(buffer); + res.ret_code = ret_code; + return res; +} + +/* + * Function: pio_create_filename + * Purpose: Create a new filename to write to. Determine the correct + * suffix to append to the filename by the type of I/O we're + * doing. Also, place in the /tmp/{$USER,$LOGIN} directory if + * USER or LOGIN are specified in the environment. + * Return: Pointer to filename or NULL + * Programmer: Bill Wendling, 21. November 2001 + * Modifications: + */ +static char * +pio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size) +{ + const char *prefix, *suffix = ""; + char * ptr, last = '\0'; + size_t i, j; + + if (!base_name || !fullname || size < 1) + return NULL; + + HDmemset(fullname, 0, size); + + switch (iot) { + case POSIXIO: + suffix = ".posix"; + break; + case MPIO: + suffix = ".mpio"; + break; + case PHDF5: + suffix = ".h5"; + break; + default: + break; + } + + /* First use the environment variable and then try the constant */ + prefix = HDgetenv("HDF5_PARAPREFIX"); + +#ifdef HDF5_PARAPREFIX + if (!prefix) + prefix = HDF5_PARAPREFIX; +#endif /* HDF5_PARAPREFIX */ + + /* Prepend the prefix value to the base name */ + if (prefix && *prefix) { + /* If the prefix specifies the HDF5_PARAPREFIX directory, then + * default to using the "/tmp/$USER" or "/tmp/$LOGIN" + * directory instead. */ + register char *user, *login, *subdir; + + user = HDgetenv("USER"); + login = HDgetenv("LOGIN"); + subdir = (user ? user : login); + + if (subdir) { + for (i = 0; i < size - 1 && prefix[i]; i++) + fullname[i] = prefix[i]; + + fullname[i++] = '/'; + + for (j = 0; i < size && subdir[j]; i++, j++) + fullname[i] = subdir[j]; + } + else { + /* We didn't append the prefix yet */ + HDstrncpy(fullname, prefix, size); + fullname[size - 1] = '\0'; + } + + if ((HDstrlen(fullname) + HDstrlen(base_name) + 1) < size) { + /* Append the base_name with a slash first. Multiple slashes are + * handled below. */ + h5_stat_t buf; + + if (HDstat(fullname, &buf) < 0) + /* The directory doesn't exist just yet */ + if (HDmkdir(fullname, (mode_t)0755) < 0 && errno != EEXIST) { + /* We couldn't make the "/tmp/${USER,LOGIN}" subdirectory. + * Default to PREFIX's original prefix value. */ + HDstrcpy(fullname, prefix); + } + + HDstrcat(fullname, "/"); + HDstrcat(fullname, base_name); + } + else { + /* Buffer is too small */ + return NULL; + } + } + else if (HDstrlen(base_name) >= size) { + /* Buffer is too small */ + return NULL; + } + else { + HDstrcpy(fullname, base_name); + } + + /* Append a suffix */ + if (suffix) { + if (HDstrlen(fullname) + HDstrlen(suffix) >= size) + return NULL; + + HDstrcat(fullname, suffix); + } + + /* Remove any double slashes in the filename */ + for (ptr = fullname, i = j = 0; ptr && i < size; i++, ptr++) { + if (*ptr != '/' || last != '/') + fullname[j++] = *ptr; + + last = *ptr; + } + + return fullname; +} + +/* + * Function: do_write + * Purpose: Write the required amount of data to the file. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +static herr_t +do_write(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nbytes, size_t buf_size, + void *buffer) +{ + int ret_code = SUCCESS; + int rc; /*routine return code */ + long ndset; + size_t blk_size; /* The block size to subdivide the xfer buffer into */ + off_t nbytes_xfer; /* Total number of bytes transferred so far */ + size_t nbytes_xfer_advance; /* Number of bytes transferred in a single I/O operation */ + size_t nbytes_toxfer; /* Number of bytes to transfer a particular time */ + char dname[64]; + off_t dset_offset = 0; /*dataset offset in a file */ + off_t bytes_begin[2]; /*first elmt this process transfer */ + off_t bytes_count; /*number of elmts this process transfer */ + off_t snbytes = 0; /*size of a side of the dataset square */ + unsigned char *buf_p; /* Current buffer pointer */ + + /* POSIX variables */ + off_t file_offset; /* File offset of the next transfer */ + off_t file_offset_advance; /* File offset advance after each I/O operation */ + off_t posix_file_offset; /* Base file offset of the next transfer */ + + /* MPI variables */ + MPI_Offset mpi_file_offset; /* Base file offset of the next transfer*/ + MPI_Offset mpi_offset; /* Offset in MPI file */ + MPI_Offset mpi_offset_advance; /* Offset advance after each I/O operation */ + MPI_Datatype mpi_file_type; /* MPI derived type for 1D file */ + MPI_Datatype mpi_blk_type; /* MPI derived type for 1D buffer */ + MPI_Datatype mpi_cont_type; /* MPI derived type for 2D contiguous file */ + MPI_Datatype mpi_partial_buffer_cont; /* MPI derived type for partial 2D contiguous buffer */ + MPI_Datatype mpi_inter_type; /* MPI derived type for 2D interleaved file */ + MPI_Datatype mpi_partial_buffer_inter; /* MPI derived type for partial 2D interleaved buffer */ + MPI_Datatype mpi_full_buffer; /* MPI derived type for 2D full buffer */ + MPI_Datatype mpi_full_chunk; /* MPI derived type for 2D full chunk */ + MPI_Datatype mpi_chunk_inter_type; /* MPI derived type for 2D chunk interleaved file */ + MPI_Datatype mpi_collective_type; /* Generic MPI derived type for 2D collective access */ + MPI_Status mpi_status; + int mrc; /* MPI return code */ + + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + hsize_t h5dims[2]; /*dataset dim sizes */ + hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ + hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ + hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ + hsize_t h5block[2]; /*dataspace selection */ + hsize_t h5stride[2]; + hsize_t h5count[2]; + hsize_t h5start[2]; + hssize_t h5offset[2]; /* Selection offset within dataspace */ + hid_t h5dcpl = H5I_INVALID_HID; /* Dataset creation property list */ + hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ + + /* Get the parameters from the parameter block */ + blk_size = parms->blk_size; + + /* There are two kinds of transfer patterns, contiguous and interleaved. + * Let 0,1,2,...,n be data accessed by process 0,1,2,...,n + * where n is rank of the last process. + * In contiguous pattern, data are accessed as + * 000...111...222...nnn... + * In interleaved pattern, data are accessed as + * 012...n012...n... + * These are all in the scope of one dataset. + */ + + /* 1D dataspace */ + if (!parms->dim2d) { + /* Contiguous Pattern: */ + if (!parms->interleaved) { + bytes_begin[0] = (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); + } /* end if */ + /* Interleaved Pattern: */ + else { + bytes_begin[0] = (off_t)(blk_size * (size_t)pio_mpi_rank_g); + } /* end else */ + + /* Prepare buffer for verifying data */ + if (parms->verify) + memset(buffer, pio_mpi_rank_g + 1, buf_size); + } /* end if */ + /* 2D dataspace */ + else { + /* nbytes is always the number of bytes per dataset (1D or 2D). If the + dataspace is 2D, snbytes is the size of a side of the dataset square. + */ + snbytes = sqrto(nbytes); + + /* Contiguous Pattern: */ + if (!parms->interleaved) { + bytes_begin[0] = (off_t)((double)snbytes * pio_mpi_rank_g / pio_mpi_nprocs_g); + bytes_begin[1] = 0; + } /* end if */ + /* Interleaved Pattern: */ + else { + bytes_begin[0] = 0; + + if (!parms->h5_use_chunks || parms->io_type == PHDF5) + bytes_begin[1] = (off_t)(blk_size * (size_t)pio_mpi_rank_g); + else + bytes_begin[1] = (off_t)(blk_size * blk_size * (size_t)pio_mpi_rank_g); + } /* end else */ + + /* Prepare buffer for verifying data */ + if (parms->verify) + HDmemset(buffer, pio_mpi_rank_g + 1, buf_size * blk_size); + } /* end else */ + + /* Calculate the total number of bytes (bytes_count) to be + * transferred by this process. It may be different for different + * transfer pattern due to rounding to integral values. + */ + /* + * Calculate the beginning bytes of this process and the next. + * bytes_count is the difference between these two beginnings. + * This way, it eliminates any rounding errors. + * (This is tricky, don't mess with the formula, rounding errors + * can easily get introduced) */ + bytes_count = (off_t)(((double)nbytes * (pio_mpi_rank_g + 1)) / pio_mpi_nprocs_g) - + (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); + + /* debug */ + if (pio_debug_level >= 4) { + HDprint_rank(output); + if (!parms->dim2d) { + HDfprintf(output, + "Debug(do_write): " + "buf_size=%zu, bytes_begin=%" H5_PRINTF_LL_WIDTH "d, bytes_count=%" H5_PRINTF_LL_WIDTH + "d\n", + buf_size, (long long)bytes_begin[0], (long long)bytes_count); + } + else { + HDfprintf(output, + "Debug(do_write): " + "linear buf_size=%zu, bytes_begin=(%" H5_PRINTF_LL_WIDTH "d,%" H5_PRINTF_LL_WIDTH + "d), bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", + buf_size * blk_size, (long long)bytes_begin[0], (long long)bytes_begin[1], + (long long)bytes_count); + } + } + + /* I/O Access specific setup */ + switch (parms->io_type) { + case POSIXIO: + /* No extra setup */ + break; + + case MPIO: /* MPI-I/O setup */ + /* 1D dataspace */ + if (!parms->dim2d) { + /* Build block's derived type */ + mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Build file's derived type */ + mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)pio_mpi_nprocs_g, mpi_blk_type, + &mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit file type */ + mrc = MPI_Type_commit(&mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Commit buffer type */ + mrc = MPI_Type_commit(&mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + } /* end if */ + /* 2D dataspace */ + else { + /* Build partial buffer derived type for contiguous access */ + + mrc = MPI_Type_contiguous((int)buf_size, MPI_BYTE, &mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit partial buffer derived type */ + mrc = MPI_Type_commit(&mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build contiguous file's derived type */ + mrc = MPI_Type_vector((int)blk_size, (int)1, (int)((size_t)snbytes / buf_size), + mpi_partial_buffer_cont, &mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit contiguous file type */ + mrc = MPI_Type_commit(&mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build partial buffer derived type for interleaved access */ + mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit partial buffer derived type */ + mrc = MPI_Type_commit(&mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build interleaved file's derived type */ + mrc = MPI_Type_vector((int)buf_size, (int)1, (int)((size_t)snbytes / blk_size), + mpi_partial_buffer_inter, &mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit interleaved file type */ + mrc = MPI_Type_commit(&mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build full buffer derived type */ + mrc = MPI_Type_contiguous((int)(blk_size * buf_size), MPI_BYTE, &mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit full buffer derived type */ + mrc = MPI_Type_commit(&mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build full chunk derived type */ + mrc = MPI_Type_contiguous((int)(blk_size * blk_size), MPI_BYTE, &mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit full chunk derived type */ + mrc = MPI_Type_commit(&mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build chunk interleaved file's derived type */ + mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)((size_t)snbytes / blk_size), + mpi_full_chunk, &mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit chunk interleaved file type */ + mrc = MPI_Type_commit(&mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + } /* end else */ + break; + + case PHDF5: /* HDF5 setup */ + /* 1D dataspace */ + if (!parms->dim2d) { + if (nbytes > 0) { + /* define a contiguous dataset of nbytes native bytes */ + h5dims[0] = (hsize_t)nbytes; + h5dset_space_id = H5Screate_simple(1, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + + /* Set up the file dset space id to select the pattern to access */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5stride[0] = h5block[0] = blk_size; + h5count[0] = buf_size / blk_size; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5stride[0] = blk_size * (size_t)pio_mpi_nprocs_g; + h5block[0] = blk_size; + h5count[0] = buf_size / blk_size; + } /* end else */ + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, + h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + } /* end if */ + else { + h5dset_space_id = H5Screate(H5S_SCALAR); + VRFY((h5dset_space_id >= 0), "H5Screate"); + } /* end else */ + + /* Create the memory dataspace that corresponds to the xfer buffer */ + if (buf_size > 0) { + h5dims[0] = buf_size; + h5mem_space_id = H5Screate_simple(1, h5dims, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + } /* end if */ + else { + h5mem_space_id = H5Screate(H5S_SCALAR); + VRFY((h5mem_space_id >= 0), "H5Screate"); + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + if (nbytes > 0) { + /* define a contiguous dataset of nbytes native bytes */ + h5dims[0] = (hsize_t)snbytes; + h5dims[1] = (hsize_t)snbytes; + h5dset_space_id = H5Screate_simple(2, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + + /* Set up the file dset space id to select the pattern to access */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5start[1] = (hsize_t)bytes_begin[1]; + h5stride[0] = 1; + h5stride[1] = h5block[0] = h5block[1] = blk_size; + h5count[0] = 1; + h5count[1] = buf_size / blk_size; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5start[1] = (hsize_t)bytes_begin[1]; + h5stride[0] = blk_size; + h5stride[1] = blk_size * (size_t)pio_mpi_nprocs_g; + h5block[0] = h5block[1] = blk_size; + h5count[0] = buf_size / blk_size; + h5count[1] = 1; + } /* end else */ + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, + h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + } /* end if */ + else { + h5dset_space_id = H5Screate(H5S_SCALAR); + VRFY((h5dset_space_id >= 0), "H5Screate"); + } /* end else */ + + /* Create the memory dataspace that corresponds to the xfer buffer */ + if (buf_size > 0) { + if (!parms->interleaved) { + h5dims[0] = blk_size; + h5dims[1] = buf_size; + } + else { + h5dims[0] = buf_size; + h5dims[1] = blk_size; + } + h5mem_space_id = H5Screate_simple(2, h5dims, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + } /* end if */ + else { + h5mem_space_id = H5Screate(H5S_SCALAR); + VRFY((h5mem_space_id >= 0), "H5Screate"); + } /* end else */ + } /* end else */ + + /* Create the dataset transfer property list */ + h5dxpl = H5Pcreate(H5P_DATASET_XFER); + if (h5dxpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + /* Change to collective I/O, if asked */ + if (parms->collective) { + hrc = H5Pset_dxpl_mpio(h5dxpl, H5FD_MPIO_COLLECTIVE); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } /* end if */ + } /* end if */ + break; + + default: + break; + } /* end switch */ + + for (ndset = 1; ndset <= ndsets; ++ndset) { + + /* Calculate dataset offset within a file */ + + /* create dataset */ + switch (parms->io_type) { + case POSIXIO: + case MPIO: + /* both posix and mpi io just need dataset offset in file*/ + dset_offset = (ndset - 1) * nbytes; + break; + + case PHDF5: + h5dcpl = H5Pcreate(H5P_DATASET_CREATE); + if (h5dcpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + /* 1D dataspace */ + if (!parms->dim2d) { + /* Make the dataset chunked if asked */ + if (parms->h5_use_chunks) { + /* Set the chunk size to be the same as the buffer size */ + h5dims[0] = blk_size; + hrc = H5Pset_chunk(h5dcpl, 1, h5dims); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } /* end if */ + } /* end if */ + } /* end if */ + else { + /* 2D dataspace */ + if (parms->h5_use_chunks) { + /* Set the chunk size to be the same as the block size */ + h5dims[0] = blk_size; + h5dims[1] = blk_size; + hrc = H5Pset_chunk(h5dcpl, 2, h5dims); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } /* end if */ + } /* end if */ + } /* end else */ + + HDsprintf(dname, "Dataset_%ld", ndset); + h5ds_id = H5DCREATE(fd->h5fd, dname, ELMT_H5_TYPE, h5dset_space_id, h5dcpl); + + if (h5ds_id < 0) { + HDfprintf(stderr, "HDF5 Dataset Create failed\n"); + GOTOERROR(FAIL); + } + + hrc = H5Pclose(h5dcpl); + /* verifying the close of the dcpl */ + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Close failed\n"); + GOTOERROR(FAIL); + } + break; + + default: + break; + } + + /* The task is to transfer bytes_count bytes, starting at + * bytes_begin position, using transfer buffer of buf_size bytes. + * If interleaved, select buf_size at a time, in round robin + * fashion, according to number of process. Otherwise, select + * all bytes_count in contiguous. + */ + nbytes_xfer = 0; + + /* 1D dataspace */ + if (!parms->dim2d) { + /* Set base file offset for all I/O patterns and POSIX access */ + posix_file_offset = dset_offset + bytes_begin[0]; + + /* Set base file offset for all I/O patterns and MPI access */ + mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0]); + } /* end if */ + else { + /* Set base file offset for all I/O patterns and POSIX access */ + posix_file_offset = dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]; + + /* Set base file offset for all I/O patterns and MPI access */ + mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]); + } /* end else */ + + /* Start "raw data" write timer */ + io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTART); + + while (nbytes_xfer < bytes_count) { + /* Write */ + /* Calculate offset of write within a dataset/file */ + switch (parms->io_type) { + case POSIXIO: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Contiguous pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + (off_t)nbytes_xfer; + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are written */ + rc = ((ssize_t)buf_size == POSIXWRITE(fd->posixfd, buffer, buf_size)); + VRFY((rc != 0), "POSIXWRITE"); + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size; + + /* Loop over the buffers to write */ + while (nbytes_toxfer > 0) { + /* Skip offset over blocks of other processes */ + file_offset = posix_file_offset + (off_t)(nbytes_xfer * pio_mpi_nprocs_g); + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are written */ + rc = ((ssize_t)blk_size == POSIXWRITE(fd->posixfd, buf_p, blk_size)); + VRFY((rc != 0), "POSIXWRITE"); + + /* Advance location in buffer */ + buf_p += blk_size; + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)blk_size; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= blk_size; + } /* end while */ + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + /* Contiguous storage */ + if (!parms->h5_use_chunks) { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + + (off_t)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * + (blk_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / blk_size) % (size_t)snbytes)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = buf_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = (off_t)snbytes; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute file offset */ + file_offset = + posix_file_offset + + (off_t)(((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / + (size_t)snbytes) * + (buf_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % + (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = (off_t)snbytes; + } /* end else */ + } /* end if */ + /* Chunked storage */ + else { + /*Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + (off_t)nbytes_xfer; + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * buf_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = 0; + } /* end if */ + /*Interleaved access pattern */ + else { + /* Compute file offset */ + /* Before simplification */ + /* file_offset=posix_file_offset+(off_t)((nbytes_xfer/(buf_size/blk_size) + *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))*(buf_size/blk_size + *snbytes/blk_size*(blk_size*blk_size))+((nbytes_xfer/(buf_size/blk_size)) + *pio_mpi_nprocs_g)%(snbytes/blk_size*(blk_size*blk_size))); */ + + file_offset = posix_file_offset + + (off_t)((((size_t)nbytes_xfer / (buf_size / blk_size) * + (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * blk_size)) * + (buf_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / (buf_size / blk_size)) * + (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * blk_size)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * blk_size; + + /* Global offset advance after each I/O operation */ + /* file_offset_advance = (off_t)(snbytes/blk_size*(blk_size*blk_size)); */ + file_offset_advance = (off_t)snbytes * (off_t)blk_size; + } /* end else */ + } /* end else */ + + /* Common code for file access */ + + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size * blk_size; + + /* Loop over portions of the buffer to write */ + while (nbytes_toxfer > 0) { + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are written */ + rc = ((ssize_t)nbytes_xfer_advance == + POSIXWRITE(fd->posixfd, buf_p, nbytes_xfer_advance)); + VRFY((rc != 0), "POSIXWRITE"); + + /* Advance location in buffer */ + buf_p += nbytes_xfer_advance; + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)nbytes_xfer_advance; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= nbytes_xfer_advance; + + /* Partially advance file offset */ + file_offset += file_offset_advance; + } /* end while */ + + } /* end else */ + + break; + + case MPIO: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Independent file access */ + if (!parms->collective) { + /* Contiguous pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Perform independent write */ + mrc = + MPI_File_write_at(fd->mpifd, mpi_offset, buffer, + (int)(buf_size / blk_size), mpi_blk_type, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size; + + /* Loop over the buffers to write */ + while (nbytes_toxfer > 0) { + /* Skip offset over blocks of other processes */ + mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); + + /* Perform independent write */ + mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buf_p, (int)1, + mpi_blk_type, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance location in buffer */ + buf_p += blk_size; + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)blk_size; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= blk_size; + } /* end while */ + } /* end else */ + } /* end if */ + /* Collective file access */ + else { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Perform independent write */ + mrc = MPI_File_write_at_all(fd->mpifd, mpi_offset, buffer, + (int)(buf_size / blk_size), mpi_blk_type, + &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); + + /* Set the file view */ + mrc = MPI_File_set_view(fd->mpifd, mpi_offset, mpi_blk_type, mpi_file_type, + (char *)"native", h5_io_info_g); + VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); + + /* Perform write */ + mrc = MPI_File_write_at_all(fd->mpifd, 0, buffer, (int)(buf_size / blk_size), + mpi_blk_type, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)buf_size; + } /* end else */ + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + /* Contiguous storage */ + if (!parms->h5_use_chunks) { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = + mpi_file_offset + + (MPI_Offset)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * + (blk_size * (size_t)snbytes)) + + (MPI_Offset)(((size_t)nbytes_xfer / blk_size) % (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = buf_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = snbytes; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_cont_type; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute offset in file */ + mpi_offset = + mpi_file_offset + + (MPI_Offset)( + ((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / + (size_t)snbytes) * + (buf_size * (size_t)snbytes)) + + (MPI_Offset)( + (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % + (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = snbytes; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_inter_type; + } /* end else */ + } /* end if */ + /* Chunked storage */ + else { + /*Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * buf_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = 0; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_full_buffer; + } /* end if */ + /*Interleaved access pattern */ + else { + /* Compute offset in file */ + /* Before simplification */ + /* mpi_offset=mpi_file_offset+(nbytes_xfer/(buf_size/blk_size) + *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))* + (buf_size/blk_size*snbytes/blk_size*(blk_size*blk_size))+ + ((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes + /blk_size*(blk_size*blk_size)); */ + mpi_offset = mpi_file_offset + + (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size) * + (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * blk_size)) * + (buf_size * (size_t)snbytes)) + + (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size)) * + (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * blk_size)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * blk_size; + + /* Global offset advance after each I/O operation */ + /* mpi_offset_advance = (MPI_Offset)(snbytes/blk_size*(blk_size*blk_size)); */ + mpi_offset_advance = (MPI_Offset)((size_t)snbytes * blk_size); + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_chunk_inter_type; + } /* end else */ + } /* end else */ + + /* Common code for independent file access */ + if (!parms->collective) { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size * blk_size; + + /* Loop over portions of the buffer to write */ + while (nbytes_toxfer > 0) { + /* Perform independent write */ + mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buf_p, + (int)nbytes_xfer_advance, MPI_BYTE, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance location in buffer */ + buf_p += nbytes_xfer_advance; + + /* Advance global offset in dataset */ + nbytes_xfer += (ssize_t)nbytes_xfer_advance; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= nbytes_xfer_advance; + + /* Partially advance global offset in dataset */ + mpi_offset += mpi_offset_advance; + } /* end while */ + } /* end if */ + + /* Common code for collective file access */ + else { + /* Set the file view */ + mrc = MPI_File_set_view(fd->mpifd, mpi_offset, MPI_BYTE, mpi_collective_type, + (char *)"native", h5_io_info_g); + VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); + + /* Perform write */ + MPI_File_write_at_all(fd->mpifd, 0, buffer, (int)(buf_size * blk_size), MPI_BYTE, + &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size * (off_t)blk_size; + } /* end else */ + + } /* end else */ + + break; + + case PHDF5: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Set up the file dset space id to move the selection to process */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5offset[0] = nbytes_xfer; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5offset[0] = (nbytes_xfer * pio_mpi_nprocs_g); + } /* end else */ + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + + /* Write the buffer out */ + hrc = + H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dwrite"); + + /* Increment number of bytes transferred */ + nbytes_xfer += (ssize_t)buf_size; + } /* end if */ + /* 2D dataspace */ + else { + /* Set up the file dset space id to move the selection to process */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5offset[0] = + (hssize_t)(((size_t)nbytes_xfer / ((size_t)snbytes * blk_size)) * blk_size); + h5offset[1] = + (hssize_t)(((size_t)nbytes_xfer % ((size_t)snbytes * blk_size)) / blk_size); + + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5offset[0] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * buf_size)) * + buf_size); + h5offset[1] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * buf_size)) / + buf_size); + + } /* end else */ + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + + /* Write the buffer out */ + hrc = + H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dwrite"); + + /* Increment number of bytes transferred */ + nbytes_xfer += (off_t)buf_size * (off_t)blk_size; + + } /* end else */ + + break; + + default: + break; + } /* switch (parms->io_type) */ + } /* end while */ + + /* Stop "raw data" write timer */ + io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTOP); + + /* Calculate write time */ + + /* Close dataset. Only HDF5 needs to do an explicit close. */ + if (parms->io_type == PHDF5) { + hrc = H5Dclose(h5ds_id); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Close failed\n"); + GOTOERROR(FAIL); + } + + h5ds_id = H5I_INVALID_HID; + } /* end if */ + } /* end for */ + +done: + /* release MPI-I/O objects */ + if (parms->io_type == MPIO) { + /* 1D dataspace */ + if (!parms->dim2d) { + /* Free file type */ + mrc = MPI_Type_free(&mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free buffer type */ + mrc = MPI_Type_free(&mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + } /* end if */ + /* 2D dataspace */ + else { + /* Free partial buffer type for contiguous access */ + mrc = MPI_Type_free(&mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free contiguous file type */ + mrc = MPI_Type_free(&mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free partial buffer type for interleaved access */ + mrc = MPI_Type_free(&mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free interleaved file type */ + mrc = MPI_Type_free(&mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free full buffer type */ + mrc = MPI_Type_free(&mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free full chunk type */ + mrc = MPI_Type_free(&mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free chunk interleaved file type */ + mrc = MPI_Type_free(&mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + } /* end else */ + } /* end if */ + + /* release HDF5 objects */ + if (h5dset_space_id != -1) { + hrc = H5Sclose(h5dset_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); + ret_code = FAIL; + } + else { + h5dset_space_id = H5I_INVALID_HID; + } + } + + if (h5mem_space_id != -1) { + hrc = H5Sclose(h5mem_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); + ret_code = FAIL; + } + else { + h5mem_space_id = H5I_INVALID_HID; + } + } + + if (h5dxpl != -1) { + hrc = H5Pclose(h5dxpl); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); + ret_code = FAIL; + } + else { + h5dxpl = H5I_INVALID_HID; + } + } + + return ret_code; +} + +static off_t +sqrto(off_t x) +{ + double root_x = sqrt((double)x); + return (off_t)root_x; +} + +/* + * Function: do_read + * Purpose: read the required amount of data from the file. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng 2001/12/13 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +static herr_t +do_read(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nbytes, size_t buf_size, + void *buffer /*out*/) +{ + int ret_code = SUCCESS; + int rc; /*routine return code */ + long ndset; + size_t blk_size; /* The block size to subdivide the xfer buffer into */ + size_t bsize; /* Size of the actual buffer */ + off_t nbytes_xfer; /* Total number of bytes transferred so far */ + size_t nbytes_xfer_advance; /* Number of bytes transferred in a single I/O operation */ + size_t nbytes_toxfer; /* Number of bytes to transfer a particular time */ + char dname[64]; + off_t dset_offset = 0; /*dataset offset in a file */ + off_t bytes_begin[2]; /*first elmt this process transfer */ + off_t bytes_count; /*number of elmts this process transfer */ + off_t snbytes = 0; /*size of a side of the dataset square */ + unsigned char *buf_p; /* Current buffer pointer */ + + /* POSIX variables */ + off_t file_offset; /* File offset of the next transfer */ + off_t file_offset_advance; /* File offset advance after each I/O operation */ + off_t posix_file_offset; /* Base file offset of the next transfer */ + + /* MPI variables */ + MPI_Offset mpi_file_offset; /* Base file offset of the next transfer*/ + MPI_Offset mpi_offset; /* Offset in MPI file */ + MPI_Offset mpi_offset_advance; /* Offset advance after each I/O operation */ + MPI_Datatype mpi_file_type; /* MPI derived type for 1D file */ + MPI_Datatype mpi_blk_type; /* MPI derived type for 1D buffer */ + MPI_Datatype mpi_cont_type; /* MPI derived type for 2D contiguous file */ + MPI_Datatype mpi_partial_buffer_cont; /* MPI derived type for partial 2D contiguous buffer */ + MPI_Datatype mpi_inter_type; /* MPI derived type for 2D interleaved file */ + MPI_Datatype mpi_partial_buffer_inter; /* MPI derived type for partial 2D interleaved buffer */ + MPI_Datatype mpi_full_buffer; /* MPI derived type for 2D full buffer */ + MPI_Datatype mpi_full_chunk; /* MPI derived type for 2D full chunk */ + MPI_Datatype mpi_chunk_inter_type; /* MPI derived type for 2D chunk interleaved file */ + MPI_Datatype mpi_collective_type; /* Generic MPI derived type for 2D collective access */ + MPI_Status mpi_status; + int mrc; /* MPI return code */ + + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + hsize_t h5dims[2]; /*dataset dim sizes */ + hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ + hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ + hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ + hsize_t h5block[2]; /*dataspace selection */ + hsize_t h5stride[2]; + hsize_t h5count[2]; + hsize_t h5start[2]; + hssize_t h5offset[2]; /* Selection offset within dataspace */ + hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ + + /* Get the parameters from the parameter block */ + blk_size = parms->blk_size; + + /* There are two kinds of transfer patterns, contiguous and interleaved. + * Let 0,1,2,...,n be data accessed by process 0,1,2,...,n + * where n is rank of the last process. + * In contiguous pattern, data are accessed as + * 000...111...222...nnn... + * In interleaved pattern, data are accessed as + * 012...n012...n... + * These are all in the scope of one dataset. + */ + + /* 1D dataspace */ + if (!parms->dim2d) { + bsize = buf_size; + /* Contiguous Pattern: */ + if (!parms->interleaved) { + bytes_begin[0] = (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); + } /* end if */ + /* Interleaved Pattern: */ + else { + bytes_begin[0] = (off_t)blk_size * (off_t)pio_mpi_rank_g; + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + /* nbytes is always the number of bytes per dataset (1D or 2D). If the + dataspace is 2D, snbytes is the size of a side of the 'dataset square'. + */ + snbytes = sqrto(nbytes); + + bsize = buf_size * blk_size; + + /* Contiguous Pattern: */ + if (!parms->interleaved) { + bytes_begin[0] = (off_t)((double)snbytes * pio_mpi_rank_g / pio_mpi_nprocs_g); + bytes_begin[1] = 0; + } /* end if */ + /* Interleaved Pattern: */ + else { + bytes_begin[0] = 0; + + if (!parms->h5_use_chunks || parms->io_type == PHDF5) + bytes_begin[1] = (off_t)blk_size * (off_t)pio_mpi_rank_g; + else + bytes_begin[1] = (off_t)blk_size * (off_t)blk_size * (off_t)pio_mpi_rank_g; + } /* end else */ + } /* end else */ + + /* Calculate the total number of bytes (bytes_count) to be + * transferred by this process. It may be different for different + * transfer pattern due to rounding to integral values. + */ + /* + * Calculate the beginning bytes of this process and the next. + * bytes_count is the difference between these two beginnings. + * This way, it eliminates any rounding errors. + * (This is tricky, don't mess with the formula, rounding errors + * can easily get introduced) */ + bytes_count = (off_t)(((double)nbytes * (pio_mpi_rank_g + 1)) / pio_mpi_nprocs_g) - + (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); + + /* debug */ + if (pio_debug_level >= 4) { + HDprint_rank(output); + if (!parms->dim2d) { + HDfprintf(output, + "Debug(do_write): " + "buf_size=%zu, bytes_begin=%" H5_PRINTF_LL_WIDTH "d, bytes_count=%" H5_PRINTF_LL_WIDTH + "d\n", + buf_size, (long long)bytes_begin[0], (long long)bytes_count); + } + else { + HDfprintf(output, + "Debug(do_write): " + "linear buf_size=%zu, bytes_begin=(%" H5_PRINTF_LL_WIDTH "d,%" H5_PRINTF_LL_WIDTH + "d), bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", + buf_size * blk_size, (long long)bytes_begin[0], (long long)bytes_begin[1], + (long long)bytes_count); + } + } + + /* I/O Access specific setup */ + switch (parms->io_type) { + case POSIXIO: + /* No extra setup */ + break; + + case MPIO: /* MPI-I/O setup */ + /* 1D dataspace */ + if (!parms->dim2d) { + /* Build block's derived type */ + mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Build file's derived type */ + mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)pio_mpi_nprocs_g, mpi_blk_type, + &mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit file type */ + mrc = MPI_Type_commit(&mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Commit buffer type */ + mrc = MPI_Type_commit(&mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + } /* end if */ + /* 2D dataspace */ + else { + /* Build partial buffer derived type for contiguous access */ + mrc = MPI_Type_contiguous((int)buf_size, MPI_BYTE, &mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit partial buffer derived type */ + mrc = MPI_Type_commit(&mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build contiguous file's derived type */ + mrc = MPI_Type_vector((int)blk_size, (int)1, (int)((size_t)snbytes / buf_size), + mpi_partial_buffer_cont, &mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit contiguous file type */ + mrc = MPI_Type_commit(&mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build partial buffer derived type for interleaved access */ + mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit partial buffer derived type */ + mrc = MPI_Type_commit(&mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build interleaved file's derived type */ + mrc = MPI_Type_vector((int)buf_size, (int)1, (int)((size_t)snbytes / blk_size), + mpi_partial_buffer_inter, &mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit interleaved file type */ + mrc = MPI_Type_commit(&mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build full buffer derived type */ + mrc = MPI_Type_contiguous((int)(blk_size * buf_size), MPI_BYTE, &mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit full buffer derived type */ + mrc = MPI_Type_commit(&mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build full chunk derived type */ + mrc = MPI_Type_contiguous((int)(blk_size * blk_size), MPI_BYTE, &mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit full chunk derived type */ + mrc = MPI_Type_commit(&mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + + /* Build chunk interleaved file's derived type */ + mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)((size_t)snbytes / blk_size), + mpi_full_chunk, &mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); + + /* Commit chunk interleaved file type */ + mrc = MPI_Type_commit(&mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); + } /* end else */ + break; + + case PHDF5: /* HDF5 setup */ + /* 1D dataspace */ + if (!parms->dim2d) { + if (nbytes > 0) { + /* define a contiguous dataset of nbytes native bytes */ + h5dims[0] = (hsize_t)nbytes; + h5dset_space_id = H5Screate_simple(1, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + + /* Set up the file dset space id to select the pattern to access */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5stride[0] = h5block[0] = blk_size; + h5count[0] = buf_size / blk_size; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5stride[0] = blk_size * (size_t)pio_mpi_nprocs_g; + h5block[0] = blk_size; + h5count[0] = buf_size / blk_size; + } /* end else */ + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, + h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + } /* end if */ + else { + h5dset_space_id = H5Screate(H5S_SCALAR); + VRFY((h5dset_space_id >= 0), "H5Screate"); + } /* end else */ + + /* Create the memory dataspace that corresponds to the xfer buffer */ + if (buf_size > 0) { + h5dims[0] = buf_size; + h5mem_space_id = H5Screate_simple(1, h5dims, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + } /* end if */ + else { + h5mem_space_id = H5Screate(H5S_SCALAR); + VRFY((h5mem_space_id >= 0), "H5Screate"); + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + if (nbytes > 0) { + /* define a contiguous dataset of nbytes native bytes */ + h5dims[0] = (hsize_t)snbytes; + h5dims[1] = (hsize_t)snbytes; + h5dset_space_id = H5Screate_simple(2, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + + /* Set up the file dset space id to select the pattern to access */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5start[1] = (hsize_t)bytes_begin[1]; + h5stride[0] = 1; + h5stride[1] = h5block[0] = h5block[1] = blk_size; + h5count[0] = 1; + h5count[1] = buf_size / blk_size; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5start[0] = (hsize_t)bytes_begin[0]; + h5start[1] = (hsize_t)bytes_begin[1]; + h5stride[0] = blk_size; + h5stride[1] = blk_size * (size_t)pio_mpi_nprocs_g; + h5block[0] = h5block[1] = blk_size; + h5count[0] = buf_size / blk_size; + h5count[1] = 1; + } /* end else */ + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, + h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + } /* end if */ + else { + h5dset_space_id = H5Screate(H5S_SCALAR); + VRFY((h5dset_space_id >= 0), "H5Screate"); + } /* end else */ + + /* Create the memory dataspace that corresponds to the xfer buffer */ + if (buf_size > 0) { + if (!parms->interleaved) { + h5dims[0] = blk_size; + h5dims[1] = buf_size; + } + else { + h5dims[0] = buf_size; + h5dims[1] = blk_size; + } + h5mem_space_id = H5Screate_simple(2, h5dims, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + } /* end if */ + else { + h5mem_space_id = H5Screate(H5S_SCALAR); + VRFY((h5mem_space_id >= 0), "H5Screate"); + } /* end else */ + } /* end else */ + + /* Create the dataset transfer property list */ + h5dxpl = H5Pcreate(H5P_DATASET_XFER); + if (h5dxpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + /* Change to collective I/O, if asked */ + if (parms->collective) { + hrc = H5Pset_dxpl_mpio(h5dxpl, H5FD_MPIO_COLLECTIVE); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } /* end if */ + } /* end if */ + break; + + default: + break; + } /* end switch */ + + for (ndset = 1; ndset <= ndsets; ++ndset) { + + /* Calculate dataset offset within a file */ + + /* create dataset */ + switch (parms->io_type) { + case POSIXIO: + case MPIO: + /* both posix and mpi io just need dataset offset in file*/ + dset_offset = (ndset - 1) * nbytes; + break; + + case PHDF5: + HDsprintf(dname, "Dataset_%ld", ndset); + h5ds_id = H5DOPEN(fd->h5fd, dname); + if (h5ds_id < 0) { + HDfprintf(stderr, "HDF5 Dataset open failed\n"); + GOTOERROR(FAIL); + } + break; + + default: + break; + } + + /* The task is to transfer bytes_count bytes, starting at + * bytes_begin position, using transfer buffer of buf_size bytes. + * If interleaved, select buf_size at a time, in round robin + * fashion, according to number of process. Otherwise, select + * all bytes_count in contiguous. + */ + nbytes_xfer = 0; + + /* 1D dataspace */ + if (!parms->dim2d) { + /* Set base file offset for all I/O patterns and POSIX access */ + posix_file_offset = dset_offset + bytes_begin[0]; + + /* Set base file offset for all I/O patterns and MPI access */ + mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0]); + } /* end if */ + else { + /* Set base file offset for all I/O patterns and POSIX access */ + posix_file_offset = dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]; + + /* Set base file offset for all I/O patterns and MPI access */ + mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]); + } /* end else */ + + /* Start "raw data" read timer */ + io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTART); + + while (nbytes_xfer < bytes_count) { + /* Read */ + /* Calculate offset of read within a dataset/file */ + switch (parms->io_type) { + case POSIXIO: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Contiguous pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + (off_t)nbytes_xfer; + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are read */ + rc = ((ssize_t)buf_size == POSIXREAD(fd->posixfd, buffer, buf_size)); + VRFY((rc != 0), "POSIXREAD"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size; + + /* Loop over the buffers to read */ + while (nbytes_toxfer > 0) { + /* Skip offset over blocks of other processes */ + file_offset = posix_file_offset + (off_t)(nbytes_xfer * pio_mpi_nprocs_g); + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are read */ + rc = ((ssize_t)blk_size == POSIXREAD(fd->posixfd, buf_p, blk_size)); + VRFY((rc != 0), "POSIXREAD"); + + /* Advance location in buffer */ + buf_p += blk_size; + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)blk_size; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= blk_size; + } /* end while */ + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + /* Contiguous storage */ + if (!parms->h5_use_chunks) { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + + (off_t)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * + (blk_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / blk_size) % (size_t)snbytes)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = buf_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = (off_t)snbytes; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute file offset */ + file_offset = + posix_file_offset + + (off_t)(((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / + (size_t)snbytes) * + (buf_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % + (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = (off_t)snbytes; + } /* end else */ + } /* end if */ + /* Chunked storage */ + else { + /*Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute file offset */ + file_offset = posix_file_offset + (off_t)nbytes_xfer; + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * buf_size; + + /* Global offset advance after each I/O operation */ + file_offset_advance = 0; + } /* end if */ + /*Interleaved access pattern */ + else { + /* Compute file offset */ + /* Before simplification */ + /* file_offset=posix_file_offset+(off_t)((nbytes_xfer/(buf_size/blk_size) + *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))*(buf_size/blk_size + *snbytes/blk_size*(blk_size*blk_size))+((nbytes_xfer/(buf_size/blk_size)) + *pio_mpi_nprocs_g)%(snbytes/blk_size*(blk_size*blk_size))); */ + + file_offset = posix_file_offset + + (off_t)((((size_t)nbytes_xfer / (buf_size / blk_size) * + (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * blk_size)) * + (buf_size * (size_t)snbytes) + + (((size_t)nbytes_xfer / (buf_size / blk_size)) * + (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * blk_size)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * blk_size; + + /* Global offset advance after each I/O operation */ + /* file_offset_advance = (off_t)(snbytes/blk_size*(blk_size*blk_size)); */ + file_offset_advance = (off_t)((size_t)snbytes * blk_size); + } /* end else */ + } /* end else */ + + /* Common code for file access */ + + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size * blk_size; + + /* Loop over portions of the buffer to read */ + while (nbytes_toxfer > 0) { + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + + /* check if all bytes are read */ + rc = ((ssize_t)nbytes_xfer_advance == + POSIXREAD(fd->posixfd, buf_p, nbytes_xfer_advance)); + VRFY((rc != 0), "POSIXREAD"); + + /* Advance location in buffer */ + buf_p += nbytes_xfer_advance; + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)nbytes_xfer_advance; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= nbytes_xfer_advance; + + /* Partially advance file offset */ + file_offset += file_offset_advance; + } /* end while */ + + } /* end else */ + break; + + case MPIO: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Independent file access */ + if (!parms->collective) { + /* Contiguous pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Perform independent read */ + mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buffer, + (int)(buf_size / blk_size), mpi_blk_type, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size; + + /* Loop over the buffers to read */ + while (nbytes_toxfer > 0) { + /* Skip offset over blocks of other processes */ + mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); + + /* Perform independent read */ + mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buf_p, (int)1, mpi_blk_type, + &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance location in buffer */ + buf_p += blk_size; + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)blk_size; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= blk_size; + } /* end while */ + } /* end else */ + } /* end if */ + /* Collective file access */ + else { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Perform collective read */ + mrc = MPI_File_read_at_all(fd->mpifd, mpi_offset, buffer, + (int)(buf_size / blk_size), mpi_blk_type, + &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); + + /* Set the file view */ + mrc = MPI_File_set_view(fd->mpifd, mpi_offset, mpi_blk_type, mpi_file_type, + (char *)"native", h5_io_info_g); + VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); + + /* Perform collective read */ + mrc = MPI_File_read_at_all(fd->mpifd, 0, buffer, (int)(buf_size / blk_size), + mpi_blk_type, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size; + } /* end else */ + } /* end else */ + } /* end if */ + /* 2D dataspace */ + else { + /* Contiguous storage */ + if (!parms->h5_use_chunks) { + /* Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = + mpi_file_offset + + (MPI_Offset)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * + (blk_size * (size_t)snbytes)) + + (MPI_Offset)(((size_t)nbytes_xfer / blk_size) % (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = buf_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = snbytes; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_cont_type; + } /* end if */ + /* Interleaved access pattern */ + else { + /* Compute offset in file */ + mpi_offset = + mpi_file_offset + + (MPI_Offset)( + ((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / + (size_t)snbytes) * + (buf_size * (size_t)snbytes)) + + (MPI_Offset)( + (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % + (size_t)snbytes); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = snbytes; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_inter_type; + } /* end else */ + } /* end if */ + /* Chunked storage */ + else { + /*Contiguous access pattern */ + if (!parms->interleaved) { + /* Compute offset in file */ + mpi_offset = mpi_file_offset + nbytes_xfer; + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * buf_size; + + /* Global offset advance after each I/O operation */ + mpi_offset_advance = 0; + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_full_buffer; + } /* end if */ + /*Interleaved access pattern */ + else { + /* Compute offset in file */ + /* Before simplification */ + /* mpi_offset=mpi_file_offset+(nbytes_xfer/(buf_size/blk_size) + *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))* + (buf_size/blk_size*snbytes/blk_size*(blk_size*blk_size))+ + ((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes + /blk_size*(blk_size*blk_size)); */ + mpi_offset = mpi_file_offset + + (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size) * + (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * blk_size)) * + (buf_size * (size_t)snbytes)) + + (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size)) * + (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * blk_size)); + + /* Number of bytes to be transferred per I/O operation */ + nbytes_xfer_advance = blk_size * blk_size; + + /* Global offset advance after each I/O operation */ + /* mpi_offset_advance = (MPI_Offset)(snbytes/blk_size*(blk_size*blk_size)); */ + mpi_offset_advance = (MPI_Offset)((size_t)snbytes * blk_size); + + /* MPI type to be used for collective access */ + mpi_collective_type = mpi_chunk_inter_type; + } /* end else */ + } /* end else */ + + /* Common code for independent file access */ + if (!parms->collective) { + /* Set the base of user's buffer */ + buf_p = (unsigned char *)buffer; + + /* Set the number of bytes to transfer this time */ + nbytes_toxfer = buf_size * blk_size; + + /* Loop over portions of the buffer to read */ + while (nbytes_toxfer > 0) { + /* Perform independent read */ + mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buf_p, (int)nbytes_xfer_advance, + MPI_BYTE, &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance location in buffer */ + buf_p += nbytes_xfer_advance; + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)nbytes_xfer_advance; + + /* Decrement number of bytes left this time */ + nbytes_toxfer -= nbytes_xfer_advance; + + /* Partially advance global offset in dataset */ + mpi_offset += mpi_offset_advance; + } /* end while */ + } /* end if */ + + /* Common code for collective file access */ + else { + /* Set the file view */ + mrc = MPI_File_set_view(fd->mpifd, mpi_offset, MPI_BYTE, mpi_collective_type, + (char *)"native", h5_io_info_g); + VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); + + /* Perform read */ + MPI_File_read_at_all(fd->mpifd, 0, buffer, (int)(buf_size * blk_size), MPI_BYTE, + &mpi_status); + VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); + + /* Advance global offset in dataset */ + nbytes_xfer += (off_t)buf_size * (off_t)blk_size; + } /* end else */ + + } /* end else */ + break; + + case PHDF5: + /* 1D dataspace */ + if (!parms->dim2d) { + /* Set up the file dset space id to move the selection to process */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5offset[0] = nbytes_xfer; + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5offset[0] = (nbytes_xfer * pio_mpi_nprocs_g); + } /* end else */ + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + + /* Read the buffer in */ + hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dread"); + + /* Increment number of bytes transferred */ + nbytes_xfer += (off_t)buf_size; + } /* end if */ + /* 2D dataspace */ + else { + /* Set up the file dset space id to move the selection to process */ + if (!parms->interleaved) { + /* Contiguous pattern */ + h5offset[0] = + (hssize_t)(((size_t)nbytes_xfer / ((size_t)snbytes * blk_size)) * blk_size); + h5offset[1] = + (hssize_t)(((size_t)nbytes_xfer % ((size_t)snbytes * blk_size)) / blk_size); + } /* end if */ + else { + /* Interleaved access pattern */ + /* Skip offset over blocks of other processes */ + h5offset[0] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) / + ((size_t)snbytes * buf_size)) * + buf_size); + h5offset[1] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) % + ((size_t)snbytes * buf_size)) / + buf_size); + + } /* end else */ + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + + /* Write the buffer out */ + hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dread"); + + /* Increment number of bytes transferred */ + nbytes_xfer += (off_t)buf_size * (off_t)blk_size; + + } /* end else */ + break; + + default: + break; + } /* switch (parms->io_type) */ + + /* Verify raw data, if asked */ + if (parms->verify) { + /* Verify data read */ + unsigned char *ucharptr = (unsigned char *)buffer; + size_t i; + int nerror = 0; + + for (i = 0; i < bsize; ++i) { + if (*ucharptr++ != pio_mpi_rank_g + 1) { + if (++nerror < 20) { + /* report at most 20 errors */ + HDprint_rank(output); + HDfprintf(output, + "read data error, expected (%d), " + "got (%d)\n", + pio_mpi_rank_g + 1, (int)*(ucharptr - 1)); + } /* end if */ + } /* end if */ + } /* end for */ + if (nerror >= 20) { + HDprint_rank(output); + HDfprintf(output, "..."); + HDfprintf(output, "total read data errors=%d\n", nerror); + } /* end if */ + } /* if (parms->verify) */ + + } /* end while */ + + /* Stop "raw data" read timer */ + io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTOP); + + /* Calculate read time */ + + /* Close dataset. Only HDF5 needs to do an explicit close. */ + if (parms->io_type == PHDF5) { + hrc = H5Dclose(h5ds_id); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Close failed\n"); + GOTOERROR(FAIL); + } + + h5ds_id = H5I_INVALID_HID; + } /* end if */ + } /* end for */ + +done: + /* release MPI-I/O objects */ + if (parms->io_type == MPIO) { + /* 1D dataspace */ + if (!parms->dim2d) { + /* Free file type */ + mrc = MPI_Type_free(&mpi_file_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free buffer type */ + mrc = MPI_Type_free(&mpi_blk_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + } /* end if */ + /* 2D dataspace */ + else { + /* Free partial buffer type for contiguous access */ + mrc = MPI_Type_free(&mpi_partial_buffer_cont); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free contiguous file type */ + mrc = MPI_Type_free(&mpi_cont_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free partial buffer type for interleaved access */ + mrc = MPI_Type_free(&mpi_partial_buffer_inter); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free interleaved file type */ + mrc = MPI_Type_free(&mpi_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free full buffer type */ + mrc = MPI_Type_free(&mpi_full_buffer); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free full chunk type */ + mrc = MPI_Type_free(&mpi_full_chunk); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + + /* Free chunk interleaved file type */ + mrc = MPI_Type_free(&mpi_chunk_inter_type); + VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); + } /* end else */ + } /* end if */ + + /* release HDF5 objects */ + if (h5dset_space_id != -1) { + hrc = H5Sclose(h5dset_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); + ret_code = FAIL; + } + else { + h5dset_space_id = H5I_INVALID_HID; + } + } + + if (h5mem_space_id != -1) { + hrc = H5Sclose(h5mem_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); + ret_code = FAIL; + } + else { + h5mem_space_id = H5I_INVALID_HID; + } + } + + if (h5dxpl != -1) { + hrc = H5Pclose(h5dxpl); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); + ret_code = FAIL; + } + else { + h5dxpl = H5I_INVALID_HID; + } + } + + return ret_code; +} + +/* + * Function: do_fopen + * Purpose: Open the specified file. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 + * Modifications: + */ +static herr_t +do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags) +{ + int ret_code = SUCCESS, mrc; + hid_t acc_tpl = H5I_INVALID_HID; /* file access templates */ + + switch (param->io_type) { + case POSIXIO: + if (flags & (PIO_CREATE | PIO_WRITE)) + fd->posixfd = POSIXCREATE(fname); + else + fd->posixfd = POSIXOPEN(fname, O_RDONLY); + + if (fd->posixfd < 0) { + HDfprintf(stderr, "POSIX File Open failed(%s)\n", fname); + GOTOERROR(FAIL); + } + + /* The perils of POSIX I/O in a parallel environment. The problem is: + * + * - Process n opens a file with truncation and then starts + * writing to the file. + * - Process m also opens the file with truncation, but after + * process n has already started to write to the file. Thus, + * all of the stuff process n wrote is now lost. + */ + MPI_Barrier(pio_comm_g); + + break; + + case MPIO: + if (flags & (PIO_CREATE | PIO_WRITE)) { + MPI_File_delete(fname, h5_io_info_g); + mrc = MPI_File_open(pio_comm_g, fname, MPI_MODE_CREATE | MPI_MODE_RDWR, h5_io_info_g, + &fd->mpifd); + + if (mrc != MPI_SUCCESS) { + HDfprintf(stderr, "MPI File Open failed(%s)\n", fname); + GOTOERROR(FAIL); + } + + /*since MPI_File_open with MPI_MODE_CREATE does not truncate */ + /*filesize , set size to 0 explicitedly. */ + mrc = MPI_File_set_size(fd->mpifd, (MPI_Offset)0); + if (mrc != MPI_SUCCESS) { + HDfprintf(stderr, "MPI_File_set_size failed\n"); + GOTOERROR(FAIL); + } + } + else { + mrc = MPI_File_open(pio_comm_g, fname, MPI_MODE_RDONLY, h5_io_info_g, &fd->mpifd); + if (mrc != MPI_SUCCESS) { + HDfprintf(stderr, "MPI File Open failed(%s)\n", fname); + GOTOERROR(FAIL); + } + } + + break; + + case PHDF5: + if ((acc_tpl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + /* Set the file driver to the MPI-IO driver */ + if (H5Pset_fapl_mpio(acc_tpl, pio_comm_g, h5_io_info_g) < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } + + /* Set the alignment of objects in HDF5 file */ + if (H5Pset_alignment(acc_tpl, param->h5_thresh, param->h5_align) < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } + + /* create the parallel file */ + if (flags & (PIO_CREATE | PIO_WRITE)) + fd->h5fd = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl); + else + fd->h5fd = H5Fopen(fname, H5F_ACC_RDONLY, acc_tpl); + if (fd->h5fd < 0) { + HDfprintf(stderr, "HDF5 File Create failed(%s)\n", fname); + GOTOERROR(FAIL); + } + + /* verifying the close of the acc_tpl */ + if (H5Pclose(acc_tpl) < 0) { + HDfprintf(stderr, "HDF5 Property List Close failed\n"); + GOTOERROR(FAIL); + } + + break; + + default: + break; + } + +done: + return ret_code; +} + +/* + * Function: do_fclose + * Purpose: Close the specified file descriptor. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 + * Modifications: + */ +static herr_t +do_fclose(iotype iot, file_descr *fd /*out*/) +{ + herr_t ret_code = SUCCESS, hrc; + int mrc = 0, rc = 0; + + switch (iot) { + case POSIXIO: + rc = POSIXCLOSE(fd->posixfd); + + if (rc != 0) { + HDfprintf(stderr, "POSIX File Close failed\n"); + GOTOERROR(FAIL); + } + + fd->posixfd = -1; + break; + + case MPIO: + mrc = MPI_File_close(&fd->mpifd); + + if (mrc != MPI_SUCCESS) { + HDfprintf(stderr, "MPI File close failed\n"); + GOTOERROR(FAIL); + } + + fd->mpifd = MPI_FILE_NULL; + break; + + case PHDF5: + hrc = H5Fclose(fd->h5fd); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 File Close failed\n"); + GOTOERROR(FAIL); + } + + fd->h5fd = -1; + break; + + default: + break; + } + +done: + return ret_code; +} + +/* + * Function: do_fclose + * Purpose: Cleanup temporary file unless HDF5_NOCLEANUP is set. + * Only Proc 0 of the PIO communicator will do the cleanup. + * Other processes just return. + * Return: void + * Programmer: Albert Cheng 2001/12/12 + * Modifications: + */ +static void +do_cleanupfile(iotype iot, char *fname) +{ + if (pio_mpi_rank_g != 0) + return; + + if (clean_file_g == -1) + clean_file_g = (getenv("HDF5_NOCLEANUP") == NULL) ? 1 : 0; + + if (clean_file_g) { + switch (iot) { + case POSIXIO: + HDremove(fname); + break; + case MPIO: + case PHDF5: + MPI_File_delete(fname, h5_io_info_g); + break; + default: + break; + } + } +} + +#ifdef TIME_MPI +/* instrument the MPI_File_wrirte_xxx and read_xxx calls to measure + * pure time spent in MPI_File code. + */ +int +MPI_File_read_at(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, + MPI_Status *status) +{ + int err; + io_time_set(timer_g, HDF5_MPI_READ, TSTART); + err = PMPI_File_read_at(fh, offset, buf, count, datatype, status); + io_time_set(timer_g, HDF5_MPI_READ, TSTOP); + return err; +} + +int +MPI_File_read_at_all(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, + MPI_Status *status) +{ + int err; + io_time_set(timer_g, HDF5_MPI_READ, TSTART); + err = PMPI_File_read_at_all(fh, offset, buf, count, datatype, status); + io_time_set(timer_g, HDF5_MPI_READ, TSTOP); + return err; +} + +int +MPI_File_write_at(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, + MPI_Status *status) +{ + int err; + io_time_set(timer_g, HDF5_MPI_WRITE, TSTART); + err = PMPI_File_write_at(fh, offset, buf, count, datatype, status); + io_time_set(timer_g, HDF5_MPI_WRITE, TSTOP); + return err; +} + +int +MPI_File_write_at_all(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, + MPI_Status *status) +{ + int err; + io_time_set(timer_g, HDF5_MPI_WRITE, TSTART); + err = PMPI_File_write_at_all(fh, offset, buf, count, datatype, status); + io_time_set(timer_g, HDF5_MPI_WRITE, TSTOP); + return err; +} + +#endif /* TIME_MPI */ +#endif /* H5_HAVE_PARALLEL */ diff --git a/tools/src/h5perf/pio_perf.c b/tools/src/h5perf/pio_perf.c new file mode 100644 index 0000000..41245d9 --- /dev/null +++ b/tools/src/h5perf/pio_perf.c @@ -0,0 +1,1718 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Parallel HDF5 Performance Testing Code + * -------------------------------------- + * + * Portable code to test performance on the different platforms we support. + * This is what the report should look like: + * + * nprocs = Max#Procs + * IO API = POSIXIO + * # Files = 1, # of dsets = 1000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * # Files = 1, # of dsets = 3000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * + * . . . + * + * IO API = MPIO + * # Files = 1, # of dsets = 1000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * # Files = 1, # of dsets = 3000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * + * . . . + * + * IO API = PHDF5 + * # Files = 1, # of dsets = 1000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * # Files = 1, # of dsets = 3000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * + * . . . + * + * nprocs = Max#Procs / 2 + * + * . . . + * + */ + +/* system header files */ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include "hdf5.h" + +#ifdef H5_HAVE_PARALLEL + +/* library header files */ +#include <mpi.h> + +/* our header files */ +#include "pio_perf.h" + +/* useful macros */ +#define TAB_SPACE 4 + +#define ONE_KB 1024 +#define ONE_MB (ONE_KB * ONE_KB) +#define ONE_GB (ONE_MB * ONE_KB) + +#define PIO_POSIX 0x1 +#define PIO_MPI 0x2 +#define PIO_HDF5 0x4 + +#ifdef STANDALONE +#define DBL_EPSILON 2.2204460492503131e-16 +#define H5_DBL_ABS_EQUAL(X, Y) (fabs((X) - (Y)) < DBL_EPSILON) +#endif + +/* report 0.0 in case t is zero too */ +#define MB_PER_SEC(bytes, t) (H5_DBL_ABS_EQUAL((t), 0.0) ? 0.0 : ((((double)bytes) / ONE_MB) / (t))) + +#ifndef TRUE +#define TRUE 1 +#endif /* TRUE */ +#ifndef FALSE +#define FALSE (!TRUE) +#endif /* FALSE */ + +/* global variables */ +FILE * output; /* output file */ +int comm_world_rank_g; /* my rank in MPI_COMM_RANK */ +int comm_world_nprocs_g; /* num. of processes of MPI_COMM_WORLD */ +MPI_Comm pio_comm_g; /* Communicator to run the PIO */ +int pio_mpi_rank_g; /* MPI rank of pio_comm_g */ +int pio_mpi_nprocs_g; /* Number of processes of pio_comm_g */ +int pio_debug_level = 0; /* The debug level: + * 0 - Off + * 1 - Minimal + * 2 - Some more + * 3 - Maximal + * 4 - Maximal & then some + */ + +/* local variables */ +static const char *progname = "h5perf"; + +#ifndef HDF5_PARAPREFIX +#define HDF5_PARAPREFIX "" +#endif +char * paraprefix = NULL; /* for command line option para-prefix */ +MPI_Info h5_io_info_g = MPI_INFO_NULL; /* MPI INFO object for IO */ + +/* + * Command-line options: The user can specify short or long-named + * parameters. The long-named ones can be partially spelled. When + * adding more, make sure that they don't clash with each other. + */ +#if 1 +static const char *s_opts = "a:A:B:cCd:D:e:F:ghi:Imno:p:P:stT:wx:X:"; +#else +static const char *s_opts = "a:A:bB:cCd:D:e:F:ghi:Imno:p:P:stT:wx:X:"; +#endif /* 1 */ +static struct h5_long_options l_opts[] = {{"align", require_arg, 'a'}, + {"api", require_arg, 'A'}, +#if 0 + /* a sighting of the elusive binary option */ + { "binary", no_arg, 'b' }, +#endif /* 0 */ + {"block-size", require_arg, 'B'}, + {"chunk", no_arg, 'c'}, + {"collective", no_arg, 'C'}, + {"debug", require_arg, 'D'}, + {"geometry", no_arg, 'g'}, + {"help", no_arg, 'h'}, + {"interleaved", require_arg, 'I'}, + {"max-num-processes", require_arg, 'P'}, + {"min-num-processes", require_arg, 'p'}, + {"max-xfer-size", require_arg, 'X'}, + {"min-xfer-size", require_arg, 'x'}, + {"num-bytes", require_arg, 'e'}, + {"num-dsets", require_arg, 'd'}, + {"num-files", require_arg, 'F'}, + {"num-iterations", require_arg, 'i'}, + {"output", require_arg, 'o'}, + {"threshold", require_arg, 'T'}, + {"write-only", require_arg, 'w'}, + {NULL, 0, '\0'}}; + +struct options { + long io_types; /* bitmask of which I/O types to test */ + const char *output_file; /* file to print report to */ + long num_dsets; /* number of datasets */ + long num_files; /* number of files */ + off_t num_bpp; /* number of bytes per proc per dset */ + int num_iters; /* number of iterations */ + int max_num_procs; /* maximum number of processes to use */ + int min_num_procs; /* minimum number of processes to use */ + size_t max_xfer_size; /* maximum transfer buffer size */ + size_t min_xfer_size; /* minimum transfer buffer size */ + size_t blk_size; /* Block size */ + unsigned interleaved; /* Interleaved vs. contiguous blocks */ + unsigned collective; /* Collective vs. independent I/O */ + unsigned dim2d; /* 1D vs. 2D geometry */ + int print_times; /* print times as well as throughputs */ + int print_raw; /* print raw data throughput info */ + off_t h5_alignment; /* alignment in HDF5 file */ + off_t h5_threshold; /* threshold for alignment in HDF5 file */ + int h5_use_chunks; /* Make HDF5 dataset chunked */ + int h5_write_only; /* Perform the write tests only */ + int verify; /* Verify data correctness */ +}; + +typedef struct _minmax { + double min; + double max; + double sum; + int num; +} minmax; + +/* local functions */ +static off_t parse_size_directive(const char *size); +static struct options *parse_command_line(int argc, char *argv[]); +static void run_test_loop(struct options *options); +static int run_test(iotype iot, parameters parms, struct options *opts); +static void output_all_info(minmax *mm, int count, int indent_level); +static void get_minmax(minmax *mm, double val); +static minmax accumulate_minmax_stuff(minmax *mm, int count); +static int create_comm_world(int num_procs, int *doing_pio); +static int destroy_comm_world(void); +static void output_results(const struct options *options, const char *name, minmax *table, int table_size, + off_t data_size); +static void output_times(const struct options *options, const char *name, minmax *table, int table_size); +static void output_report(const char *fmt, ...); +static void print_indent(register int indent); +static void usage(const char *prog); +static void report_parameters(struct options *opts); +static off_t squareo(off_t); + +/* + * Function: main + * Purpose: Start things up. Initialize MPI and then call the test looping + * function. + * Return: EXIT_SUCCESS or EXIT_FAILURE + * Programmer: Bill Wendling, 30. October 2001 + * Modifications: + */ +int +main(int argc, char *argv[]) +{ + int ret; + int exit_value = EXIT_SUCCESS; + struct options *opts = NULL; + +#ifndef STANDALONE + /* Initialize h5tools lib */ + h5tools_init(); +#endif + + output = stdout; + + /* initialize MPI and get the maximum num of processors we started with */ + MPI_Init(&argc, &argv); + ret = MPI_Comm_size(MPI_COMM_WORLD, &comm_world_nprocs_g); + + if (ret != MPI_SUCCESS) { + HDfprintf(stderr, "%s: MPI_Comm_size call failed\n", progname); + + if (ret == MPI_ERR_COMM) + HDfprintf(stderr, "invalid MPI communicator\n"); + else + HDfprintf(stderr, "invalid argument\n"); + + exit_value = EXIT_FAILURE; + goto finish; + } + + ret = MPI_Comm_rank(MPI_COMM_WORLD, &comm_world_rank_g); + + if (ret != MPI_SUCCESS) { + HDfprintf(stderr, "%s: MPI_Comm_rank call failed\n", progname); + + if (ret == MPI_ERR_COMM) + HDfprintf(stderr, "invalid MPI communicator\n"); + else + HDfprintf(stderr, "invalid argument\n"); + + exit_value = EXIT_FAILURE; + goto finish; + } + + pio_comm_g = MPI_COMM_WORLD; + + h5_set_info_object(); + opts = parse_command_line(argc, argv); + + if (!opts) { + exit_value = EXIT_FAILURE; + goto finish; + } + + if (opts->output_file) { + if ((output = HDfopen(opts->output_file, "w")) == NULL) { + HDfprintf(stderr, "%s: cannot open output file\n", progname); + perror(opts->output_file); + goto finish; + } + } + + if ((pio_debug_level == 0 && comm_world_rank_g == 0) || pio_debug_level > 0) + report_parameters(opts); + + run_test_loop(opts); + +finish: + MPI_Finalize(); + free(opts); + return exit_value; +} + +off_t +squareo(off_t x) +{ + return x * x; +} + +/* + * Function: run_test_loop + * Purpose: Run the I/O tests. Write the results to OUTPUT. + * + * - The slowest changing part of the test is the number of + * processors to use. For each loop iteration, we divide that + * number by 2 and rerun the test. + * + * - The second slowest is what type of IO API to perform. We have + * three choices: POSIXIO, MPI-IO, and PHDF5. + * + * - Then we change the size of the buffer. This information is + * inferred from the number of datasets to create and the number + * of integers to put into each dataset. The backend code figures + * this out. + * + * Return: Nothing + * Programmer: Bill Wendling, 30. October 2001 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +static void +run_test_loop(struct options *opts) +{ + parameters parms; + int num_procs; + int doing_pio; /* if this process is doing PIO */ + + parms.num_files = opts->num_files; + parms.num_dsets = opts->num_dsets; + parms.num_iters = opts->num_iters; + parms.blk_size = opts->blk_size; + parms.interleaved = opts->interleaved; + parms.collective = opts->collective; + parms.dim2d = opts->dim2d; + parms.h5_align = (hsize_t)opts->h5_alignment; + parms.h5_thresh = (hsize_t)opts->h5_threshold; + parms.h5_use_chunks = opts->h5_use_chunks; + parms.h5_write_only = opts->h5_write_only; + parms.verify = opts->verify; + + /* start with max_num_procs and decrement it by half for each loop. */ + /* if performance needs restart, fewer processes may be needed. */ + for (num_procs = opts->max_num_procs; num_procs >= opts->min_num_procs; num_procs >>= 1) { + register size_t buf_size; + + parms.num_procs = num_procs; + + if (create_comm_world(parms.num_procs, &doing_pio) != SUCCESS) { + /* do something harsh */ + } + + /* only processes doing PIO will run the tests */ + if (doing_pio) { + output_report("Number of processors = %ld\n", parms.num_procs); + + /* multiply the xfer buffer size by 2 for each loop iteration */ + for (buf_size = opts->min_xfer_size; buf_size <= opts->max_xfer_size; buf_size <<= 1) { + parms.buf_size = buf_size; + + if (parms.dim2d) { + parms.num_bytes = squareo(opts->num_bpp * parms.num_procs); + if (parms.interleaved) + output_report("Transfer Buffer Size: %ldx%ld bytes, File size: %.2f MB\n", buf_size, + opts->blk_size, + ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); + else + output_report("Transfer Buffer Size: %ldx%ld bytes, File size: %.2f MB\n", + opts->blk_size, buf_size, + ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); + + print_indent(1); + output_report(" # of files: %ld, # of datasets: %ld, dataset size: %.2fx%.2f KB\n", + parms.num_files, parms.num_dsets, + (double)(opts->num_bpp * parms.num_procs) / ONE_KB, + (double)(opts->num_bpp * parms.num_procs) / ONE_KB); + } + else { + parms.num_bytes = (off_t)opts->num_bpp * parms.num_procs; + output_report("Transfer Buffer Size: %ld bytes, File size: %.2f MB\n", buf_size, + ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); + + print_indent(1); + output_report(" # of files: %ld, # of datasets: %ld, dataset size: %.2f MB\n", + parms.num_files, parms.num_dsets, + (double)(opts->num_bpp * parms.num_procs) / ONE_MB); + } + + if (opts->io_types & PIO_POSIX) + run_test(POSIXIO, parms, opts); + + if (opts->io_types & PIO_MPI) + run_test(MPIO, parms, opts); + + if (opts->io_types & PIO_HDF5) + run_test(PHDF5, parms, opts); + + /* Run the tests once if buf_size==0, but then break out */ + if (buf_size == 0) + break; + } + + if (destroy_comm_world() != SUCCESS) { + /* do something harsh */ + } + } + } +} + +/* + * Function: run_test + * Purpose: Inner loop call to actually run the I/O test. + * Return: Nothing + * Programmer: Bill Wendling, 18. December 2001 + * Modifications: + */ +static int +run_test(iotype iot, parameters parms, struct options *opts) +{ + results res; + register int i, ret_value = SUCCESS; + int comm_size; + off_t raw_size; + minmax * write_mpi_mm_table = NULL; + minmax * write_mm_table = NULL; + minmax * write_gross_mm_table = NULL; + minmax * write_raw_mm_table = NULL; + minmax * read_mpi_mm_table = NULL; + minmax * read_mm_table = NULL; + minmax * read_gross_mm_table = NULL; + minmax * read_raw_mm_table = NULL; + minmax * read_open_mm_table = NULL; + minmax * read_close_mm_table = NULL; + minmax * write_open_mm_table = NULL; + minmax * write_close_mm_table = NULL; + minmax write_mpi_mm = {0.0, 0.0, 0.0, 0}; + minmax write_mm = {0.0, 0.0, 0.0, 0}; + minmax write_gross_mm = {0.0, 0.0, 0.0, 0}; + minmax write_raw_mm = {0.0, 0.0, 0.0, 0}; + minmax read_mpi_mm = {0.0, 0.0, 0.0, 0}; + minmax read_mm = {0.0, 0.0, 0.0, 0}; + minmax read_gross_mm = {0.0, 0.0, 0.0, 0}; + minmax read_raw_mm = {0.0, 0.0, 0.0, 0}; + minmax read_open_mm = {0.0, 0.0, 0.0, 0}; + minmax read_close_mm = {0.0, 0.0, 0.0, 0}; + minmax write_open_mm = {0.0, 0.0, 0.0, 0}; + minmax write_close_mm = {0.0, 0.0, 0.0, 0}; + + raw_size = parms.num_files * (off_t)parms.num_dsets * (off_t)parms.num_bytes; + parms.io_type = iot; + print_indent(2); + output_report("IO API = "); + + switch (iot) { + case POSIXIO: + output_report("POSIX\n"); + break; + case MPIO: + output_report("MPIO\n"); + break; + case PHDF5: + output_report("PHDF5 (w/MPI-IO driver)\n"); + break; + default: + break; + } + + MPI_Comm_size(pio_comm_g, &comm_size); + + /* allocate space for tables minmax and that it is sufficient */ + /* to initialize all elements to zeros by calloc. */ + write_mpi_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + write_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + write_gross_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + write_raw_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + write_open_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + write_close_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + if (!parms.h5_write_only) { + read_mpi_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + read_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + read_gross_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + read_raw_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + read_open_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + read_close_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); + } + + /* Do IO iteration times, collecting statistics each time */ + for (i = 0; i < parms.num_iters; ++i) { + double t; + + MPI_Barrier(pio_comm_g); + res = do_pio(parms); + + /* gather all of the "mpi write" times */ + t = io_time_get(res.timers, HDF5_MPI_WRITE); + get_minmax(&write_mpi_mm, t); + + write_mpi_mm_table[i] = write_mpi_mm; + + /* gather all of the "write" times */ + t = io_time_get(res.timers, HDF5_FINE_WRITE_FIXED_DIMS); + get_minmax(&write_mm, t); + + write_mm_table[i] = write_mm; + + /* gather all of the "write" times from open to close */ + t = io_time_get(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS); + get_minmax(&write_gross_mm, t); + + write_gross_mm_table[i] = write_gross_mm; + + /* gather all of the raw "write" times */ + t = io_time_get(res.timers, HDF5_RAW_WRITE_FIXED_DIMS); + get_minmax(&write_raw_mm, t); + + write_raw_mm_table[i] = write_raw_mm; + + /* gather all of the file open times (time from open to first write) */ + t = io_time_get(res.timers, HDF5_FILE_WRITE_OPEN); + get_minmax(&write_open_mm, t); + + write_open_mm_table[i] = write_open_mm; + + /* gather all of the file close times (time from last write to close) */ + t = io_time_get(res.timers, HDF5_FILE_WRITE_CLOSE); + get_minmax(&write_close_mm, t); + + write_close_mm_table[i] = write_close_mm; + + if (!parms.h5_write_only) { + /* gather all of the "mpi read" times */ + t = io_time_get(res.timers, HDF5_MPI_READ); + get_minmax(&read_mpi_mm, t); + + read_mpi_mm_table[i] = read_mpi_mm; + + /* gather all of the "read" times */ + t = io_time_get(res.timers, HDF5_FINE_READ_FIXED_DIMS); + get_minmax(&read_mm, t); + + read_mm_table[i] = read_mm; + + /* gather all of the "read" times from open to close */ + t = io_time_get(res.timers, HDF5_GROSS_READ_FIXED_DIMS); + get_minmax(&read_gross_mm, t); + + read_gross_mm_table[i] = read_gross_mm; + + /* gather all of the raw "read" times */ + t = io_time_get(res.timers, HDF5_RAW_READ_FIXED_DIMS); + get_minmax(&read_raw_mm, t); + + read_raw_mm_table[i] = read_raw_mm; + + /* gather all of the file open times (time from open to first read) */ + t = io_time_get(res.timers, HDF5_FILE_READ_OPEN); + get_minmax(&read_open_mm, t); + + read_open_mm_table[i] = read_open_mm; + + /* gather all of the file close times (time from last read to close) */ + t = io_time_get(res.timers, HDF5_FILE_READ_CLOSE); + get_minmax(&read_close_mm, t); + + read_close_mm_table[i] = read_close_mm; + } + + io_time_destroy(res.timers); + } + + /* + * Show various statistics + */ + /* Write statistics */ + /* Print the raw data throughput if desired */ + if (opts->print_raw) { + /* accumulate and output the max, min, and average "raw write" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Raw Data Write details:\n"); + output_all_info(write_raw_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Raw Data Write", write_raw_mm_table, parms.num_iters, raw_size); + } /* end if */ + + /* show mpi write statics */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("MPI Write details:\n"); + output_all_info(write_mpi_mm_table, parms.num_iters, 4); + } + + /* We don't currently output the MPI write results */ + + /* accumulate and output the max, min, and average "write" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write details:\n"); + output_all_info(write_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Write", write_mm_table, parms.num_iters, raw_size); + + /* accumulate and output the max, min, and average "gross write" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write Open-Close details:\n"); + output_all_info(write_gross_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Write Open-Close", write_gross_mm_table, parms.num_iters, raw_size); + + if (opts->print_times) { + output_times(opts, "Write File Open", write_open_mm_table, parms.num_iters); + output_times(opts, "Write File Close", write_close_mm_table, parms.num_iters); + } + + /* Print out time from open to first write */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write file open details:\n"); + output_all_info(write_open_mm_table, parms.num_iters, 4); + } + + /* Print out time from last write to close */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write file close details:\n"); + output_all_info(write_close_mm_table, parms.num_iters, 4); + } + + if (!parms.h5_write_only) { + /* Read statistics */ + /* Print the raw data throughput if desired */ + if (opts->print_raw) { + /* accumulate and output the max, min, and average "raw read" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Raw Data Read details:\n"); + output_all_info(read_raw_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Raw Data Read", read_raw_mm_table, parms.num_iters, raw_size); + } /* end if */ + + /* show mpi read statics */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("MPI Read details:\n"); + output_all_info(read_mpi_mm_table, parms.num_iters, 4); + } + + /* We don't currently output the MPI read results */ + + /* accumulate and output the max, min, and average "read" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read details:\n"); + output_all_info(read_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Read", read_mm_table, parms.num_iters, raw_size); + + /* accumulate and output the max, min, and average "gross read" times */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read Open-Close details:\n"); + output_all_info(read_gross_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Read Open-Close", read_gross_mm_table, parms.num_iters, raw_size); + + if (opts->print_times) { + output_times(opts, "Read File Open", read_open_mm_table, parms.num_iters); + output_times(opts, "Read File Close", read_close_mm_table, parms.num_iters); + } + + /* Print out time from open to first read */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read file open details:\n"); + output_all_info(read_open_mm_table, parms.num_iters, 4); + } + + /* Print out time from last read to close */ + if (pio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read file close details:\n"); + output_all_info(read_close_mm_table, parms.num_iters, 4); + } + } + + /* clean up our mess */ + free(write_mpi_mm_table); + free(write_mm_table); + free(write_gross_mm_table); + free(write_raw_mm_table); + free(write_open_mm_table); + free(write_close_mm_table); + + if (!parms.h5_write_only) { + free(read_mpi_mm_table); + free(read_mm_table); + free(read_gross_mm_table); + free(read_raw_mm_table); + free(read_open_mm_table); + free(read_close_mm_table); + } + + return ret_value; +} + +/* + * Function: output_all_info + * Purpose: + * Return: Nothing + * Programmer: Bill Wendling, 29. January 2002 + * Modifications: + */ +static void +output_all_info(minmax *mm, int count, int indent_level) +{ + int i; + + for (i = 0; i < count; ++i) { + print_indent(indent_level); + output_report("Iteration %d:\n", i + 1); + print_indent(indent_level + 1); + output_report("Minimum Time: %.2fs\n", mm[i].min); + print_indent(indent_level + 1); + output_report("Maximum Time: %.2fs\n", mm[i].max); + } +} + +/* + * Function: h5_set_info_object + * Purpose: Process environment variables setting to set up MPI Info + * object. + * Return: 0 if all is fine; otherwise non-zero. + * Programmer: Albert Cheng, 2002/05/21. + * Modifications: + * Bill Wendling, 2002/05/31 + * Modified so that the HDF5_MPI_INFO environment variable can + * be a semicolon separated list of "key=value" pairings. Most + * of the code is to remove any whitespaces which might be + * surrounding the "key=value" pairs. + */ +int +h5_set_info_object(void) +{ + char *envp; /* environment pointer */ + int ret_value = 0; + + /* handle any MPI INFO hints via $HDF5_MPI_INFO */ + if ((envp = HDgetenv("HDF5_MPI_INFO")) != NULL) { + char *next, *valp; + + valp = envp = next = HDstrdup(envp); + + if (!valp) + return 0; + + /* create an INFO object if not created yet */ + if (h5_io_info_g == MPI_INFO_NULL) + MPI_Info_create(&h5_io_info_g); + + do { + size_t len; + char * key_val, *endp, *namep; + + if (*valp == ';') + valp++; + + /* copy key/value pair into temporary buffer */ + len = strcspn(valp, ";"); + next = &valp[len]; + key_val = (char *)HDcalloc(1, len + 1); + + /* increment the next pointer past the terminating semicolon */ + if (*next == ';') + ++next; + + namep = HDstrncpy(key_val, valp, len); + + /* pass up any beginning whitespaces */ + while (*namep && (*namep == ' ' || *namep == '\t')) + namep++; + + if (!*namep) + continue; /* was all white space, so move to next k/v pair */ + + /* eat up any ending white spaces */ + endp = &namep[HDstrlen(namep) - 1]; + + while (endp && (*endp == ' ' || *endp == '\t')) + *endp-- = '\0'; + + /* find the '=' */ + valp = HDstrchr(namep, '='); + + if (valp != NULL) { /* it's a valid key/value pairing */ + char *tmp_val = valp + 1; + + /* change '=' to \0, move valp down one */ + *valp-- = '\0'; + + /* eat up ending whitespace on the "key" part */ + while (*valp == ' ' || *valp == '\t') + *valp-- = '\0'; + + valp = tmp_val; + + /* eat up beginning whitespace on the "value" part */ + while (*valp == ' ' || *valp == '\t') + *valp++ = '\0'; + + /* actually set the darned thing */ + if (MPI_SUCCESS != MPI_Info_set(h5_io_info_g, namep, valp)) { + HDprintf("MPI_Info_set failed\n"); + ret_value = -1; + } + } + + valp = next; + HDfree(key_val); + } while (next && *next); + + HDfree(envp); + } + + return ret_value; +} + +/* + * Function: h5_dump_info_object + * Purpose: Display content of an MPI Info object + * Return: void + * Programmer: Albert Cheng 2002/05/21 + * Modifications: + */ +void +h5_dump_info_object(MPI_Info info) +{ + char key[MPI_MAX_INFO_KEY + 1]; + char value[MPI_MAX_INFO_VAL + 1]; + int flag; + int i, nkeys; + + HDprintf("Dumping MPI Info Object (up to %d bytes per item):\n", MPI_MAX_INFO_VAL); + if (info == MPI_INFO_NULL) { + HDprintf("object is MPI_INFO_NULL\n"); + } + else { + MPI_Info_get_nkeys(info, &nkeys); + HDprintf("object has %d items\n", nkeys); + for (i = 0; i < nkeys; i++) { + MPI_Info_get_nthkey(info, i, key); + MPI_Info_get(info, key, MPI_MAX_INFO_VAL, value, &flag); + HDprintf("%s=%s\n", key, value); + } + } +} + +/* + * Function: get_minmax + * Purpose: Gather all the min, max and total of val. + * Return: Nothing + * Programmer: Bill Wendling, 21. December 2001 + * Modifications: + * Use MPI_Allreduce to do it. -akc, 2002/01/11 + */ +static void +get_minmax(minmax *mm, double val) +{ + int myrank; + + MPI_Comm_rank(pio_comm_g, &myrank); + MPI_Comm_size(pio_comm_g, &mm->num); + + MPI_Allreduce(&val, &mm->max, 1, MPI_DOUBLE, MPI_MAX, pio_comm_g); + MPI_Allreduce(&val, &mm->min, 1, MPI_DOUBLE, MPI_MIN, pio_comm_g); + MPI_Allreduce(&val, &mm->sum, 1, MPI_DOUBLE, MPI_SUM, pio_comm_g); +} + +/* + * Function: accumulate_minmax_stuff + * Purpose: Accumulate the minimum, maximum, and average of the times + * across all processes. + * Return: TOTAL_MM - the total of all of these. + * Programmer: Bill Wendling, 21. December 2001 + * Modifications: + * Changed to use seconds instead of MB/s - QAK, 5/9/02 + */ +static minmax +accumulate_minmax_stuff(minmax *mm, int count) +{ + int i; + minmax total_mm; + + total_mm.sum = 0.0f; + total_mm.max = -DBL_MAX; + total_mm.min = DBL_MAX; + total_mm.num = count; + + for (i = 0; i < count; ++i) { + double m = mm[i].max; + + total_mm.sum += m; + + if (m < total_mm.min) + total_mm.min = m; + + if (m > total_mm.max) + total_mm.max = m; + } + + return total_mm; +} + +/* + * Function: create_comm_world + * Purpose: Create an MPI Comm world and store it in pio_comm_g, which + * is a global variable. + * Return: SUCCESS on success. + * FAIL otherwise. + * Programmer: Bill Wendling, 19. December 2001 + * Modifications: + */ +static int +create_comm_world(int num_procs, int *doing_pio) +{ + /* MPI variables */ + int mrc; /* return values */ + int color; /* for communicator creation */ + int myrank, nprocs; + + pio_comm_g = MPI_COMM_NULL; + + /* + * Create a sub communicator for this PIO run. Easier to use the first N + * processes. + */ + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + + if (num_procs > nprocs) { + HDfprintf(stderr, "number of process(%d) must be <= number of processes in MPI_COMM_WORLD(%d)\n", + num_procs, nprocs); + goto error_done; + } + + MPI_Comm_rank(MPI_COMM_WORLD, &myrank); + color = (myrank < num_procs); + mrc = MPI_Comm_split(MPI_COMM_WORLD, color, myrank, &pio_comm_g); + + if (mrc != MPI_SUCCESS) { + HDfprintf(stderr, "MPI_Comm_split failed\n"); + goto error_done; + } + + if (!color) { + /* not involved in this run */ + mrc = destroy_comm_world(); + goto done; + } + + /* determine the MPI rank in the PIO communicator */ + MPI_Comm_size(pio_comm_g, &pio_mpi_nprocs_g); + MPI_Comm_rank(pio_comm_g, &pio_mpi_rank_g); + +done: + *doing_pio = color; + return SUCCESS; + +error_done: + destroy_comm_world(); + return FAIL; +} + +/* + * Function: destroy_comm_world + * Purpose: Destroy the created MPI Comm world which is stored in the + * pio_comm_g global variable. + * Return: SUCCESS on success. + * FAIL otherwise. + * Programmer: Bill Wendling, 19. December 2001 + * Modifications: + */ +static int +destroy_comm_world(void) +{ + int mrc = SUCCESS; /* return code */ + + /* release MPI resources */ + if (pio_comm_g != MPI_COMM_NULL) + mrc = (MPI_Comm_free(&pio_comm_g) == MPI_SUCCESS ? SUCCESS : FAIL); + + return mrc; +} + +/* + * Function: output_results + * Purpose: Print information about the time & bandwidth for a given + * minmax & # of iterations. + * Return: Nothing + * Programmer: Quincey Koziol, 9. May 2002 + * Modifications: + */ +static void +output_results(const struct options *opts, const char *name, minmax *table, int table_size, off_t data_size) +{ + minmax total_mm; + + total_mm = accumulate_minmax_stuff(table, table_size); + + print_indent(3); + output_report("%s (%d iteration(s)):\n", name, table_size); + + /* Note: The maximum throughput uses the minimum amount of time & vice versa */ + + print_indent(4); + output_report("Maximum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.min)); + if (opts->print_times) + output_report(" (%7.3f s)\n", total_mm.min); + else + output_report("\n"); + + print_indent(4); + output_report("Average Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.sum / total_mm.num)); + if (opts->print_times) + output_report(" (%7.3f s)\n", (total_mm.sum / total_mm.num)); + else + output_report("\n"); + + print_indent(4); + output_report("Minimum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.max)); + if (opts->print_times) + output_report(" (%7.3f s)\n", total_mm.max); + else + output_report("\n"); +} + +static void +output_times(const struct options *opts, const char *name, minmax *table, int table_size) +{ + minmax total_mm; + + total_mm = accumulate_minmax_stuff(table, table_size); + + print_indent(3); + output_report("%s (%d iteration(s)):\n", name, table_size); + + /* Note: The maximum throughput uses the minimum amount of time & vice versa */ + + print_indent(4); + output_report("Minimum Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, (total_mm.min)); + + print_indent(4); + output_report("Average Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, + (total_mm.sum / total_mm.num)); + + print_indent(4); + output_report("Maximum Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, (total_mm.max)); +} + +/* + * Function: output_report + * Purpose: Print a line of the report. Only do so if I'm the 0 process. + * Return: Nothing + * Programmer: Bill Wendling, 19. December 2001 + * Modifications: + */ +static void +output_report(const char *fmt, ...) +{ + int myrank; + + MPI_Comm_rank(pio_comm_g, &myrank); + + if (myrank == 0) { + va_list ap; + + HDva_start(ap, fmt); + HDvfprintf(output, fmt, ap); + HDva_end(ap); + } +} + +/* + * Function: print_indent + * Purpose: Print spaces to indent a new line of text for pretty printing + * things. + * Return: Nothing + * Programmer: Bill Wendling, 29. October 2001 + * Modifications: + */ +static void +print_indent(register int indent) +{ + int myrank; + + MPI_Comm_rank(pio_comm_g, &myrank); + + if (myrank == 0) { + indent *= TAB_SPACE; + + for (; indent > 0; --indent) + HDfputc(' ', output); + } +} + +static void +recover_size_and_print(long long val, const char *end) +{ + if (val >= ONE_KB && (val % ONE_KB) == 0) { + if (val >= ONE_MB && (val % ONE_MB) == 0) { + if (val >= ONE_GB && (val % ONE_GB) == 0) + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "GB%s", + val / ONE_GB, end); + else + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "MB%s", + val / ONE_MB, end); + } + else { + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "KB%s", + val / ONE_KB, end); + } + } + else { + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "%s", + val, end); + } +} + +static void +print_io_api(long io_types) +{ + if (io_types & PIO_POSIX) + HDfprintf(output, "posix "); + if (io_types & PIO_MPI) + HDfprintf(output, "mpiio "); + if (io_types & PIO_HDF5) + HDfprintf(output, "phdf5 "); + HDfprintf(output, "\n"); +} + +static void +report_parameters(struct options *opts) +{ + int rank = comm_world_rank_g; + + print_version("HDF5 Library"); /* print library version */ + HDfprintf(output, "rank %d: ==== Parameters ====\n", rank); + + HDfprintf(output, "rank %d: IO API=", rank); + print_io_api(opts->io_types); + + HDfprintf(output, "rank %d: Number of files=%ld\n", rank, opts->num_files); + HDfprintf(output, "rank %d: Number of datasets=%ld\n", rank, opts->num_dsets); + HDfprintf(output, "rank %d: Number of iterations=%d\n", rank, opts->num_iters); + HDfprintf(output, "rank %d: Number of processes=%d:%d\n", rank, opts->min_num_procs, opts->max_num_procs); + + if (opts->dim2d) { + HDfprintf(output, "rank %d: Number of bytes per process per dataset=", rank); + recover_size_and_print((long long)(opts->num_bpp * opts->num_bpp * opts->min_num_procs), ":"); + recover_size_and_print((long long)(opts->num_bpp * opts->num_bpp * opts->max_num_procs), "\n"); + + HDfprintf(output, "rank %d: Size of dataset(s)=", rank); + recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), "x"); + recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), ":"); + recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "x"); + recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "\n"); + + HDfprintf(output, "rank %d: File size=", rank); + recover_size_and_print((long long)(squareo(opts->num_bpp * opts->min_num_procs) * opts->num_dsets), + ":"); + recover_size_and_print((long long)(squareo(opts->num_bpp * opts->max_num_procs) * opts->num_dsets), + "\n"); + + HDfprintf(output, "rank %d: Transfer buffer size=", rank); + if (opts->interleaved) { + recover_size_and_print((long long)opts->min_xfer_size, "x"); + recover_size_and_print((long long)opts->blk_size, ":"); + recover_size_and_print((long long)opts->max_xfer_size, "x"); + recover_size_and_print((long long)opts->blk_size, "\n"); + } + else { + recover_size_and_print((long long)opts->blk_size, "x"); + recover_size_and_print((long long)opts->min_xfer_size, ":"); + recover_size_and_print((long long)opts->blk_size, "x"); + recover_size_and_print((long long)opts->max_xfer_size, "\n"); + } + HDfprintf(output, "rank %d: Block size=", rank); + recover_size_and_print((long long)opts->blk_size, "x"); + recover_size_and_print((long long)opts->blk_size, "\n"); + } + else { + HDfprintf(output, "rank %d: Number of bytes per process per dataset=", rank); + recover_size_and_print((long long)opts->num_bpp, "\n"); + + HDfprintf(output, "rank %d: Size of dataset(s)=", rank); + recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), ":"); + recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "\n"); + + HDfprintf(output, "rank %d: File size=", rank); + recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs * opts->num_dsets), ":"); + recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs * opts->num_dsets), "\n"); + + HDfprintf(output, "rank %d: Transfer buffer size=", rank); + recover_size_and_print((long long)opts->min_xfer_size, ":"); + recover_size_and_print((long long)opts->max_xfer_size, "\n"); + HDfprintf(output, "rank %d: Block size=", rank); + recover_size_and_print((long long)opts->blk_size, "\n"); + } + + HDfprintf(output, "rank %d: Block Pattern in Dataset=", rank); + if (opts->interleaved) + HDfprintf(output, "Interleaved\n"); + else + HDfprintf(output, "Contiguous\n"); + + HDfprintf(output, "rank %d: I/O Method for MPI and HDF5=", rank); + if (opts->collective) + HDfprintf(output, "Collective\n"); + else + HDfprintf(output, "Independent\n"); + + HDfprintf(output, "rank %d: Geometry=", rank); + if (opts->dim2d) + HDfprintf(output, "2D\n"); + else + HDfprintf(output, "1D\n"); + + HDfprintf(output, "rank %d: VFL used for HDF5 I/O=%s\n", rank, "MPI-IO driver"); + + HDfprintf(output, "rank %d: Data storage method in HDF5=", rank); + if (opts->h5_use_chunks) + HDfprintf(output, "Chunked\n"); + else + HDfprintf(output, "Contiguous\n"); + + { + char *prefix = HDgetenv("HDF5_PARAPREFIX"); + + HDfprintf(output, "rank %d: Env HDF5_PARAPREFIX=%s\n", rank, (prefix ? prefix : "not set")); + } + + HDfprintf(output, "rank %d: ", rank); + h5_dump_info_object(h5_io_info_g); + + HDfprintf(output, "rank %d: ==== End of Parameters ====\n", rank); + HDfprintf(output, "\n"); +} + +/* + * Function: parse_command_line + * Purpose: Parse the command line options and return a STRUCT OPTIONS + * structure which will need to be freed by the calling function. + * Return: Pointer to an OPTIONS structure + * Programmer: Bill Wendling, 31. October 2001 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +static struct options * +parse_command_line(int argc, char *argv[]) +{ + register int opt; + struct options *cl_opts; + + cl_opts = (struct options *)malloc(sizeof(struct options)); + + cl_opts->output_file = NULL; + cl_opts->io_types = 0; /* will set default after parsing options */ + cl_opts->num_dsets = 1; + cl_opts->num_files = 1; + cl_opts->num_bpp = 0; + cl_opts->num_iters = 1; + cl_opts->max_num_procs = comm_world_nprocs_g; + cl_opts->min_num_procs = 1; + cl_opts->max_xfer_size = 0; + cl_opts->min_xfer_size = 0; + cl_opts->blk_size = 0; + cl_opts->interleaved = 0; /* Default to contiguous blocks in dataset */ + cl_opts->collective = 0; /* Default to independent I/O access */ + cl_opts->dim2d = 0; /* Default to 1D */ + cl_opts->print_times = FALSE; /* Printing times is off by default */ + cl_opts->print_raw = FALSE; /* Printing raw data throughput is off by default */ + cl_opts->h5_alignment = 1; /* No alignment for HDF5 objects by default */ + cl_opts->h5_threshold = 1; /* No threshold for aligning HDF5 objects by default */ + cl_opts->h5_use_chunks = FALSE; /* Don't chunk the HDF5 dataset by default */ + cl_opts->h5_write_only = FALSE; /* Do both read and write by default */ + cl_opts->verify = FALSE; /* No Verify data correctness by default */ + + while ((opt = H5_get_option(argc, (const char **)argv, s_opts, l_opts)) != EOF) { + switch ((char)opt) { + case 'a': + cl_opts->h5_alignment = parse_size_directive(H5_optarg); + break; + case 'A': { + const char *end = H5_optarg; + + while (end && *end != '\0') { + char buf[10]; + int i; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (isalnum(*end) && i < 10) + buf[i++] = *end; + + if (!HDstrcasecmp(buf, "phdf5")) { + cl_opts->io_types |= PIO_HDF5; + } + else if (!HDstrcasecmp(buf, "mpiio")) { + cl_opts->io_types |= PIO_MPI; + } + else if (!HDstrcasecmp(buf, "posix")) { + cl_opts->io_types |= PIO_POSIX; + } + else { + HDfprintf(stderr, "pio_perf: invalid --api option %s\n", buf); + HDexit(EXIT_FAILURE); + } + + if (*end == '\0') + break; + + end++; + } + } + + break; +#if 0 + case 'b': + /* the future "binary" option */ + break; +#endif /* 0 */ + case 'B': + cl_opts->blk_size = (size_t)parse_size_directive(H5_optarg); + break; + case 'c': + /* Turn on chunked HDF5 dataset creation */ + cl_opts->h5_use_chunks = TRUE; + break; + case 'C': + cl_opts->collective = 1; + break; + case 'd': + cl_opts->num_dsets = atoi(H5_optarg); + break; + case 'D': { + const char *end = H5_optarg; + + while (end && *end != '\0') { + char buf[10]; + int i; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + if (HDstrlen(buf) > 1 || HDisdigit(buf[0])) { + size_t j; + + for (j = 0; j < 10 && buf[j] != '\0'; ++j) + if (!isdigit(buf[j])) { + HDfprintf(stderr, "pio_perf: invalid --debug option %s\n", buf); + HDexit(EXIT_FAILURE); + } + + pio_debug_level = atoi(buf); + + if (pio_debug_level > 4) + pio_debug_level = 4; + else if (pio_debug_level < 0) + pio_debug_level = 0; + } + else { + switch (*buf) { + case 'r': + /* Turn on raw data throughput info */ + cl_opts->print_raw = TRUE; + break; + case 't': + /* Turn on time printing */ + cl_opts->print_times = TRUE; + break; + case 'v': + /* Turn on verify data correctness*/ + cl_opts->verify = TRUE; + break; + default: + HDfprintf(stderr, "pio_perf: invalid --debug option %s\n", buf); + HDexit(EXIT_FAILURE); + } + } + + if (*end == '\0') + break; + + end++; + } + } + + break; + case 'e': + cl_opts->num_bpp = parse_size_directive(H5_optarg); + break; + case 'F': + cl_opts->num_files = HDatoi(H5_optarg); + break; + case 'g': + cl_opts->dim2d = 1; + break; + case 'i': + cl_opts->num_iters = HDatoi(H5_optarg); + break; + case 'I': + cl_opts->interleaved = 1; + break; + case 'o': + cl_opts->output_file = H5_optarg; + break; + case 'p': + cl_opts->min_num_procs = HDatoi(H5_optarg); + break; + case 'P': + cl_opts->max_num_procs = HDatoi(H5_optarg); + break; + case 'T': + cl_opts->h5_threshold = parse_size_directive(H5_optarg); + break; + case 'w': + cl_opts->h5_write_only = TRUE; + break; + case 'x': + cl_opts->min_xfer_size = (size_t)parse_size_directive(H5_optarg); + break; + case 'X': + cl_opts->max_xfer_size = (size_t)parse_size_directive(H5_optarg); + break; + case 'h': + case '?': + default: + usage(progname); + HDfree(cl_opts); + return NULL; + } + } + + if (cl_opts->num_bpp == 0) { + if (cl_opts->dim2d == 0) + cl_opts->num_bpp = 256 * ONE_KB; + else + cl_opts->num_bpp = 8 * ONE_KB; + } + + if (cl_opts->max_xfer_size == 0) + cl_opts->max_xfer_size = (size_t)cl_opts->num_bpp; + + if (cl_opts->min_xfer_size == 0) + cl_opts->min_xfer_size = (size_t)(cl_opts->num_bpp) / 2; + + if (cl_opts->blk_size == 0) + cl_opts->blk_size = (size_t)(cl_opts->num_bpp) / 2; + + /* set default if none specified yet */ + if (!cl_opts->io_types) + cl_opts->io_types = PIO_HDF5 | PIO_MPI | PIO_POSIX; /* run all API */ + + /* verify parameters sanity. Adjust if needed. */ + /* cap xfer_size with bytes per process */ + if (!cl_opts->dim2d) { + if (cl_opts->min_xfer_size > (size_t)cl_opts->num_bpp) + cl_opts->min_xfer_size = (size_t)cl_opts->num_bpp; + if (cl_opts->max_xfer_size > (size_t)cl_opts->num_bpp) + cl_opts->max_xfer_size = (size_t)cl_opts->num_bpp; + } + if (cl_opts->min_xfer_size > cl_opts->max_xfer_size) + cl_opts->min_xfer_size = cl_opts->max_xfer_size; + if (cl_opts->blk_size > (size_t)cl_opts->num_bpp) + cl_opts->blk_size = (size_t)cl_opts->num_bpp; + /* check range of number of processes */ + if (cl_opts->min_num_procs <= 0) + cl_opts->min_num_procs = 1; + if (cl_opts->max_num_procs <= 0) + cl_opts->max_num_procs = 1; + if (cl_opts->min_num_procs > cl_opts->max_num_procs) + cl_opts->min_num_procs = cl_opts->max_num_procs; + /* check iteration */ + if (cl_opts->num_iters <= 0) + cl_opts->num_iters = 1; + + return cl_opts; +} + +/* + * Function: parse_size_directive + * Purpose: Parse the size directive passed on the commandline. The size + * directive is an integer followed by a size indicator: + * + * K, k - Kilobyte + * M, m - Megabyte + * G, g - Gigabyte + * + * Return: The size as a off_t because this is related to file size. + * If an unknown size indicator is used, then the program will + * exit with EXIT_FAILURE as the return value. + * Programmer: Bill Wendling, 18. December 2001 + * Modifications: + */ +static off_t +parse_size_directive(const char *size) +{ + off_t s; + char *endptr; + + s = HDstrtol(size, &endptr, 10); + + if (endptr && *endptr) { + while (*endptr != '\0' && (*endptr == ' ' || *endptr == '\t')) + ++endptr; + + switch (*endptr) { + case 'K': + case 'k': + s *= ONE_KB; + break; + case 'M': + case 'm': + s *= ONE_MB; + break; + case 'G': + case 'g': + s *= ONE_GB; + break; + default: + HDfprintf(stderr, "Illegal size specifier '%c'\n", *endptr); + HDexit(EXIT_FAILURE); + } + } + + return s; +} + +/* + * Function: usage + * Purpose: Print a usage message and then exit. + * Return: Nothing + * Programmer: Bill Wendling, 31. October 2001 + * Modifications: + * Added 2D testing (Christian Chilan, 10. August 2005) + */ +static void +usage(const char *prog) +{ + int myrank; + + MPI_Comm_rank(pio_comm_g, &myrank); + + if (myrank == 0) { + print_version(prog); + HDprintf("usage: %s [OPTIONS]\n", prog); + HDprintf(" OPTIONS\n"); + HDprintf(" -h, --help Print a usage message and exit\n"); + HDprintf(" -a S, --align=S Alignment of objects in HDF5 file [default: 1]\n"); + HDprintf(" -A AL, --api=AL Which APIs to test [default: all of them]\n"); +#if 0 + HDprintf(" -b, --binary The elusive binary option\n"); +#endif /* 0 */ + HDprintf(" -B S, --block-size=S Block size within transfer buffer\n"); + HDprintf(" (see below for description)\n"); + HDprintf(" [default: half the number of bytes per process\n"); + HDprintf(" per dataset]\n"); + HDprintf(" -c, --chunk Create HDF5 datasets using chunked storage\n"); + HDprintf(" [default: contiguous storage]\n"); + HDprintf(" -C, --collective Use collective I/O for MPI and HDF5 APIs\n"); + HDprintf(" [default: independent I/O)\n"); + HDprintf(" -d N, --num-dsets=N Number of datasets per file [default: 1]\n"); + HDprintf(" -D DL, --debug=DL Indicate the debugging level\n"); + HDprintf(" [default: no debugging]\n"); + HDprintf(" -e S, --num-bytes=S Number of bytes per process per dataset\n"); + HDprintf(" (see below for description)\n"); + HDprintf(" [default: 256K for 1D, 8K for 2D]\n"); + HDprintf(" -F N, --num-files=N Number of files [default: 1]\n"); + HDprintf(" -g, --geometry Use 2D geometry [default: 1D geometry]\n"); + HDprintf(" -i N, --num-iterations=N Number of iterations to perform [default: 1]\n"); + HDprintf(" -I, --interleaved Interleaved access pattern\n"); + HDprintf(" (see below for example)\n"); + HDprintf(" [default: Contiguous access pattern]\n"); + HDprintf(" -o F, --output=F Output raw data into file F [default: none]\n"); + HDprintf(" -p N, --min-num-processes=N Minimum number of processes to use [default: 1]\n"); + HDprintf(" -P N, --max-num-processes=N Maximum number of processes to use\n"); + HDprintf(" [default: all MPI_COMM_WORLD processes ]\n"); + HDprintf(" -T S, --threshold=S Threshold for alignment of objects in HDF5 file\n"); + HDprintf(" [default: 1]\n"); + HDprintf(" -w, --write-only Perform write tests not the read tests\n"); + HDprintf(" -x S, --min-xfer-size=S Minimum transfer buffer size\n"); + HDprintf(" (see below for description)\n"); + HDprintf(" [default: half the number of bytes per process\n"); + HDprintf(" per dataset]\n"); + HDprintf(" -X S, --max-xfer-size=S Maximum transfer buffer size\n"); + HDprintf(" [default: the number of bytes per process per\n"); + HDprintf(" dataset]\n"); + HDprintf("\n"); + HDprintf(" F - is a filename.\n"); + HDprintf(" N - is an integer >=0.\n"); + HDprintf(" S - is a size specifier, an integer >=0 followed by a size indicator:\n"); + HDprintf(" K - Kilobyte (%d)\n", ONE_KB); + HDprintf(" M - Megabyte (%d)\n", ONE_MB); + HDprintf(" G - Gigabyte (%d)\n", ONE_GB); + HDprintf("\n"); + HDprintf(" Example: '37M' is 37 megabytes or %d bytes\n", 37 * ONE_MB); + HDprintf("\n"); + HDprintf(" AL - is an API list. Valid values are:\n"); + HDprintf(" phdf5 - Parallel HDF5\n"); + HDprintf(" mpiio - MPI-I/O\n"); + HDprintf(" posix - POSIX\n"); + HDprintf("\n"); + HDprintf(" Example: --api=mpiio,phdf5\n"); + HDprintf("\n"); + HDprintf(" Dataset size:\n"); + HDprintf(" Depending on the selected geometry, each test dataset is either a linear\n"); + HDprintf(" array of size bytes-per-process * num-processes, or a square array of size\n"); + HDprintf(" (bytes-per-process * num-processes) x (bytes-per-process * num-processes).\n"); + HDprintf("\n"); + HDprintf(" Block size vs. Transfer buffer size:\n"); + HDprintf(" buffer-size controls the size of the memory buffer, which is broken into\n"); + HDprintf(" blocks and written to the file. Depending on the selected geometry, each\n"); + HDprintf(" block can be a linear array of size block-size or a square array of size\n"); + HDprintf(" block-size x block-size. The arrangement in which blocks are written is\n"); + HDprintf(" determined by the access pattern.\n"); + HDprintf("\n"); + HDprintf(" In 1D geometry, the transfer buffer is a linear array of size buffer-size.\n"); + HDprintf(" In 2D geometry, it is a rectangular array of size block-size x buffer-size\n"); + HDprintf(" or buffer-size x block-size if interleaved pattern is selected.\n"); + HDprintf("\n"); + HDprintf(" Interleaved and Contiguous patterns in 1D geometry:\n"); + HDprintf(" When contiguous access pattern is chosen, the dataset is evenly divided\n"); + HDprintf(" into num-processes regions and each process writes data to its own region.\n"); + HDprintf(" When interleaved blocks are written to a dataset, space for the first\n"); + HDprintf(" block of the first process is allocated in the dataset, then space is\n"); + HDprintf(" allocated for the first block of the second process, etc. until space is\n"); + HDprintf(" allocated for the first block of each process, then space is allocated for\n"); + HDprintf(" the second block of the first process, the second block of the second\n"); + HDprintf(" process, etc.\n"); + HDprintf("\n"); + HDprintf(" For example, with a 3 process run, 512KB bytes-per-process, 256KB transfer\n"); + HDprintf(" buffer size, and 64KB block size, each process must issue 2 transfer\n"); + HDprintf(" requests to complete access to the dataset.\n"); + HDprintf(" Contiguous blocks of the first transfer request are written like so:\n"); + HDprintf(" 1111----2222----3333----\n"); + HDprintf(" Interleaved blocks of the first transfer request are written like so:\n"); + HDprintf(" 123123123123------------\n"); + HDprintf(" The actual number of I/O operations involved in a transfer request\n"); + HDprintf(" depends on the access pattern and communication mode.\n"); + HDprintf(" When using independent I/O with interleaved pattern, each process\n"); + HDprintf(" performs 4 small non-contiguous I/O operations per transfer request.\n"); + HDprintf(" If collective I/O is turned on, the combined content of the buffers of\n"); + HDprintf(" the 3 processes will be written using one collective I/O operation\n"); + HDprintf(" per transfer request.\n"); + HDprintf("\n"); + HDprintf(" For information about access patterns in 2D geometry, please refer to the\n"); + HDprintf(" HDF5 Reference Manual.\n"); + HDprintf("\n"); + HDprintf(" DL - is a list of debugging flags. Valid values are:\n"); + HDprintf(" 1 - Minimal\n"); + HDprintf(" 2 - Not quite everything\n"); + HDprintf(" 3 - Everything\n"); + HDprintf(" 4 - The kitchen sink\n"); + HDprintf(" r - Raw data I/O throughput information\n"); + HDprintf(" t - Times as well as throughputs\n"); + HDprintf(" v - Verify data correctness\n"); + HDprintf("\n"); + HDprintf(" Example: --debug=2,r,t\n"); + HDprintf("\n"); + HDprintf(" Environment variables:\n"); + HDprintf(" HDF5_NOCLEANUP Do not remove data files if set [default remove]\n"); + HDprintf(" HDF5_MPI_INFO MPI INFO object key=value separated by ;\n"); + HDprintf(" HDF5_PARAPREFIX Paralllel data files prefix\n"); + fflush(stdout); + } /* end if */ +} /* end usage() */ + +#else /* H5_HAVE_PARALLEL */ + +/* + * Function: main + * Purpose: Dummy main() function for if HDF5 was configured without + * parallel stuff. + * Return: EXIT_SUCCESS + * Programmer: Bill Wendling, 14. November 2001 + */ +int +main(void) +{ + HDprintf("No parallel IO performance because parallel is not configured\n"); + return EXIT_SUCCESS; +} /* end main */ + +#endif /* !H5_HAVE_PARALLEL */ diff --git a/tools/src/h5perf/pio_perf.h b/tools/src/h5perf/pio_perf.h new file mode 100644 index 0000000..8924c20 --- /dev/null +++ b/tools/src/h5perf/pio_perf.h @@ -0,0 +1,109 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef PIO_PERF_H +#define PIO_PERF_H + +#ifndef STANDALONE +#include "io_timer.h" +#include "H5private.h" +#include "h5tools.h" +#include "h5tools_utils.h" +#else +#include "io_timer.h" +#include "pio_standalone.h" +#endif + +#ifdef H5_HAVE_PARALLEL +extern MPI_Info h5_io_info_g; /* MPI INFO object for IO */ +#endif + +#ifdef H5_HAVE_PARALLEL +int h5_set_info_object(void); +void h5_dump_info_object(MPI_Info info); +#endif + +/* setup the dataset no fill option if this is v1.5 or more */ +#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR > 4 +#define H5_HAVE_NOFILL 1 +#endif + +typedef enum iotype_ { + POSIXIO, + MPIO, + PHDF5 + /*NUM_TYPES*/ +} iotype; + +typedef struct parameters_ { + iotype io_type; /* The type of IO test to perform */ + int num_procs; /* Maximum number of processes to use */ + long num_files; /* Number of files to create */ + long num_dsets; /* Number of datasets to create */ + off_t num_bytes; /* Number of bytes in each dset */ + int num_iters; /* Number of times to loop doing the IO */ + size_t buf_size; /* Buffer size */ + size_t blk_size; /* Block size */ + unsigned interleaved; /* Interleaved vs. contiguous blocks */ + unsigned collective; /* Collective vs. independent I/O */ + unsigned dim2d; /* 1D vs. 2D */ + hsize_t h5_align; /* HDF5 object alignment */ + hsize_t h5_thresh; /* HDF5 object alignment threshold */ + int h5_use_chunks; /* Make HDF5 dataset chunked */ + int h5_write_only; /* Perform the write tests only */ + int verify; /* Verify data correctness */ +} parameters; + +typedef struct results_ { + herr_t ret_code; + io_time_t *timers; +} results; + +#ifndef SUCCESS +#define SUCCESS 0 +#endif /* !SUCCESS */ + +#ifndef FAIL +#define FAIL -1 +#endif /* !FAIL */ + +extern FILE * output; /* output file */ +extern io_time_t *timer_g; /* timer: global for stub functions */ +extern int comm_world_rank_g; /* my rank in MPI_COMM_RANK */ +extern int comm_world_nprocs_g; /* num. of processes of MPI_COMM_WORLD */ +extern MPI_Comm pio_comm_g; /* Communicator to run the PIO */ +extern int pio_mpi_rank_g; /* MPI rank of pio_comm_g */ +extern int pio_mpi_nprocs_g; /* number of processes of pio_comm_g */ +extern int pio_debug_level; /* The debug level: + * 0 - Off + * 1 - Minimal + * 2 - Some more + * 3 - Maximal + * 4 - Even More Debugging (timer stuff) + */ + +#define HDprint_rank(f) /* print rank in MPI_COMM_WORLD */ HDfprintf(f, "%d: ", comm_world_rank_g); +#define HDprint_size(f) /* print size of MPI_COMM_WORLD */ HDfprintf(f, "%d", comm_world_nprocs_g); +#define HDprint_rank_size(f) /* print rank/size of MPI_COMM_WORLD */ \ + HDfprintf(f, "%d/%d: ", comm_world_rank_g, comm_world_nprocs_g); + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern results do_pio(parameters param); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PIO_PERF_H */ diff --git a/tools/src/h5perf/sio_engine.c b/tools/src/h5perf/sio_engine.c new file mode 100644 index 0000000..e69a7cd --- /dev/null +++ b/tools/src/h5perf/sio_engine.c @@ -0,0 +1,1328 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Author: Christian Chilan, April 2008 + */ + +#include "hdf5.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef H5_HAVE_UNISTD_H +#include <sys/types.h> +#include <unistd.h> +#endif + +#ifdef H5_HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif + +#include "sio_perf.h" + +/* Macro definitions */ + +/* sizes of various items. these sizes won't change during program execution */ +#define ELMT_H5_TYPE H5T_NATIVE_UCHAR + +#define GOTOERROR(errcode) \ + { \ + ret_code = errcode; \ + goto done; \ + } +#define ERRMSG(mesg) \ + { \ + HDfprintf(stderr, "*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ + } + +/* verify: if val is false (0), print mesg. */ +#define VRFY(val, mesg) \ + do { \ + if (!(val)) { \ + ERRMSG(mesg); \ + GOTOERROR(FAIL); \ + } \ + } while (0) + +/* POSIX I/O macros */ +#ifdef H5_HAVE_WIN32_API +/* Can't link against the library, so this test will use the older, non-Unicode + * _open() call on Windows. + */ +#define HDopen(S, F, ...) _open(S, F | _O_BINARY, __VA_ARGS__) +#endif /* H5_HAVE_WIN32_API */ +#define POSIXCREATE(fn) HDopen(fn, O_CREAT | O_TRUNC | O_RDWR, 0600) +#define POSIXOPEN(fn, F) HDopen(fn, F, 0600) +#define POSIXCLOSE(F) HDclose(F) +#define POSIXSEEK(F, L) HDlseek(F, L, SEEK_SET) +#define POSIXWRITE(F, B, S) HDwrite(F, B, S) +#define POSIXREAD(F, B, S) HDread(F, B, S) + +enum { SIO_CREATE = 1, SIO_WRITE = 2, SIO_READ = 4 }; + +/* Global variables */ +static int clean_file_g = -1; /*whether to cleanup temporary test */ +/*files. -1 is not defined; */ +/*0 is no cleanup; 1 is do cleanup */ + +/* the different types of file descriptors we can expect */ +typedef union { + int posixfd; /* POSIX file handle*/ + hid_t h5fd; /* HDF5 file */ +} file_descr; + +/* local functions */ +static char * sio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size, + parameters *param); +static herr_t do_write(results *res, file_descr *fd, parameters *parms, void *buffer); +static herr_t do_read(results *res, file_descr *fd, parameters *parms, void *buffer); +static herr_t dset_write(int local_dim, file_descr *fd, parameters *parms, void *buffer); +static herr_t posix_buffer_write(int local_dim, file_descr *fd, parameters *parms, void *buffer); +static herr_t dset_read(int localrank, file_descr *fd, parameters *parms, void *buffer, const char *buffer2); +static herr_t posix_buffer_read(int local_dim, file_descr *fd, parameters *parms, void *buffer); +static herr_t do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags); +hid_t set_vfd(parameters *param); +static herr_t do_fclose(iotype iot, file_descr *fd); +static void do_cleanupfile(iotype iot, char *fname); + +/* global variables */ +static HDoff_t offset[MAX_DIMS]; /* dataset size in bytes */ +static size_t buf_offset[MAX_DIMS]; /* dataset size in bytes */ +static int order[MAX_DIMS]; /* dimension access order */ +static size_t linear_buf_size; /* linear buffer size */ +static int cont_dim; /* lowest dimension for contiguous POSIX + access */ +static size_t cont_size; /* size of contiguous POSIX access */ +static hid_t fapl; /* file access list */ +static unsigned char *buf_p; /* buffer pointer */ +static const char * multi_letters = "msbrglo"; /* string for multi driver */ + +/* HDF5 global variables */ +static hsize_t h5count[MAX_DIMS]; /*selection count */ +static hssize_t h5offset[MAX_DIMS]; /* Selection offset within dataspace */ +static hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ +static hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ +static hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ +static hid_t h5dcpl = H5I_INVALID_HID; /* Dataset creation property list */ +static hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ + +/* + * Function: do_sio + * Purpose: SIO Engine where IO are executed. + * Return: results + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ +void +do_sio(parameters param, results *res) +{ + char * buffer = NULL; /*data buffer pointer */ + size_t buf_size[MAX_DIMS]; /* general buffer size in bytes */ + file_descr fd; /* file handles */ + iotype iot; /* API type */ + char base_name[256]; /* test file base name */ + /* return codes */ + herr_t ret_code = 0; /*return code */ + + char fname[FILENAME_MAX]; /* test file name */ + int i; + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + + /* Sanity check parameters */ + + /* IO type */ + iot = param.io_type; + + switch (iot) { + case POSIXIO: + fd.posixfd = -1; + res->timers = io_time_new(SYS_CLOCK); + break; + case HDF5: + fd.h5fd = -1; + res->timers = io_time_new(SYS_CLOCK); + break; + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); + GOTOERROR(FAIL); + } + + linear_buf_size = 1; + + for (i = 0; i < param.rank; i++) { + buf_size[i] = param.buf_size[i]; + order[i] = param.order[i]; + linear_buf_size *= buf_size[i]; + buf_offset[i] = 0; + offset[i] = 0; + + /* Validate transfer buffer size */ + if (param.buf_size[i] <= 0) { + HDfprintf(stderr, "Transfer buffer size[%d] (%zu) must be > 0\n", i, buf_size[i]); + GOTOERROR(FAIL); + } + + if ((param.dset_size[i] % param.buf_size[i]) != 0) { + HDfprintf(stderr, + "Dataset size[%d] (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " + "trasfer buffer size[%d] (%zu)\n", + param.rank, (long long)param.dset_size[i], param.rank, param.buf_size[i]); + GOTOERROR(FAIL); + } + } + + /* Allocate transfer buffer */ + if ((buffer = (char *)malloc(linear_buf_size)) == NULL) { + HDfprintf(stderr, "malloc for transfer buffer size (%zu) failed\n", linear_buf_size); + GOTOERROR(FAIL); + } + + if (sio_debug_level >= 4) + + /* output all of the times for all iterations */ + HDfprintf(output, "Timer details:\n"); + + /* + * Write performance measurement + */ + /* Open file for write */ + + HDstrcpy(base_name, "#sio_tmp"); + sio_create_filename(iot, base_name, fname, sizeof(fname), ¶m); + + if (sio_debug_level > 0) + HDfprintf(output, "data filename=%s\n", fname); + + io_time_set(res->timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTART); + hrc = do_fopen(¶m, fname, &fd, SIO_CREATE | SIO_WRITE); + VRFY((hrc == SUCCESS), "do_fopen failed"); + + io_time_set(res->timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTART); + hrc = do_write(res, &fd, ¶m, buffer); + io_time_set(res->timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_write failed"); + + /* Close file for write */ + hrc = do_fclose(iot, &fd); + io_time_set(res->timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_fclose failed"); + + if (!param.h5_write_only) { + /* + * Read performance measurement + */ + + /* Open file for read */ + io_time_set(res->timers, HDF5_GROSS_READ_FIXED_DIMS, TSTART); + hrc = do_fopen(¶m, fname, &fd, SIO_READ); + VRFY((hrc == SUCCESS), "do_fopen failed"); + + io_time_set(res->timers, HDF5_FINE_READ_FIXED_DIMS, TSTART); + hrc = do_read(res, &fd, ¶m, buffer); + io_time_set(res->timers, HDF5_FINE_READ_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_read failed"); + + /* Close file for read */ + hrc = do_fclose(iot, &fd); + + io_time_set(res->timers, HDF5_GROSS_READ_FIXED_DIMS, TSTOP); + VRFY((hrc == SUCCESS), "do_fclose failed"); + } + + do_cleanupfile(iot, fname); + +done: + /* clean up */ + /* release HDF5 objects */ + + /* close any opened files */ + /* no remove(fname) because that should have happened normally. */ + switch (iot) { + case POSIXIO: + if (fd.posixfd != -1) + hrc = do_fclose(iot, &fd); + break; + case HDF5: + if (fd.h5fd != -1) + hrc = do_fclose(iot, &fd); + break; + default: + /* unknown request */ + HDassert(0 && "Unknown IO type"); + break; + } + + /* release generic resources */ + if (buffer) + free(buffer); + + res->ret_code = ret_code; +} + +/* + * Function: sio_create_filename + * Purpose: Create a new filename to write to. Determine the correct + * suffix to append to the filename by the type of I/O we're + * doing. Also, place in the /tmp/{$USER,$LOGIN} directory if + * USER or LOGIN are specified in the environment. + * Return: Pointer to filename or NULL + * Programmer: Bill Wendling, 21. November 2001 + * Modifications: Support for file drivers. Christian Chilan, April, 2008 + */ +static char * +sio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size, parameters *param) +{ + const char *prefix, *suffix = ""; + char * ptr, last = '\0'; + size_t i, j; + vfdtype vfd; + vfd = param->vfd; + + if (!base_name || !fullname || size < 1) + return NULL; + + memset(fullname, 0, size); + + switch (iot) { + case POSIXIO: + suffix = ".posix"; + break; + case HDF5: + suffix = ".h5"; + if (vfd == family) + suffix = "%05d.h5"; + else if (vfd == multi) + suffix = NULL; + break; + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); + HDassert(0 && "Unknown IO type"); + break; + } + + /* First use the environment variable and then try the constant */ + prefix = HDgetenv("HDF5_PREFIX"); + +#ifdef HDF5_PREFIX + if (!prefix) + prefix = HDF5_PREFIX; +#endif /* HDF5_PREFIX */ + + /* Prepend the prefix value to the base name */ + if (prefix && *prefix) { + /* If the prefix specifies the HDF5_PREFIX directory, then + * default to using the "/tmp/$USER" or "/tmp/$LOGIN" + * directory instead. */ + register char *user, *login, *subdir; + + user = HDgetenv("USER"); + login = HDgetenv("LOGIN"); + subdir = (user ? user : login); + + if (subdir) { + for (i = 0; i < size - 1 && prefix[i]; i++) + fullname[i] = prefix[i]; + + fullname[i++] = '/'; + + for (j = 0; i < size && subdir[j]; i++, j++) + fullname[i] = subdir[j]; + } + else { + /* We didn't append the prefix yet */ + HDstrncpy(fullname, prefix, size); + fullname[size - 1] = '\0'; + } + + if ((HDstrlen(fullname) + HDstrlen(base_name) + 1) < size) { + /* Append the base_name with a slash first. Multiple slashes are + * handled below. */ + h5_stat_t buf; + + if (HDstat(fullname, &buf) < 0) + /* The directory doesn't exist just yet */ + if (HDmkdir(fullname, 0755) < 0 && errno != EEXIST) { + /* We couldn't make the "/tmp/${USER,LOGIN}" subdirectory. + * Default to PREFIX's original prefix value. */ + HDstrcpy(fullname, prefix); + } + + HDstrcat(fullname, "/"); + HDstrcat(fullname, base_name); + } + else { + /* Buffer is too small */ + return NULL; + } + } + else if (strlen(base_name) >= size) { + /* Buffer is too small */ + return NULL; + } + else { + HDstrcpy(fullname, base_name); + } + + /* Append a suffix */ + if (suffix) { + if (HDstrlen(fullname) + HDstrlen(suffix) >= size) + return NULL; + + HDstrcat(fullname, suffix); + } + + /* Remove any double slashes in the filename */ + for (ptr = fullname, i = j = 0; ptr && (i < size); i++, ptr++) { + if (*ptr != '/' || last != '/') + fullname[j++] = *ptr; + + last = *ptr; + } + + return fullname; +} + +/* + * Function: do_write + * Purpose: Write the required amount of data to the file. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ +static herr_t +do_write(results *res, file_descr *fd, parameters *parms, void *buffer) +{ + int ret_code = SUCCESS; + char dname[64]; + int i; + size_t u; + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + hsize_t h5dims[MAX_DIMS]; /*dataset dim sizes */ + hsize_t h5chunk[MAX_DIMS]; /*dataset dim sizes */ + hsize_t h5block[MAX_DIMS]; /*dataspace selection */ + hsize_t h5stride[MAX_DIMS]; /*selection stride */ + hsize_t h5start[MAX_DIMS]; /*selection start */ + hsize_t h5maxdims[MAX_DIMS]; + int rank; /*rank of dataset */ + + /* Prepare buffer for verifying data */ + /* if (parms->verify) + memset(buffer,1,linear_buf_size); */ + + buf_p = (unsigned char *)buffer; + + for (u = 0; u < linear_buf_size; u++) + buf_p[u] = u % 128; + + rank = parms->rank; + + for (i = 0; i < rank; i++) + h5offset[i] = offset[i] = 0; + + /* I/O Access specific setup */ + switch (parms->io_type) { + case POSIXIO: + + /* determine lowest dimension for contiguous POSIX access */ + cont_dim = rank; + + for (i = rank - 1; i >= 0; i--) { + if (parms->buf_size[i] == parms->dset_size[i]) + cont_dim = i; + else + break; + } + + /* determine size of the contiguous POSIX access */ + cont_size = (!cont_dim) ? 1 : parms->buf_size[cont_dim - 1]; + for (i = cont_dim; i < rank; i++) + cont_size *= parms->buf_size[i]; + + break; + + case HDF5: /* HDF5 setup */ + + for (i = 0; i < rank; i++) { + h5dims[i] = parms->dset_size[i]; + h5start[i] = 0; + h5stride[i] = 1; + h5block[i] = 1; + h5count[i] = parms->buf_size[i]; + h5chunk[i] = parms->chk_size[i]; + h5maxdims[i] = H5S_UNLIMITED; + } + + if (parms->h5_use_chunks && parms->h5_extendable) { + h5dset_space_id = H5Screate_simple(rank, h5count, h5maxdims); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + } + else { + h5dset_space_id = H5Screate_simple(rank, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + } + + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + + /* Create the memory dataspace that corresponds to the xfer buffer */ + h5mem_space_id = H5Screate_simple(rank, h5count, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + + /* Create the dataset transfer property list */ + h5dxpl = H5Pcreate(H5P_DATASET_XFER); + if (h5dxpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + break; + + default: + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + GOTOERROR(FAIL); + break; + } /* end switch */ + + /* create dataset */ + switch (parms->io_type) { + case POSIXIO: + break; + + case HDF5: + h5dcpl = H5Pcreate(H5P_DATASET_CREATE); + + if (h5dcpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + if (parms->h5_use_chunks) { + /* Set the chunk size to be the same as the buffer size */ + hrc = H5Pset_chunk(h5dcpl, rank, h5chunk); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Set failed\n"); + GOTOERROR(FAIL); + } /* end if */ + } /* end if */ + + HDsprintf(dname, "Dataset_%ld", (unsigned long)parms->num_bytes); + h5ds_id = + H5Dcreate2(fd->h5fd, dname, ELMT_H5_TYPE, h5dset_space_id, H5P_DEFAULT, h5dcpl, H5P_DEFAULT); + + if (h5ds_id < 0) { + HDfprintf(stderr, "HDF5 Dataset Create failed\n"); + GOTOERROR(FAIL); + } + + hrc = H5Pclose(h5dcpl); + /* verifying the close of the dcpl */ + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Property List Close failed\n"); + GOTOERROR(FAIL); + } + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + GOTOERROR(FAIL); + break; + } + + /* Start "raw data" write timer */ + io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTART); + + /* Perform write */ + hrc = dset_write(rank - 1, fd, parms, buffer); + + if (hrc < 0) { + HDfprintf(stderr, "Error in dataset write\n"); + GOTOERROR(FAIL); + } + + /* Stop "raw data" write timer */ + io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTOP); + + /* Calculate write time */ + + /* Close dataset. Only HDF5 needs to do an explicit close. */ + if (parms->io_type == HDF5) { + hrc = H5Dclose(h5ds_id); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Close failed\n"); + GOTOERROR(FAIL); + } + + h5ds_id = H5I_INVALID_HID; + } /* end if */ + +done: + + /* release HDF5 objects */ + if (h5dset_space_id != -1) { + hrc = H5Sclose(h5dset_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); + ret_code = FAIL; + } + else { + h5dset_space_id = H5I_INVALID_HID; + } + } + + if (h5mem_space_id != -1) { + hrc = H5Sclose(h5mem_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); + ret_code = FAIL; + } + else { + h5mem_space_id = H5I_INVALID_HID; + } + } + + if (h5dxpl != -1) { + hrc = H5Pclose(h5dxpl); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); + ret_code = FAIL; + } + else { + h5dxpl = H5I_INVALID_HID; + } + } + + return ret_code; +} + +/* + * Function: dset_write + * Purpose: Write buffer into the dataset. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ +static herr_t +dset_write(int local_dim, file_descr *fd, parameters *parms, void *buffer) +{ + int cur_dim = order[local_dim] - 1; + int ret_code = SUCCESS; + int k; + hsize_t dims[MAX_DIMS], maxdims[MAX_DIMS]; + hsize_t i; + int j; + herr_t hrc; + + /* iterates according to the dimensions in order array */ + for (i = 0; i < parms->dset_size[cur_dim]; i += parms->buf_size[cur_dim]) { + + h5offset[cur_dim] = (hssize_t)i; + offset[cur_dim] = (HDoff_t)i; + + if (local_dim > 0) { + + dset_write(local_dim - 1, fd, parms, buffer); + } + else { + + switch (parms->io_type) { + + case POSIXIO: + /* initialize POSIX offset in the buffer */ + for (j = 0; j < parms->rank; j++) + buf_offset[j] = 0; + buf_p = (unsigned char *)buffer; + /* write POSIX buffer */ + posix_buffer_write(0, fd, parms, buffer); + break; + + case HDF5: + /* if dimensions are extendable, extend them as needed during access */ + if (parms->h5_use_chunks && parms->h5_extendable) { + + hrc = H5Sget_simple_extent_dims(h5dset_space_id, dims, maxdims); + VRFY((hrc >= 0), "H5Sget_simple_extent_dims"); + + for (k = 0; k < parms->rank; k++) { + + HDassert(h5offset[k] >= 0); + if (dims[k] <= (hsize_t)h5offset[k]) { + dims[k] = dims[k] + h5count[k]; + hrc = H5Sset_extent_simple(h5dset_space_id, parms->rank, dims, maxdims); + VRFY((hrc >= 0), "H5Sset_extent_simple"); + hrc = H5Dset_extent(h5ds_id, dims); + VRFY((hrc >= 0), "H5Dextend"); + } + } + } + /* applies offset */ + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + + /* Write the buffer out */ + hrc = H5Sget_simple_extent_dims(h5dset_space_id, dims, maxdims); + hrc = H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dwrite"); + + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + HDassert(0 && "Unknown IO type"); + break; + } /* switch (parms->io_type) */ + } + } +done: + return ret_code; +} + +/* + * Function: posix_buffer_write + * Purpose: Write buffer into the POSIX file considering contiguity. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ + +static herr_t +posix_buffer_write(int local_dim, file_descr *fd, parameters *parms, void *buffer) +{ + int ret_code = SUCCESS; + + /* if dimension is not contiguous, call recursively */ + if (local_dim < parms->rank - 1 && local_dim != cont_dim) { + size_t u; + + for (u = 0; u < parms->buf_size[local_dim]; u++) { + buf_offset[local_dim] = u; + posix_buffer_write(local_dim + 1, fd, parms, buffer); + + /* if next dimension is cont_dim, it will fill out the buffer + traversing the entire dimension local_dim without the need + of performing iteration */ + if (local_dim + 1 == cont_dim) + break; + } + /* otherwise, perform contiguous POSIX access */ + } + else { + HDoff_t d_offset; + HDoff_t linear_dset_offset = 0; + int i, j, rc; + + buf_offset[local_dim] = 0; + + /* determine offset in the buffer */ + for (i = 0; i < parms->rank; i++) { + d_offset = 1; + + for (j = i + 1; j < parms->rank; j++) + d_offset *= (HDoff_t)parms->dset_size[j]; + + linear_dset_offset += (offset[i] + (HDoff_t)buf_offset[i]) * d_offset; + } + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, linear_dset_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + /* check if all bytes are written */ + rc = ((ssize_t)cont_size == POSIXWRITE(fd->posixfd, buf_p, cont_size)); + VRFY((rc != 0), "POSIXWRITE"); + + /* Advance location in buffer */ + buf_p += cont_size; + } + +done: + return ret_code; +} + +/* + * Function: do_read + * Purpose: Read the required amount of data to the file. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ +static herr_t +do_read(results *res, file_descr *fd, parameters *parms, void *buffer) +{ + char * buffer2 = NULL; /* Buffer for data verification */ + int ret_code = SUCCESS; + char dname[64]; + int i; + size_t u; + /* HDF5 variables */ + herr_t hrc; /*HDF5 return code */ + hsize_t h5dims[MAX_DIMS]; /*dataset dim sizes */ + hsize_t h5block[MAX_DIMS]; /*dataspace selection */ + hsize_t h5stride[MAX_DIMS]; /*selection stride */ + hsize_t h5start[MAX_DIMS]; /*selection start */ + int rank; + + /* Allocate data verification buffer */ + if (NULL == (buffer2 = (char *)malloc(linear_buf_size))) { + HDfprintf(stderr, "malloc for data verification buffer size (%zu) failed\n", linear_buf_size); + GOTOERROR(FAIL); + } /* end if */ + + /* Prepare buffer for verifying data */ + for (u = 0; u < linear_buf_size; u++) + buffer2[u] = (char)(u % 128); + + rank = parms->rank; + for (i = 0; i < rank; i++) + h5offset[i] = offset[i] = 0; + + /* I/O Access specific setup */ + switch (parms->io_type) { + case POSIXIO: + cont_dim = rank; + + for (i = rank - 1; i >= 0; i--) { + if (parms->buf_size[i] == parms->dset_size[i]) + cont_dim = i; + else + break; + } + cont_size = (!cont_dim) ? 1 : parms->buf_size[cont_dim - 1]; + for (i = cont_dim; i < rank; i++) + cont_size *= parms->buf_size[i]; + + break; + + case HDF5: /* HDF5 setup */ + for (i = 0; i < rank; i++) { + h5dims[i] = parms->dset_size[i]; + h5start[i] = 0; + h5stride[i] = 1; + h5block[i] = 1; + h5count[i] = parms->buf_size[i]; + } + + h5dset_space_id = H5Screate_simple(rank, h5dims, NULL); + VRFY((h5dset_space_id >= 0), "H5Screate_simple"); + + hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, h5block); + VRFY((hrc >= 0), "H5Sselect_hyperslab"); + + /* Create the memory dataspace that corresponds to the xfer buffer */ + h5mem_space_id = H5Screate_simple(rank, h5count, NULL); + VRFY((h5mem_space_id >= 0), "H5Screate_simple"); + + /* Create the dataset transfer property list */ + h5dxpl = H5Pcreate(H5P_DATASET_XFER); + if (h5dxpl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + GOTOERROR(FAIL); + break; + } /* end switch */ + + /* create dataset */ + switch (parms->io_type) { + case POSIXIO: + break; + + case HDF5: + HDsprintf(dname, "Dataset_%ld", (long)parms->num_bytes); + h5ds_id = H5Dopen2(fd->h5fd, dname, H5P_DEFAULT); + if (h5ds_id < 0) { + HDfprintf(stderr, "HDF5 Dataset open failed\n"); + GOTOERROR(FAIL); + } + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + GOTOERROR(FAIL); + break; + } /* end switch */ + + /* Start "raw data" read timer */ + io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTART); + hrc = dset_read(rank - 1, fd, parms, buffer, buffer2); + + if (hrc < 0) { + HDfprintf(stderr, "Error in dataset read\n"); + GOTOERROR(FAIL); + } + + /* Stop "raw data" read timer */ + io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTOP); + + /* Calculate read time */ + + /* Close dataset. Only HDF5 needs to do an explicit close. */ + if (parms->io_type == HDF5) { + hrc = H5Dclose(h5ds_id); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Close failed\n"); + GOTOERROR(FAIL); + } + + h5ds_id = H5I_INVALID_HID; + } /* end if */ + +done: + + /* release HDF5 objects */ + if (h5dset_space_id != -1) { + hrc = H5Sclose(h5dset_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); + ret_code = FAIL; + } + else { + h5dset_space_id = H5I_INVALID_HID; + } + } + + if (h5mem_space_id != -1) { + hrc = H5Sclose(h5mem_space_id); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); + ret_code = FAIL; + } + else { + h5mem_space_id = H5I_INVALID_HID; + } + } + + if (h5dxpl != -1) { + hrc = H5Pclose(h5dxpl); + if (hrc < 0) { + HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); + ret_code = FAIL; + } + else { + h5dxpl = H5I_INVALID_HID; + } + } + + /* release generic resources */ + if (buffer2) + free(buffer2); + + return ret_code; +} + +/* + * Function: dset_read + * Purpose: Read buffer into the dataset. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ + +static herr_t +dset_read(int local_dim, file_descr *fd, parameters *parms, void *buffer, const char *buffer2) +{ + int cur_dim = order[local_dim] - 1; + hsize_t i; + int j; + herr_t hrc; + int ret_code = SUCCESS; + + /* iterate on the current dimension */ + for (i = 0; i < parms->dset_size[cur_dim]; i += parms->buf_size[cur_dim]) { + + h5offset[cur_dim] = (hssize_t)i; + offset[cur_dim] = (HDoff_t)i; + + /* if traverse in order array is incomplete, recurse */ + if (local_dim > 0) { + + ret_code = dset_read(local_dim - 1, fd, parms, buffer, buffer2); + + /* otherwise, write buffer into dataset */ + } + else { + + switch (parms->io_type) { + + case POSIXIO: + for (j = 0; j < parms->rank; j++) { + buf_offset[j] = 0; + } + buf_p = (unsigned char *)buffer; + posix_buffer_read(0, fd, parms, buffer); + break; + + case HDF5: + hrc = H5Soffset_simple(h5dset_space_id, h5offset); + VRFY((hrc >= 0), "H5Soffset_simple"); + /* Read the buffer out */ + hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); + VRFY((hrc >= 0), "H5Dread"); + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); + HDassert(0 && "Unknown IO type"); + break; + } /* switch (parms->io_type) */ + } + } +done: + return ret_code; +} + +/* + * Function: posix_buffer_read + * Purpose: Read buffer into the POSIX file considering contiguity. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ + +static herr_t +posix_buffer_read(int local_dim, file_descr *fd, parameters *parms, void *buffer) +{ + int ret_code = SUCCESS; + + /* if local dimension is not contiguous, recurse */ + if (local_dim < parms->rank - 1 && local_dim != cont_dim) { + size_t u; + + for (u = 0; u < parms->buf_size[local_dim]; u++) { + buf_offset[local_dim] = u; + ret_code = posix_buffer_read(local_dim + 1, fd, parms, buffer); + if (local_dim + 1 == cont_dim) + break; + } + /* otherwise, perform contiguous POSIX access */ + } + else { + HDoff_t d_offset; + HDoff_t linear_dset_offset = 0; + int i, j, rc; + + buf_offset[local_dim] = 0; + /* determine offset in buffer */ + for (i = 0; i < parms->rank; i++) { + d_offset = 1; + + for (j = i + 1; j < parms->rank; j++) + d_offset *= (HDoff_t)parms->dset_size[j]; + + linear_dset_offset += (offset[i] + (HDoff_t)buf_offset[i]) * d_offset; + } + + /* only care if seek returns error */ + rc = POSIXSEEK(fd->posixfd, linear_dset_offset) < 0 ? -1 : 0; + VRFY((rc == 0), "POSIXSEEK"); + /* check if all bytes are read */ + rc = ((ssize_t)cont_size == POSIXREAD(fd->posixfd, buf_p, cont_size)); + VRFY((rc != 0), "POSIXREAD"); + + /* Advance location in buffer */ + buf_p += cont_size; + } +done: + return ret_code; +} + +/* + * Function: do_fopen + * Purpose: Open the specified file. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 + * Modifications: Support for file drivers, Christian Chilan, April, 2008 + */ +static herr_t +do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags) +{ + int ret_code = SUCCESS; + hid_t fcpl; + + switch (param->io_type) { + case POSIXIO: + if (flags & (SIO_CREATE | SIO_WRITE)) + fd->posixfd = POSIXCREATE(fname); + else + fd->posixfd = POSIXOPEN(fname, O_RDONLY); + + if (fd->posixfd < 0) { + HDfprintf(stderr, "POSIX File Open failed(%s)\n", fname); + GOTOERROR(FAIL); + } + + break; + + case HDF5: + + fapl = set_vfd(param); + + if (fapl < 0) { + HDfprintf(stderr, "HDF5 Property List Create failed\n"); + GOTOERROR(FAIL); + } + + fcpl = H5Pcreate(H5P_FILE_CREATE); + if (param->page_size) { + H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, 0, (hsize_t)1); + H5Pset_file_space_page_size(fcpl, param->page_size); + if (param->page_buffer_size) + H5Pset_page_buffer_size(fapl, param->page_buffer_size, 0, 0); + } + + /* create the parallel file */ + if (flags & (SIO_CREATE | SIO_WRITE)) { + fd->h5fd = H5Fcreate(fname, H5F_ACC_TRUNC, fcpl, fapl); + } + else { + fd->h5fd = H5Fopen(fname, H5F_ACC_RDONLY, fapl); + } + + if (fd->h5fd < 0) { + HDfprintf(stderr, "HDF5 File Create failed(%s)\n", fname); + GOTOERROR(FAIL); + } + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)param->io_type); + GOTOERROR(FAIL); + break; + } + +done: + return ret_code; +} + +/* + * Function: set_vfd + * Purpose: Sets file driver. + * Return: SUCCESS or FAIL + * Programmer: Christian Chilan, April, 2008 + * Modifications: + */ + +hid_t +set_vfd(parameters *param) +{ + hid_t my_fapl = H5I_INVALID_HID; + vfdtype vfd; + + vfd = param->vfd; + + if ((my_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + return -1; + + if (vfd == sec2) { + /* Unix read() and write() system calls */ + if (H5Pset_fapl_sec2(my_fapl) < 0) + return -1; + } + else if (vfd == stdio) { + /* Standard C fread() and fwrite() system calls */ + if (H5Pset_fapl_stdio(my_fapl) < 0) + return -1; + } + else if (vfd == core) { + /* In-core temporary file with 1MB increment */ + if (H5Pset_fapl_core(my_fapl, (size_t)1024 * 1024, TRUE) < 0) + return -1; + } + else if (vfd == split) { + /* Split meta data and raw data each using default driver */ + if (H5Pset_fapl_split(my_fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0) + return -1; + } + else if (vfd == multi) { + /* Multi-file driver, general case of the split driver */ + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + const char *memb_name[H5FD_MEM_NTYPES]; + char sv[H5FD_MEM_NTYPES][1024]; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + H5FD_mem_t mt; + + HDmemset(memb_map, 0, sizeof memb_map); + HDmemset(memb_fapl, 0, sizeof memb_fapl); + HDmemset(memb_name, 0, sizeof memb_name); + HDmemset(memb_addr, 0, sizeof memb_addr); + + HDassert(HDstrlen(multi_letters) == H5FD_MEM_NTYPES); + for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { + memb_fapl[mt] = H5P_DEFAULT; + HDsprintf(sv[mt], "%%s-%c.h5", multi_letters[mt]); + memb_name[mt] = sv[mt]; + memb_addr[mt] = (haddr_t)MAX(mt - 1, 0) * (HADDR_MAX / 10); + } + + if (H5Pset_fapl_multi(my_fapl, memb_map, memb_fapl, memb_name, memb_addr, FALSE) < 0) { + return -1; + } + } + else if (vfd == family) { + hsize_t fam_size = 1 * 1024 * 1024; /*100 MB*/ + + /* Family of files, each 1MB and using the default driver */ + /* if ((val=HDstrtok(NULL, " \t\n\r"))) + fam_size = (hsize_t)(HDstrtod(val, NULL) * 1024*1024); */ + if (H5Pset_fapl_family(my_fapl, fam_size, H5P_DEFAULT) < 0) + return -1; + } + else if (vfd == direct) { +#ifdef H5_HAVE_DIRECT + /* Linux direct read() and write() system calls. Set memory boundary, file block size, + * and copy buffer size to the default values. */ + if (H5Pset_fapl_direct(my_fapl, 1024, 4096, 8 * 4096) < 0) + return -1; +#endif + } + else { + /* Unknown driver */ + return -1; + } + + return my_fapl; +} + +/* + * Function: do_fclose + * Purpose: Close the specified file descriptor. + * Return: SUCCESS or FAIL + * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 + * Modifications: + */ +static herr_t +do_fclose(iotype iot, file_descr *fd /*out*/) +{ + herr_t ret_code = SUCCESS, hrc; + int rc = 0; + + switch (iot) { + case POSIXIO: + rc = POSIXCLOSE(fd->posixfd); + + if (rc != 0) { + HDfprintf(stderr, "POSIX File Close failed\n"); + GOTOERROR(FAIL); + } + + fd->posixfd = -1; + break; + + case HDF5: + hrc = H5Fclose(fd->h5fd); + + if (hrc < 0) { + HDfprintf(stderr, "HDF5 File Close failed\n"); + GOTOERROR(FAIL); + } + + fd->h5fd = -1; + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); + GOTOERROR(FAIL); + break; + } + +done: + return ret_code; +} + +/* + * Function: do_cleanupfile + * Purpose: Cleanup temporary file unless HDF5_NOCLEANUP is set. + * Return: void + * Programmer: Albert Cheng 2001/12/12 + * Modifications: Support for file drivers. Christian Chilan, April, 2008 + */ +static void +do_cleanupfile(iotype iot, char *filename) +{ + char temp[2048]; + int j; + hid_t driver; + + if (clean_file_g == -1) + clean_file_g = (HDgetenv("HDF5_NOCLEANUP") == NULL) ? 1 : 0; + + if (clean_file_g) { + + switch (iot) { + case POSIXIO: + HDremove(filename); + break; + + case HDF5: + driver = H5Pget_driver(fapl); + + if (driver == H5FD_FAMILY) { + for (j = 0; /*void*/; j++) { + HDsnprintf(temp, sizeof temp, filename, j); + + if (HDaccess(temp, F_OK) < 0) + break; + + HDremove(temp); + } + } + else if (driver == H5FD_CORE) { + hbool_t backing; /* Whether the core file has backing store */ + + H5Pget_fapl_core(fapl, NULL, &backing); + + /* If the file was stored to disk with bacing store, remove it */ + if (backing) + HDremove(filename); + } + else if (driver == H5FD_MULTI) { + H5FD_mem_t mt; + assert(HDstrlen(multi_letters) == H5FD_MEM_NTYPES); + + for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { + HDsnprintf(temp, sizeof temp, "%s-%c.h5", filename, multi_letters[mt]); + HDremove(temp); /*don't care if it fails*/ + } + } + else { + HDremove(filename); + } + H5Pclose(fapl); + break; + + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); + HDassert(0 && "Unknown IO type"); + break; + } + } +} diff --git a/tools/src/h5perf/sio_perf.c b/tools/src/h5perf/sio_perf.c new file mode 100644 index 0000000..1b200b0 --- /dev/null +++ b/tools/src/h5perf/sio_perf.c @@ -0,0 +1,1301 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Serial HDF5 Performance Testing Code + * -------------------------------------- + * + * Portable code to test performance on the different platforms we support. + * This is what the report should look like: + * + * nprocs = Max#Procs + * IO API = POSIXIO + * # Files = 1, # of dsets = 1000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * # Files = 1, # of dsets = 3000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * + * . . . + * + * + * IO API = HDF5 + * # Files = 1, # of dsets = 1000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * # Files = 1, # of dsets = 3000, Elements per dset = 37000 + * Write Results = x MB/s + * Read Results = x MB/s + * + * . . . + * + * + * . . . + * + */ + +/* system header files */ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include "hdf5.h" + +/* our header files */ +#include "sio_perf.h" + +/* useful macros */ +#define TAB_SPACE 4 + +#define ONE_KB 1024 +#define ONE_MB (ONE_KB * ONE_KB) +#define ONE_GB (ONE_MB * ONE_KB) + +#define SIO_POSIX 0x1 +#define SIO_HDF5 0x4 + +/* report 0.0 in case t is zero too */ +#define MB_PER_SEC(bytes, t) (H5_DBL_ABS_EQUAL(t, 0.0) ? 0.0 : ((((double)(bytes)) / (double)ONE_MB) / (t))) + +#ifndef TRUE +#define TRUE 1 +#endif /* TRUE */ +#ifndef FALSE +#define FALSE (!TRUE) +#endif /* FALSE */ + +/* global variables */ +FILE *output; /* output file */ +int sio_debug_level = 0; /* The debug level: + * 0 - Off + * 1 - Minimal + * 2 - Some more + * 3 - Maximal + * 4 - Maximal & then some + */ + +/* local variables */ +static const char *progname = "h5perf_serial"; + +/* + * Command-line options: The user can specify short or long-named + * parameters. The long-named ones can be partially spelled. When + * adding more, make sure that they don't clash with each other. + */ + +/* + * It seems that only the options that accept additional information + * such as dataset size (-e) require the colon next to it. + */ +static const char * s_opts = "a:A:B:c:Cd:D:e:F:ghi:Imno:p:P:r:stT:v:wx:X:"; +static struct h5_long_options l_opts[] = {{"align", require_arg, 'a'}, + {"api", require_arg, 'A'}, +#if 0 + /* a sighting of the elusive binary option */ + { "binary", no_arg, 'b' }, +#endif /* 0 */ + {"block-size", require_arg, 'B'}, + {"chunk", no_arg, 'c'}, + {"collective", no_arg, 'C'}, + {"debug", require_arg, 'D'}, + {"file-driver", require_arg, 'v'}, + {"geometry", no_arg, 'g'}, + {"help", no_arg, 'h'}, + {"interleaved", require_arg, 'I'}, + {"max-num-processes", require_arg, 'P'}, + {"min-num-processes", require_arg, 'p'}, + {"max-xfer-size", require_arg, 'X'}, + {"min-xfer-size", require_arg, 'x'}, + {"num-bytes", require_arg, 'e'}, + {"num-dsets", require_arg, 'd'}, + {"num-files", require_arg, 'F'}, + {"num-iterations", require_arg, 'i'}, + {"order", require_arg, 'r'}, + {"output", require_arg, 'o'}, + {"extendable", no_arg, 't'}, + {"threshold", require_arg, 'T'}, + {"write-only", require_arg, 'w'}, + {NULL, 0, '\0'}}; + +struct options { + long io_types; /* bitmask of which I/O types to test */ + const char *output_file; /* file to print report to */ + long num_dsets; /* number of datasets */ + long num_files; /* number of files */ + off_t num_bpp; /* number of bytes per proc per dset */ + int num_iters; /* number of iterations */ + hsize_t dset_size[MAX_DIMS]; /* Dataset size */ + size_t buf_size[MAX_DIMS]; /* Buffer size */ + size_t chk_size[MAX_DIMS]; /* Chunk size */ + int order[MAX_DIMS]; /* Dimension access order */ + int dset_rank; /* Rank */ + int buf_rank; /* Rank */ + int order_rank; /* Rank */ + int chk_rank; /* Rank */ + int print_times; /* print times as well as throughputs */ + int print_raw; /* print raw data throughput info */ + hsize_t h5_alignment; /* alignment in HDF5 file */ + hsize_t h5_threshold; /* threshold for alignment in HDF5 file */ + int h5_use_chunks; /* Make HDF5 dataset chunked */ + int h5_write_only; /* Perform the write tests only */ + int h5_extendable; /* Perform the write tests only */ + int verify; /* Verify data correctness */ + vfdtype vfd; /* File driver */ + size_t page_buffer_size; + size_t page_size; +}; + +typedef struct { + double min; + double max; + double sum; + int num; +} minmax; + +/* local functions */ +static hsize_t parse_size_directive(const char *size); +static struct options *parse_command_line(int argc, const char *argv[]); +static void run_test_loop(struct options *options); +static int run_test(iotype iot, parameters parms, struct options *opts); +static void output_all_info(minmax *mm, int count, int indent_level); +static void get_minmax(minmax *mm, double val); +static void accumulate_minmax_stuff(const minmax *mm, int count, minmax *total_mm); +static void output_results(const struct options *options, const char *name, minmax *table, int table_size, + off_t data_size); +static void output_report(const char *fmt, ...); +static void print_indent(register int indent); +static void usage(const char *prog); +static void report_parameters(struct options *opts); + +/* + * Function: main + * Purpose: Start things up. + * Return: EXIT_SUCCESS or EXIT_FAILURE + * Programmer: Bill Wendling, 30. October 2001 + * Modifications: + */ +int +main(int argc, const char *argv[]) +{ + int exit_value = EXIT_SUCCESS; + struct options *opts = NULL; + +#ifndef STANDALONE + /* Initialize h5tools lib */ + h5tools_init(); +#endif + + output = stdout; + + opts = parse_command_line(argc, argv); + + if (!opts) { + exit_value = EXIT_FAILURE; + goto finish; + } + + if (opts->output_file) { + if ((output = HDfopen(opts->output_file, "w")) == NULL) { + HDfprintf(stderr, "%s: cannot open output file\n", progname); + HDperror(opts->output_file); + goto finish; + } + } + + report_parameters(opts); + + run_test_loop(opts); + +finish: + HDfree(opts); + return exit_value; +} + +/* + * Function: run_test_loop + * Purpose: Run the I/O tests. Write the results to OUTPUT. + * + * - The slowest changing part of the test is the number of + * processors to use. For each loop iteration, we divide that + * number by 2 and rerun the test. + * + * - The second slowest is what type of IO API to perform. We have + * three choices: POSIXIO, and HDF5. + * + * - Then we change the size of the buffer. This information is + * inferred from the number of datasets to create and the number + * of integers to put into each dataset. The backend code figures + * this out. + * + * Return: Nothing + * Programmer: Bill Wendling, 30. October 2001 + * Modifications: + * Added multidimensional testing (Christian Chilan, April, 2008) + */ +static void +run_test_loop(struct options *opts) +{ + parameters parms; + int i; + size_t buf_bytes; + + /* load options into parameter structure */ + parms.num_files = opts->num_files; + parms.num_dsets = opts->num_dsets; + parms.num_iters = opts->num_iters; + parms.rank = opts->dset_rank; + parms.h5_align = opts->h5_alignment; + parms.h5_thresh = opts->h5_threshold; + parms.h5_use_chunks = opts->h5_use_chunks; + parms.h5_extendable = opts->h5_extendable; + parms.h5_write_only = opts->h5_write_only; + parms.verify = opts->verify; + parms.vfd = opts->vfd; + parms.page_buffer_size = opts->page_buffer_size; + parms.page_size = opts->page_size; + + /* load multidimensional options */ + parms.num_bytes = 1; + buf_bytes = 1; + for (i = 0; i < parms.rank; i++) { + parms.buf_size[i] = opts->buf_size[i]; + parms.dset_size[i] = opts->dset_size[i]; + parms.chk_size[i] = opts->chk_size[i]; + parms.order[i] = opts->order[i]; + parms.num_bytes *= opts->dset_size[i]; + buf_bytes *= opts->buf_size[i]; + } + + /* print size information */ + output_report("Transfer Buffer Size (bytes): %d\n", buf_bytes); + output_report("File Size(MB): %.2f\n", ((double)parms.num_bytes) / ONE_MB); + + print_indent(0); + if (opts->io_types & SIO_POSIX) + run_test(POSIXIO, parms, opts); + + print_indent(0); + if (opts->io_types & SIO_HDF5) + run_test(HDF5, parms, opts); +} + +/* + * Function: run_test + * Purpose: Inner loop call to actually run the I/O test. + * Return: Nothing + * Programmer: Bill Wendling, 18. December 2001 + * Modifications: + */ +static int +run_test(iotype iot, parameters parms, struct options *opts) +{ + results res; + register int i, ret_value = SUCCESS; + off_t raw_size; + minmax * write_sys_mm_table = NULL; + minmax * write_mm_table = NULL; + minmax * write_gross_mm_table = NULL; + minmax * write_raw_mm_table = NULL; + minmax * read_sys_mm_table = NULL; + minmax * read_mm_table = NULL; + minmax * read_gross_mm_table = NULL; + minmax * read_raw_mm_table = NULL; + minmax write_sys_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax write_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax write_gross_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax write_raw_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax read_sys_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax read_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax read_gross_mm = {0.0F, 0.0F, 0.0F, 0}; + minmax read_raw_mm = {0.0F, 0.0F, 0.0F, 0}; + + raw_size = (off_t)parms.num_bytes; + parms.io_type = iot; + print_indent(2); + output_report("IO API = "); + + switch (iot) { + case POSIXIO: + output_report("POSIX\n"); + break; + case HDF5: + output_report("HDF5\n"); + break; + default: + /* unknown request */ + HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); + HDassert(0 && "Unknown IO tpe"); + break; + } + + /* allocate space for tables minmax and that it is sufficient */ + /* to initialize all elements to zeros by calloc. */ + write_sys_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + write_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + write_gross_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + write_raw_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + + if (!parms.h5_write_only) { + read_sys_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + read_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + read_gross_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + read_raw_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); + } + + /* Do IO iteration times, collecting statistics each time */ + for (i = 0; i < parms.num_iters; ++i) { + double t; + + do_sio(parms, &res); + + /* gather all of the "sys write" times */ + t = io_time_get(res.timers, HDF5_MPI_WRITE); + get_minmax(&write_sys_mm, t); + + write_sys_mm_table[i] = write_sys_mm; + + /* gather all of the "write" times */ + t = io_time_get(res.timers, HDF5_FINE_WRITE_FIXED_DIMS); + get_minmax(&write_mm, t); + + write_mm_table[i] = write_mm; + + /* gather all of the "write" times from open to close */ + t = io_time_get(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS); + get_minmax(&write_gross_mm, t); + + write_gross_mm_table[i] = write_gross_mm; + + /* gather all of the raw "write" times */ + t = io_time_get(res.timers, HDF5_RAW_WRITE_FIXED_DIMS); + get_minmax(&write_raw_mm, t); + + write_raw_mm_table[i] = write_raw_mm; + + if (!parms.h5_write_only) { + /* gather all of the "mpi read" times */ + t = io_time_get(res.timers, HDF5_MPI_READ); + get_minmax(&read_sys_mm, t); + + read_sys_mm_table[i] = read_sys_mm; + + /* gather all of the "read" times */ + t = io_time_get(res.timers, HDF5_FINE_READ_FIXED_DIMS); + get_minmax(&read_mm, t); + + read_mm_table[i] = read_mm; + + /* gather all of the "read" times from open to close */ + t = io_time_get(res.timers, HDF5_GROSS_READ_FIXED_DIMS); + get_minmax(&read_gross_mm, t); + + read_gross_mm_table[i] = read_gross_mm; + + /* gather all of the raw "read" times */ + t = io_time_get(res.timers, HDF5_RAW_READ_FIXED_DIMS); + get_minmax(&read_raw_mm, t); + + read_raw_mm_table[i] = read_gross_mm; + } + io_time_destroy(res.timers); + } + + /* + * Show various statistics + */ + /* Write statistics */ + /* Print the raw data throughput if desired */ + if (opts->print_raw) { + /* accumulate and output the max, min, and average "raw write" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Raw Data Write details:\n"); + output_all_info(write_raw_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Raw Data Write", write_raw_mm_table, parms.num_iters, raw_size); + } /* end if */ + + /* show sys write statics */ +#if 0 + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("MPI Write details:\n"); + output_all_info(write_sys_mm_table, parms.num_iters, 4); + } +#endif + /* We don't currently output the MPI write results */ + + /* accumulate and output the max, min, and average "write" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write details:\n"); + output_all_info(write_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Write", write_mm_table, parms.num_iters, raw_size); + + /* accumulate and output the max, min, and average "gross write" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Write Open-Close details:\n"); + output_all_info(write_gross_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Write Open-Close", write_gross_mm_table, parms.num_iters, raw_size); + + if (!parms.h5_write_only) { + /* Read statistics */ + /* Print the raw data throughput if desired */ + if (opts->print_raw) { + /* accumulate and output the max, min, and average "raw read" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Raw Data Read details:\n"); + output_all_info(read_raw_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Raw Data Read", read_raw_mm_table, parms.num_iters, raw_size); + } /* end if */ + + /* show mpi read statics */ +#if 0 + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("MPI Read details:\n"); + output_all_info(read_sys_mm_table, parms.num_iters, 4); + } +#endif + /* We don't currently output the MPI read results */ + + /* accumulate and output the max, min, and average "read" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read details:\n"); + output_all_info(read_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Read", read_mm_table, parms.num_iters, raw_size); + + /* accumulate and output the max, min, and average "gross read" times */ + if (sio_debug_level >= 3) { + /* output all of the times for all iterations */ + print_indent(3); + output_report("Read Open-Close details:\n"); + output_all_info(read_gross_mm_table, parms.num_iters, 4); + } + + output_results(opts, "Read Open-Close", read_gross_mm_table, parms.num_iters, raw_size); + } + + /* clean up our mess */ + HDfree(write_sys_mm_table); + HDfree(write_mm_table); + HDfree(write_gross_mm_table); + HDfree(write_raw_mm_table); + + if (!parms.h5_write_only) { + HDfree(read_sys_mm_table); + HDfree(read_mm_table); + HDfree(read_gross_mm_table); + HDfree(read_raw_mm_table); + } + + return ret_value; +} + +/* + * Function: output_all_info + * Purpose: + * Return: Nothing + * Programmer: Bill Wendling, 29. January 2002 + * Modifications: + */ +static void +output_all_info(minmax *mm, int count, int indent_level) +{ + int i; + + for (i = 0; i < count; ++i) { + print_indent(indent_level); + output_report("Iteration %d:\n", i + 1); + print_indent(indent_level + 1); + output_report("Minimum Time: %.2fs\n", mm[i].min); + print_indent(indent_level + 1); + output_report("Maximum Time: %.2fs\n", mm[i].max); + } +} + +/* + * Function: get_minmax + * Purpose: Gather all the min, max and total of val. + * Return: Nothing + * Programmer: Bill Wendling, 21. December 2001 + * Modifications: + * Use MPI_Allreduce to do it. -akc, 2002/01/11 + */ + +static void +get_minmax(minmax *mm, double val) +{ + mm->max = val; + mm->min = val; + mm->sum = val; +} + +/* + * Function: accumulate_minmax_stuff + * Purpose: Accumulate the minimum, maximum, and average of the times + * across all processes. + * Return: TOTAL_MM - the total of all of these. + * Programmer: Bill Wendling, 21. December 2001 + * Modifications: + * Changed to use seconds instead of MB/s - QAK, 5/9/02 + */ +static void +accumulate_minmax_stuff(const minmax *mm, int count, minmax *total_mm) +{ + int i; + + total_mm->sum = 0.0F; + total_mm->max = -DBL_MAX; + total_mm->min = DBL_MAX; + total_mm->num = count; + + for (i = 0; i < count; ++i) { + double m = mm[i].max; + + total_mm->sum += m; + + if (m < total_mm->min) + total_mm->min = m; + + if (m > total_mm->max) + total_mm->max = m; + } +} + +/* + * Function: output_results + * Purpose: Print information about the time & bandwidth for a given + * minmax & # of iterations. + * Return: Nothing + * Programmer: Quincey Koziol, 9. May 2002 + * Modifications: + */ +static void +output_results(const struct options *opts, const char *name, minmax *table, int table_size, off_t data_size) +{ + minmax total_mm; + + accumulate_minmax_stuff(table, table_size, &total_mm); + + print_indent(3); + output_report("%s (%d iteration(s)):\n", name, table_size); + + /* Note: The maximum throughput uses the minimum amount of time & vice versa */ + + print_indent(4); + output_report("Maximum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.min)); + if (opts->print_times) + output_report(" (%7.3f s)\n", total_mm.min); + else + output_report("\n"); + + print_indent(4); + output_report("Average Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.sum / total_mm.num)); + if (opts->print_times) + output_report(" (%7.3f s)\n", (total_mm.sum / total_mm.num)); + else + output_report("\n"); + + print_indent(4); + output_report("Minimum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.max)); + if (opts->print_times) + output_report(" (%7.3f s)\n", total_mm.max); + else + output_report("\n"); +} + +/* + * Function: output_report + * Purpose: Print a line of the report. Only do so if I'm the 0 process. + * Return: Nothing + * Programmer: Bill Wendling, 19. December 2001 + * Modifications: + */ +static void +output_report(const char *fmt, ...) +{ + va_list ap; + + HDva_start(ap, fmt); + HDvfprintf(output, fmt, ap); + HDva_end(ap); +} + +/* + * Function: print_indent + * Purpose: Print spaces to indent a new line of text for pretty printing + * things. + * Return: Nothing + * Programmer: Bill Wendling, 29. October 2001 + * Modifications: + */ +static void +print_indent(register int indent) +{ + indent *= TAB_SPACE; + + for (; indent > 0; --indent) + HDfputc(' ', output); +} + +static void +recover_size_and_print(long long val, const char *end) +{ + if (val >= ONE_KB && (val % ONE_KB) == 0) { + if (val >= ONE_MB && (val % ONE_MB) == 0) { + if (val >= ONE_GB && (val % ONE_GB) == 0) + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "GB%s", + val / ONE_GB, end); + else + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "MB%s", + val / ONE_MB, end); + } + else { + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "KB%s", + val / ONE_KB, end); + } + } + else { + HDfprintf(output, + "%" H5_PRINTF_LL_WIDTH "d" + "%s", + val, end); + } +} + +static void +print_io_api(long io_types) +{ + if (io_types & SIO_POSIX) + HDfprintf(output, "posix "); + if (io_types & SIO_HDF5) + HDfprintf(output, "hdf5 "); + HDfprintf(output, "\n"); +} + +static void +report_parameters(struct options *opts) +{ + int i, rank; + rank = opts->dset_rank; + + print_version("HDF5 Library"); /* print library version */ + HDfprintf(output, "==== Parameters ====\n"); + + HDfprintf(output, "IO API="); + print_io_api(opts->io_types); + + HDfprintf(output, "Number of iterations=%d\n", opts->num_iters); + + HDfprintf(output, "Dataset size="); + + for (i = 0; i < rank; i++) + recover_size_and_print((long long)opts->dset_size[i], " "); + HDfprintf(output, "\n"); + + HDfprintf(output, "Transfer buffer size="); + for (i = 0; i < rank; i++) + recover_size_and_print((long long)opts->buf_size[i], " "); + HDfprintf(output, "\n"); + + if (opts->page_size) { + HDfprintf(output, "Page Aggregation Enabled. Page size = %zu\n", opts->page_size); + if (opts->page_buffer_size) + HDfprintf(output, "Page Buffering Enabled. Page Buffer size = %zu\n", opts->page_buffer_size); + else + HDfprintf(output, "Page Buffering Disabled\n"); + } + else + HDfprintf(output, "Page Aggregation Disabled\n"); + + HDfprintf(output, "Dimension access order="); + for (i = 0; i < rank; i++) + recover_size_and_print((long long)opts->order[i], " "); + HDfprintf(output, "\n"); + + if (opts->io_types & SIO_HDF5) { + + HDfprintf(output, "HDF5 data storage method="); + + if (opts->h5_use_chunks) { + + HDfprintf(output, "Chunked\n"); + HDfprintf(output, "HDF5 chunk size="); + for (i = 0; i < rank; i++) + recover_size_and_print((long long)opts->chk_size[i], " "); + HDfprintf(output, "\n"); + + HDfprintf(output, "HDF5 dataset dimensions="); + if (opts->h5_extendable) { + HDfprintf(output, "Extendable\n"); + } + else { + HDfprintf(output, "Fixed\n"); + } + } + else { + HDfprintf(output, "Contiguous\n"); + } + + HDfprintf(output, "HDF5 file driver="); + if (opts->vfd == sec2) { + HDfprintf(output, "sec2\n"); + } + else if (opts->vfd == stdio) { + HDfprintf(output, "stdio\n"); + } + else if (opts->vfd == core) { + HDfprintf(output, "core\n"); + } + else if (opts->vfd == split) { + HDfprintf(output, "split\n"); + } + else if (opts->vfd == multi) { + HDfprintf(output, "multi\n"); + } + else if (opts->vfd == family) { + HDfprintf(output, "family\n"); + } + else if (opts->vfd == direct) { + HDfprintf(output, "direct\n"); + } + } + + { + char *prefix = HDgetenv("HDF5_PREFIX"); + + HDfprintf(output, "Env HDF5_PREFIX=%s\n", (prefix ? prefix : "not set")); + } + + HDfprintf(output, "==== End of Parameters ====\n"); + HDfprintf(output, "\n"); +} + +/* + * Function: parse_command_line + * Purpose: Parse the command line options and return a STRUCT OPTIONS + * structure which will need to be freed by the calling function. + * Return: Pointer to an OPTIONS structure + * Programmer: Bill Wendling, 31. October 2001 + * Modifications: + * Added multidimensional testing (Christian Chilan, April, 2008) + */ +static struct options * +parse_command_line(int argc, const char *argv[]) +{ + int opt; + struct options *cl_opts; + int i, default_rank, actual_rank, ranks[4]; + + cl_opts = (struct options *)HDmalloc(sizeof(struct options)); + + cl_opts->page_buffer_size = 0; + cl_opts->page_size = 0; + + cl_opts->output_file = NULL; + cl_opts->io_types = 0; /* will set default after parsing options */ + cl_opts->num_iters = 1; + + default_rank = 2; + + cl_opts->dset_rank = 0; + cl_opts->buf_rank = 0; + cl_opts->chk_rank = 0; + cl_opts->order_rank = 0; + + for (i = 0; i < MAX_DIMS; i++) { + cl_opts->buf_size[i] = (size_t)((i + 1) * 10); + cl_opts->dset_size[i] = (hsize_t)((i + 1) * 100); + cl_opts->chk_size[i] = (size_t)((i + 1) * 10); + cl_opts->order[i] = i + 1; + } + + cl_opts->vfd = sec2; + + cl_opts->print_times = FALSE; /* Printing times is off by default */ + cl_opts->print_raw = FALSE; /* Printing raw data throughput is off by default */ + cl_opts->h5_alignment = 1; /* No alignment for HDF5 objects by default */ + cl_opts->h5_threshold = 1; /* No threshold for aligning HDF5 objects by default */ + cl_opts->h5_use_chunks = FALSE; /* Don't chunk the HDF5 dataset by default */ + cl_opts->h5_write_only = FALSE; /* Do both read and write by default */ + cl_opts->h5_extendable = FALSE; /* Use extendable dataset */ + cl_opts->verify = FALSE; /* No Verify data correctness by default */ + + while ((opt = H5_get_option(argc, argv, s_opts, l_opts)) != EOF) { + switch ((char)opt) { + case 'a': + cl_opts->h5_alignment = parse_size_directive(H5_optarg); + break; + case 'G': + cl_opts->page_size = parse_size_directive(H5_optarg); + break; + case 'b': + cl_opts->page_buffer_size = parse_size_directive(H5_optarg); + break; + case 'A': { + const char *end = H5_optarg; + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + if (!HDstrcasecmp(buf, "hdf5")) { + cl_opts->io_types |= SIO_HDF5; + } + else if (!HDstrcasecmp(buf, "posix")) { + cl_opts->io_types |= SIO_POSIX; + } + else { + HDfprintf(stderr, "sio_perf: invalid --api option %s\n", buf); + HDexit(EXIT_FAILURE); + } + + if (*end == '\0') + break; + + end++; + } + } + + break; +#if 0 + case 'b': + /* the future "binary" option */ + break; +#endif /* 0 */ + case 'c': + /* Turn on chunked HDF5 dataset creation */ + cl_opts->h5_use_chunks = 1; + { + const char *end = H5_optarg; + int j = 0; + + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + cl_opts->chk_size[j] = parse_size_directive(buf); + + j++; + + if (*end == '\0') + break; + + end++; + } + cl_opts->chk_rank = j; + } + + break; + + case 'D': { + const char *end = H5_optarg; + + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + if (HDstrlen(buf) > 1 || HDisdigit(buf[0])) { + size_t j; + + for (j = 0; j < 10 && buf[j] != '\0'; ++j) + if (!HDisdigit(buf[j])) { + HDfprintf(stderr, "sio_perf: invalid --debug option %s\n", buf); + HDexit(EXIT_FAILURE); + } + + sio_debug_level = atoi(buf); + + if (sio_debug_level > 4) + sio_debug_level = 4; + else if (sio_debug_level < 0) + sio_debug_level = 0; + } + else { + switch (*buf) { + case 'r': + /* Turn on raw data throughput info */ + cl_opts->print_raw = TRUE; + break; + case 't': + /* Turn on time printing */ + cl_opts->print_times = TRUE; + break; + case 'v': + /* Turn on verify data correctness*/ + cl_opts->verify = TRUE; + break; + default: + HDfprintf(stderr, "sio_perf: invalid --debug option %s\n", buf); + HDexit(EXIT_FAILURE); + } + } + + if (*end == '\0') + break; + + end++; + } + } + + break; + case 'e': { + const char *end = H5_optarg; + int j = 0; + + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + cl_opts->dset_size[j] = parse_size_directive(buf); + + j++; + + if (*end == '\0') + break; + + end++; + } + cl_opts->dset_rank = j; + } + + break; + + case 'i': + cl_opts->num_iters = HDatoi(H5_optarg); + break; + case 'o': + cl_opts->output_file = H5_optarg; + break; + case 'T': + cl_opts->h5_threshold = parse_size_directive(H5_optarg); + break; + case 'v': + if (!HDstrcasecmp(H5_optarg, "sec2")) { + cl_opts->vfd = sec2; + } + else if (!HDstrcasecmp(H5_optarg, "stdio")) { + cl_opts->vfd = stdio; + } + else if (!HDstrcasecmp(H5_optarg, "core")) { + cl_opts->vfd = core; + } + else if (!HDstrcasecmp(H5_optarg, "split")) { + cl_opts->vfd = split; + } + else if (!HDstrcasecmp(H5_optarg, "multi")) { + cl_opts->vfd = multi; + } + else if (!HDstrcasecmp(H5_optarg, "family")) { + cl_opts->vfd = family; + } + else if (!HDstrcasecmp(H5_optarg, "direct")) { + cl_opts->vfd = direct; + } + else { + HDfprintf(stderr, "sio_perf: invalid --api option %s\n", H5_optarg); + HDexit(EXIT_FAILURE); + } + break; + case 'w': + cl_opts->h5_write_only = TRUE; + break; + case 't': + cl_opts->h5_extendable = TRUE; + break; + case 'x': { + const char *end = H5_optarg; + int j = 0; + + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + cl_opts->buf_size[j] = parse_size_directive(buf); + + j++; + + if (*end == '\0') + break; + + end++; + } + cl_opts->buf_rank = j; + } + + break; + + case 'r': { + const char *end = H5_optarg; + int j = 0; + + while (end && *end != '\0') { + char buf[10]; + + HDmemset(buf, '\0', sizeof(buf)); + + for (i = 0; *end != '\0' && *end != ','; ++end) + if (HDisalnum(*end) && i < 10) + buf[i++] = *end; + + cl_opts->order[j] = (int)parse_size_directive(buf); + + j++; + + if (*end == '\0') + break; + + end++; + } + + cl_opts->order_rank = j; + } + + break; + + case 'h': + case '?': + default: + usage(progname); + HDfree(cl_opts); + return NULL; + } + } + + /* perform rank consistency analysis */ + actual_rank = 0; + + ranks[0] = cl_opts->dset_rank; + ranks[1] = cl_opts->buf_rank; + ranks[2] = cl_opts->order_rank; + ranks[3] = cl_opts->chk_rank; + + for (i = 0; i < 4; i++) { + if (ranks[i] > 0) { + if (!actual_rank) { + actual_rank = ranks[i]; + } + else { + if (actual_rank != ranks[i]) + exit(EXIT_FAILURE); + } + } + } + + if (!actual_rank) + actual_rank = default_rank; + + cl_opts->dset_rank = actual_rank; + cl_opts->buf_rank = actual_rank; + cl_opts->order_rank = actual_rank; + cl_opts->chk_rank = actual_rank; + + for (i = 0; i < actual_rank; i++) { + if (cl_opts->order[i] > actual_rank) { + exit(EXIT_FAILURE); + } + } + + /* set default if none specified yet */ + if (!cl_opts->io_types) + cl_opts->io_types = SIO_HDF5 | SIO_POSIX; /* run all API */ + + /* verify parameters sanity. Adjust if needed. */ + /* cap xfer_size with bytes per process */ + if (cl_opts->num_iters <= 0) + cl_opts->num_iters = 1; + + return cl_opts; +} + +/* + * Function: parse_size_directive + * Purpose: Parse the size directive passed on the commandline. The size + * directive is an integer followed by a size indicator: + * + * K, k - Kilobyte + * M, m - Megabyte + * G, g - Gigabyte + * + * Return: The size as a off_t because this is related to file size. + * If an unknown size indicator is used, then the program will + * exit with EXIT_FAILURE as the return value. + * Programmer: Bill Wendling, 18. December 2001 + * Modifications: + */ + +static hsize_t +parse_size_directive(const char *size) +{ + hsize_t s; + char * endptr; + + s = HDstrtoull(size, &endptr, 10); + + if (endptr && *endptr) { + while (*endptr != '\0' && (*endptr == ' ' || *endptr == '\t')) + ++endptr; + + switch (*endptr) { + case 'K': + case 'k': + s *= ONE_KB; + break; + + case 'M': + case 'm': + s *= ONE_MB; + break; + + case 'G': + case 'g': + s *= ONE_GB; + break; + + default: + HDfprintf(stderr, "Illegal size specifier '%c'\n", *endptr); + HDexit(EXIT_FAILURE); + } + } + + return s; +} + +/* + * Function: usage + * Purpose: Print a usage message and then exit. + * Return: Nothing + * Programmer: Bill Wendling, 31. October 2001 + * Modifications: + */ +static void +usage(const char *prog) +{ + print_version(prog); + HDprintf("usage: %s [OPTIONS]\n", prog); + HDprintf(" OPTIONS\n"); + HDprintf(" -h Print an usage message and exit\n"); + HDprintf(" -A AL Which APIs to test\n"); + HDprintf(" [default: all of them]\n"); + HDprintf(" -c SL Selects chunked storage and defines chunks dimensions\n"); + HDprintf(" and sizes\n"); + HDprintf(" [default: Off]\n"); + HDprintf(" -e SL Dimensions and sizes of dataset\n"); + HDprintf(" [default: 100,200]\n"); + HDprintf(" -i N Number of iterations to perform\n"); + HDprintf(" [default: 1]\n"); + HDprintf(" -r NL Dimension access order (see below for description)\n"); + HDprintf(" [default: 1,2]\n"); + HDprintf(" -t Selects extendable dimensions for HDF5 dataset\n"); + HDprintf(" [default: Off]\n"); + HDprintf(" -v VFD Selects file driver for HDF5 access\n"); + HDprintf(" [default: sec2]\n"); + HDprintf(" -w Perform write tests, not the read tests\n"); + HDprintf(" [default: Off]\n"); + HDprintf(" -x SL Dimensions and sizes of the transfer buffer\n"); + HDprintf(" [default: 10,20]\n"); + HDprintf("\n"); + HDprintf(" N - is an integer > 0.\n"); + HDprintf("\n"); + HDprintf(" S - is a size specifier, an integer > 0 followed by a size indicator:\n"); + HDprintf(" K - Kilobyte (%d)\n", ONE_KB); + HDprintf(" M - Megabyte (%d)\n", ONE_MB); + HDprintf(" G - Gigabyte (%d)\n", ONE_GB); + HDprintf("\n"); + HDprintf(" Example: '37M' is 37 megabytes or %d bytes\n", 37 * ONE_MB); + HDprintf("\n"); + HDprintf(" AL - is an API list. Valid values are:\n"); + HDprintf(" hdf5 - HDF5\n"); + HDprintf(" posix - POSIX\n"); + HDprintf("\n"); + HDprintf(" Example: -A posix,hdf5\n"); + HDprintf("\n"); + HDprintf(" NL - is list of integers (N) separated by commas.\n"); + HDprintf("\n"); + HDprintf(" Example: 1,2,3\n"); + HDprintf("\n"); + HDprintf(" SL - is list of size specifiers (S) separated by commas.\n"); + HDprintf("\n"); + HDprintf(" Example: 2K,2K,3K\n"); + HDprintf("\n"); + HDprintf(" The example defines an object (dataset, tranfer buffer) with three\n"); + HDprintf(" dimensions. Be aware that as the number of dimensions increases, the\n"); + HDprintf(" the total size of the object increases exponentially.\n"); + HDprintf("\n"); + HDprintf(" VFD - is an HDF5 file driver specifier. Valid values are:\n"); + HDprintf(" sec2, stdio, core, split, multi, family, direct\n"); + HDprintf("\n"); + HDprintf(" Dimension access order:\n"); + HDprintf(" Data access starts at the cardinal origin of the dataset using the\n"); + HDprintf(" transfer buffer. The next access occurs on a dataset region next to\n"); + HDprintf(" the previous one. For a multidimensional dataset, there are several\n"); + HDprintf(" directions as to where to proceed. This can be specified in the dimension\n"); + HDprintf(" access order. For example, -r 1,2 states that the tool should traverse\n"); + HDprintf(" dimension 1 first, and then dimension 2.\n"); + HDprintf("\n"); + HDprintf(" Environment variables:\n"); + HDprintf(" HDF5_NOCLEANUP Do not remove data files if set [default remove]\n"); + HDprintf(" HDF5_PREFIX Data file prefix\n"); + HDprintf("\n"); + HDfflush(stdout); +} /* end usage() */ diff --git a/tools/src/h5perf/sio_perf.h b/tools/src/h5perf/sio_perf.h new file mode 100644 index 0000000..d998377 --- /dev/null +++ b/tools/src/h5perf/sio_perf.h @@ -0,0 +1,104 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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://www.hdfgroup.org/licenses. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef SIO_PERF_H +#define SIO_PERF_H + +#ifndef STANDALONE +#include "io_timer.h" +#include "H5private.h" +#include "h5tools.h" +#include "h5tools_utils.h" +#else +#include "io_timer.h" +#include "sio_standalone.h" +#endif + +/* setup the dataset no fill option if this is v1.5 or more */ +#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR > 4 +#define H5_HAVE_NOFILL 1 +#endif + +#define MAX_DIMS 32 + +typedef enum iotype_ { + POSIXIO, + HDF5 + /*NUM_TYPES*/ +} iotype; + +typedef enum vfdtype_ { + sec2, + stdio, + core, + split, + multi, + family, + direct + /*NUM_TYPES*/ +} vfdtype; + +typedef struct parameters_ { + iotype io_type; /* The type of IO test to perform */ + vfdtype vfd; + long num_files; /* Number of files to create */ + long num_dsets; /* Number of datasets to create */ + hsize_t num_bytes; /* Number of bytes in each dset */ + int num_iters; /* Number of times to loop doing the IO */ + int rank; /* Rank of dataset */ + hsize_t dset_size[MAX_DIMS]; /* Dataset size */ + size_t buf_size[MAX_DIMS]; /* Buffer size */ + size_t chk_size[MAX_DIMS]; /* Chunk size */ + int order[MAX_DIMS]; /* Buffer size */ + hsize_t h5_align; /* HDF5 object alignment */ + hsize_t h5_thresh; /* HDF5 object alignment threshold */ + int h5_use_chunks; /* Make HDF5 dataset chunked */ + int h5_extendable; /* Make HDF5 dataset chunked */ + int h5_write_only; /* Perform the write tests only */ + int verify; /* Verify data correctness */ + size_t page_size; + size_t page_buffer_size; +} parameters; + +typedef struct results_ { + herr_t ret_code; + io_time_t *timers; +} results; + +#ifndef SUCCESS +#define SUCCESS 0 +#endif /* !SUCCESS */ + +#ifndef FAIL +#define FAIL -1 +#endif /* !FAIL */ + +extern FILE * output; /* output file */ +extern io_time_t *timer_g; /* timer: global for stub functions */ +extern int sio_debug_level; /* The debug level: + * 0 - Off + * 1 - Minimal + * 2 - Some more + * 3 - Maximal + * 4 - Even More Debugging (timer stuff) + */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +extern void do_sio(parameters param, results *res); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SIO_PERF_H */ diff --git a/tools/src/h5repack/h5repack_copy.c b/tools/src/h5repack/h5repack_copy.c index 536de69..934b4d1 100644 --- a/tools/src/h5repack/h5repack_copy.c +++ b/tools/src/h5repack/h5repack_copy.c @@ -626,6 +626,7 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, pack_opt_t *opti hid_t wtype_id = H5I_INVALID_HID; /* read/write type ID */ hid_t ocpl_id = H5I_INVALID_HID; /* property to pass copy options */ hid_t lcpl_id = H5I_INVALID_HID; /* link creation property list */ + hid_t dxpl_id = H5I_INVALID_HID; /* dataset transfer property list */ named_dt_t * named_dt_head = NULL; /* Pointer to the stack of named datatypes copied */ size_t msize; /* size of type */ hsize_t nelmts; /* number of elements in dataset */ @@ -995,12 +996,27 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, pack_opt_t *opti if (need < H5TOOLS_MALLOCSIZE) buf = HDmalloc(need); + /* Set up collective write if using filters in parallel */ + { +#ifdef H5_HAVE_PARALLEL + hbool_t parallel = (H5FD_MPIO == H5Pget_driver(options->fout_fapl)); + + if (parallel && apply_s && apply_f) { + if ((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) + H5TOOLS_GOTO_ERROR((-1), "H5Pcreate failed"); + if (H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) < 0) + H5TOOLS_GOTO_ERROR((-1), "H5Pset_dxpl_mpio failed"); + } + else +#endif + dxpl_id = H5P_DEFAULT; + } + if (buf != NULL) { if (H5Dread(dset_in, wtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Dread failed"); - if (H5Dwrite(dset_out, wtype_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < - 0) + if (H5Dwrite(dset_out, wtype_id, H5S_ALL, H5S_ALL, dxpl_id, buf) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Dwrite failed"); /* Check if we have VL data in the dataset's @@ -1102,8 +1118,8 @@ do_copy_objects(hid_t fidin, hid_t fidout, trav_table_t *travt, pack_opt_t *opti if (H5Dread(dset_in, wtype_id, hslab_space, f_space_id, H5P_DEFAULT, hslab_buf) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Dread failed"); - if (H5Dwrite(dset_out, wtype_id, hslab_space, f_space_id, - H5P_DEFAULT, hslab_buf) < 0) + if (H5Dwrite(dset_out, wtype_id, hslab_space, f_space_id, dxpl_id, + hslab_buf) < 0) H5TOOLS_GOTO_ERROR((-1), "H5Dwrite failed"); /* reclaim any VL memory, if necessary */ @@ -1382,6 +1398,7 @@ done: H5Pclose(dcpl_in); H5Pclose(gcpl_in); H5Pclose(gcpl_out); + H5Pclose(dxpl_id); H5Sclose(f_space_id); H5Dclose(dset_in); H5Dclose(dset_out); diff --git a/tools/src/h5stat/h5stat.c b/tools/src/h5stat/h5stat.c index b884b7e..ea4e314 100644 --- a/tools/src/h5stat/h5stat.c +++ b/tools/src/h5stat/h5stat.c @@ -172,102 +172,19 @@ struct handler_t { static const char *s_opts = "Aa:Ddm:EFfhGgl:sSTO:Vw:H:"; /* e.g. "filemetadata" has to precede "file"; "groupmetadata" has to precede "group" etc. */ static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, - {"he", no_arg, 'h'}, {"filemetadata", no_arg, 'F'}, - {"filemetadat", no_arg, 'F'}, - {"filemetada", no_arg, 'F'}, - {"filemetad", no_arg, 'F'}, - {"filemeta", no_arg, 'F'}, - {"filemet", no_arg, 'F'}, - {"fileme", no_arg, 'F'}, - {"filem", no_arg, 'F'}, - {"file", no_arg, 'f'}, - {"fil", no_arg, 'f'}, - {"fi", no_arg, 'f'}, {"groupmetadata", no_arg, 'G'}, - {"groupmetadat", no_arg, 'G'}, - {"groupmetada", no_arg, 'G'}, - {"groupmetad", no_arg, 'G'}, - {"groupmeta", no_arg, 'G'}, - {"groupmet", no_arg, 'G'}, - {"groupme", no_arg, 'G'}, - {"groupm", no_arg, 'G'}, - {"group", no_arg, 'g'}, - {"grou", no_arg, 'g'}, - {"gro", no_arg, 'g'}, - {"gr", no_arg, 'g'}, {"links", require_arg, 'l'}, - {"link", require_arg, 'l'}, - {"lin", require_arg, 'l'}, - {"li", require_arg, 'l'}, {"dsetmetadata", no_arg, 'D'}, - {"dsetmetadat", no_arg, 'D'}, - {"dsetmetada", no_arg, 'D'}, - {"dsetmetad", no_arg, 'D'}, - {"dsetmeta", no_arg, 'D'}, - {"dsetmet", no_arg, 'D'}, - {"dsetme", no_arg, 'D'}, - {"dsetm", no_arg, 'D'}, - {"dset", no_arg, 'd'}, - {"dse", no_arg, 'd'}, - {"ds", no_arg, 'd'}, {"dims", require_arg, 'm'}, - {"dim", require_arg, 'm'}, - {"di", require_arg, 'm'}, {"dtypemetadata", no_arg, 'T'}, - {"dtypemetadat", no_arg, 'T'}, - {"dtypemetada", no_arg, 'T'}, - {"dtypemetad", no_arg, 'T'}, - {"dtypemeta", no_arg, 'T'}, - {"dtypemet", no_arg, 'T'}, - {"dtypeme", no_arg, 'T'}, - {"dtypem", no_arg, 'T'}, - {"dtype", no_arg, 'T'}, - {"dtyp", no_arg, 'T'}, - {"dty", no_arg, 'T'}, - {"dt", no_arg, 'T'}, {"object", require_arg, 'O'}, - {"objec", require_arg, 'O'}, - {"obje", require_arg, 'O'}, - {"obj", require_arg, 'O'}, - {"ob", require_arg, 'O'}, {"version", no_arg, 'V'}, - {"versio", no_arg, 'V'}, - {"versi", no_arg, 'V'}, - {"vers", no_arg, 'V'}, - {"ver", no_arg, 'V'}, - {"ve", no_arg, 'V'}, {"attribute", no_arg, 'A'}, - {"attribut", no_arg, 'A'}, - {"attribu", no_arg, 'A'}, - {"attrib", no_arg, 'A'}, - {"attri", no_arg, 'A'}, - {"attr", no_arg, 'A'}, - {"att", no_arg, 'A'}, - {"at", no_arg, 'A'}, {"enable-error-stack", no_arg, 'E'}, {"numattrs", require_arg, 'a'}, - {"numattr", require_arg, 'a'}, - {"numatt", require_arg, 'a'}, - {"numat", require_arg, 'a'}, - {"numa", require_arg, 'a'}, - {"num", require_arg, 'a'}, - {"nu", require_arg, 'a'}, {"freespace", no_arg, 's'}, - {"freespac", no_arg, 's'}, - {"freespa", no_arg, 's'}, - {"freesp", no_arg, 's'}, - {"frees", no_arg, 's'}, - {"free", no_arg, 's'}, - {"fre", no_arg, 's'}, - {"fr", no_arg, 's'}, {"summary", no_arg, 'S'}, - {"summar", no_arg, 'S'}, - {"summa", no_arg, 'S'}, - {"summ", no_arg, 'S'}, - {"sum", no_arg, 'S'}, - {"su", no_arg, 'S'}, {"s3-cred", require_arg, 'w'}, {"hdfs-attrs", require_arg, 'H'}, {NULL, 0, '\0'}}; diff --git a/tools/src/misc/h5clear.c b/tools/src/misc/h5clear.c index 524ad03..face2f0 100644 --- a/tools/src/misc/h5clear.c +++ b/tools/src/misc/h5clear.c @@ -32,7 +32,7 @@ #define H5F_ACS_SKIP_EOF_CHECK_NAME "skip_eof_check" /* Default increment is 1 megabytes for the --increment option */ -#define DEFAULT_INCREMENT 1024 * 1024 +#define DEFAULT_INCREMENT (1024 * 1024) static char * fname_g = NULL; static hbool_t clear_status_flags = FALSE; @@ -45,39 +45,10 @@ static hsize_t increment = DEFAULT_INCREMENT; * Command-line options: only publicize long options */ static const char * s_opts = "hVsmzi*"; -static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, - {"he", no_arg, 'h'}, - {"version", no_arg, 'V'}, - {"version", no_arg, 'V'}, - {"versio", no_arg, 'V'}, - {"versi", no_arg, 'V'}, - {"vers", no_arg, 'V'}, - {"status", no_arg, 's'}, - {"statu", no_arg, 's'}, - {"stat", no_arg, 's'}, - {"sta", no_arg, 's'}, - {"st", no_arg, 's'}, - {"image", no_arg, 'm'}, - {"imag", no_arg, 'm'}, - {"ima", no_arg, 'm'}, - {"im", no_arg, 'm'}, - {"filesize", no_arg, 'z'}, - {"filesiz", no_arg, 'z'}, - {"filesi", no_arg, 'z'}, - {"files", no_arg, 'z'}, - {"file", no_arg, 'z'}, - {"fil", no_arg, 'z'}, - {"fi", no_arg, 'z'}, - {"increment", optional_arg, 'i'}, - {"incremen", optional_arg, 'i'}, - {"increme", optional_arg, 'i'}, - {"increm", optional_arg, 'i'}, - {"incre", optional_arg, 'i'}, - {"incr", optional_arg, 'i'}, - {"inc", optional_arg, 'i'}, - {"in", optional_arg, 'i'}, - {NULL, 0, '\0'}}; +static struct h5_long_options l_opts[] = { + {"help", no_arg, 'h'}, {"version", no_arg, 'V'}, {"status", no_arg, 's'}, + {"image", no_arg, 'm'}, {"filesize", no_arg, 'z'}, {"increment", optional_arg, 'i'}, + {NULL, 0, '\0'}}; /*------------------------------------------------------------------------- * Function: usage diff --git a/tools/test/h5diff/CMakeTests.cmake b/tools/test/h5diff/CMakeTests.cmake index 5ada730..4fcfa26 100644 --- a/tools/test/h5diff/CMakeTests.cmake +++ b/tools/test/h5diff/CMakeTests.cmake @@ -376,40 +376,44 @@ macro (ADD_H5_TEST resultfile resultcode) if (HDF5_TEST_SERIAL) - # If using memchecker add tests without using scripts - if (HDF5_ENABLE_USING_MEMCHECKER) - add_test (NAME H5DIFF-${resultfile} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:h5diff${tgt_file_ext}> ${ARGN}) - set_tests_properties (H5DIFF-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") - if (${resultcode}) - set_tests_properties (H5DIFF-${resultfile} PROPERTIES WILL_FAIL "true") - endif () - if (last_test) - set_tests_properties (H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) - endif () - else () - add_test ( - NAME H5DIFF-${resultfile} - COMMAND "${CMAKE_COMMAND}" - -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" - -D "TEST_PROGRAM=$<TARGET_FILE:h5diff${tgt_file_ext}>" - -D "TEST_ARGS:STRING=${ARGN}" - -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles" - -D "TEST_OUTPUT=${resultfile}.out" - -D "TEST_EXPECT=${resultcode}" - -D "TEST_REFERENCE=${resultfile}.txt" - -D "TEST_APPEND=EXIT CODE:" - -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" - ) - if (last_test) - set_tests_properties (H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) - endif () - endif () + ADD_SH5_TEST (${resultfile} ${resultcode} ${ARGN}) endif () if (H5_HAVE_PARALLEL AND HDF5_TEST_PARALLEL) ADD_PH5_TEST (${resultfile} ${resultcode} ${ARGN}) endif () endmacro () + macro (ADD_SH5_TEST resultfile resultcode) + # If using memchecker add tests without using scripts + if (HDF5_ENABLE_USING_MEMCHECKER) + add_test (NAME H5DIFF-${resultfile} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:h5diff${tgt_file_ext}> ${ARGN}) + set_tests_properties (H5DIFF-${resultfile} PROPERTIES WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/testfiles") + if (${resultcode}) + set_tests_properties (H5DIFF-${resultfile} PROPERTIES WILL_FAIL "true") + endif () + if (last_test) + set_tests_properties (H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) + endif () + else () + add_test ( + NAME H5DIFF-${resultfile} + COMMAND "${CMAKE_COMMAND}" + -D "TEST_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR}" + -D "TEST_PROGRAM=$<TARGET_FILE:h5diff${tgt_file_ext}>" + -D "TEST_ARGS:STRING=${ARGN}" + -D "TEST_FOLDER=${PROJECT_BINARY_DIR}/testfiles" + -D "TEST_OUTPUT=${resultfile}.out" + -D "TEST_EXPECT=${resultcode}" + -D "TEST_REFERENCE=${resultfile}.txt" + -D "TEST_APPEND=EXIT CODE:" + -P "${HDF_RESOURCES_EXT_DIR}/runTest.cmake" + ) + if (last_test) + set_tests_properties (H5DIFF-${resultfile} PROPERTIES DEPENDS ${last_test}) + endif () + endif () + endmacro () + macro (ADD_PH5_TEST resultfile resultcode) # If using memchecker add tests without using scripts if (HDF5_ENABLE_USING_MEMCHECKER) @@ -1549,7 +1553,8 @@ ADD_H5_TEST (h5diff_801 1 -v ${FILE7} ${FILE8A} /g1/array /g1/array) # ############################################################################## # # dataset subsets # ############################################################################## -ADD_H5_TEST (h5diff_830 1 --enable-error-stack -v ${FILE7} ${FILE8} /g1/array3D[0,0,0;2,2,1;2,2,2;] /g1/array3D[0,0,0;2,2,1;2,2,2;]) +#serial only +ADD_SH5_TEST (h5diff_830 1 --enable-error-stack -v ${FILE7} ${FILE8} /g1/array3D[0,0,0;2,2,1;2,2,2;] /g1/array3D[0,0,0;2,2,1;2,2,2;]) # ############################################################################## # # VDS tests diff --git a/tools/test/h5dump/h5dumpgentest.c b/tools/test/h5dump/h5dumpgentest.c index 29922e8..e74054c 100644 --- a/tools/test/h5dump/h5dumpgentest.c +++ b/tools/test/h5dump/h5dumpgentest.c @@ -199,8 +199,8 @@ const H5L_class_t UD_link_class[1] = {{ #define DIM1 20 #define DIM2 10 -#define CDIM1 DIM1 / 2 -#define CDIM2 DIM2 / 2 +#define CDIM1 (DIM1 / 2) +#define CDIM2 (DIM2 / 2) #define RANK 2 /* Dataspace of 0 dimension size */ diff --git a/tools/test/h5jam/h5jamgentest.c b/tools/test/h5jam/h5jamgentest.c index 1da6b63..5632cc0 100644 --- a/tools/test/h5jam/h5jamgentest.c +++ b/tools/test/h5jam/h5jamgentest.c @@ -31,24 +31,7 @@ #define UBTXT3 "u511.txt" #define UBTXT4 "u512.txt" #define UBTXT5 "u513.txt" -/* not used yet -#define UBTXT6 "u1023.txt" -#define UBTXT7 "u1024.txt" -#define UBTXT8 "u1025.txt" -#define UBTXT9 "u2047.txt" -#define UBTXT10 "u2048.txt" -#define UBTXT11 "u2049.txt" -#define UBBIN1 "u0.dat" -#define UBBIN2 "u10.dat" -#define UBBIN3 "u511.dat" -#define UBBIN4 "u512.dat" -#define UBBIN5 "u513.dat" -*/ -/* not used yet -#define FILE1 "tnull.h5" -#define FILE2 "tnullwithub.h5" -*/ /* tall is same as dumper test */ #define FILE7 "tall.h5" #define FILE8 "twithub.h5" @@ -66,24 +49,13 @@ char pattern[11] = "abcdefghij"; #define BUF_SIZE 1024 -/* Element selection information */ - -typedef enum { RED, GREEN, BLUE, WHITE, BLACK } enumtype; - -/* Compound datatype */ -typedef struct s1_t { - unsigned int a; - unsigned int b; - float c; -} s1_t; - /* A UD link traversal function. Shouldn't actually be called. */ static hid_t UD_traverse(const char H5_ATTR_UNUSED *link_name, hid_t H5_ATTR_UNUSED cur_group, const void H5_ATTR_UNUSED *udata, size_t H5_ATTR_UNUSED udata_size, hid_t H5_ATTR_UNUSED lapl_id, hid_t H5_ATTR_UNUSED dxpl_id) { - return -1; + return H5I_INVALID_HID; } #define MY_LINKCLASS 187 @@ -115,261 +87,340 @@ g1.2.1 : slink g2 : dset2.1 dset2.2 udlink */ - -static void +static herr_t gent_ub(const char *filename, size_t ub_size, size_t ub_fill) { - hid_t fid, group, attr, dataset, space; - hid_t create_plist; + hid_t fid = H5I_INVALID_HID; + hid_t group = H5I_INVALID_HID; + hid_t attr = H5I_INVALID_HID; + hid_t dataset = H5I_INVALID_HID; + hid_t space = H5I_INVALID_HID; + hid_t create_plist = H5I_INVALID_HID; hsize_t dims[2]; int data[2][2], dset1[10][10], dset2[20]; char buf[BUF_SIZE]; int i, j; size_t u; float dset2_1[10], dset2_2[3][5]; - int fd; - char * bp; + int fd = -1; if (ub_size > 0) { - create_plist = H5Pcreate(H5P_FILE_CREATE); - H5Pset_userblock(create_plist, (hsize_t)ub_size); - fid = H5Fcreate(filename, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT); + if ((create_plist = H5Pcreate(H5P_FILE_CREATE)) < 0) + goto error; + if (H5Pset_userblock(create_plist, (hsize_t)ub_size) < 0) + goto error; + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, create_plist, H5P_DEFAULT)) < 0) + goto error; } else { - fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + if ((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; } - /* create groups */ - group = H5Gcreate2(fid, "/g1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); + /* Create groups */ + if ((group = H5Gcreate2(fid, "/g1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; - group = H5Gcreate2(fid, "/g2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); + if ((group = H5Gcreate2(fid, "/g2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; - group = H5Gcreate2(fid, "/g1/g1.1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); + if ((group = H5Gcreate2(fid, "/g1/g1.1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; - group = H5Gcreate2(fid, "/g1/g1.2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); + if ((group = H5Gcreate2(fid, "/g1/g1.2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; - group = H5Gcreate2(fid, "/g1/g1.2/g1.2.1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); + if ((group = H5Gcreate2(fid, "/g1/g1.2/g1.2.1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; - /* root attributes */ - group = H5Gopen2(fid, "/", H5P_DEFAULT); + /* Root attributes */ + if ((group = H5Gopen2(fid, "/", H5P_DEFAULT)) < 0) + goto error; dims[0] = 10; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate2(group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT); - HDsprintf(buf, "abcdefghi"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); - - dims[0] = 2; - dims[1] = 2; - space = H5Screate_simple(2, dims, NULL); - attr = H5Acreate2(group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT); + if ((space = H5Screate_simple(1, dims, NULL)) < 0) + goto error; + if ((attr = H5Acreate2(group, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (HDsprintf(buf, "abcdefghi") < 0) + goto error; + if (H5Awrite(attr, H5T_NATIVE_SCHAR, buf) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Aclose(attr) < 0) + goto error; + + dims[0] = 2; + dims[1] = 2; + if ((space = H5Screate_simple(2, dims, NULL)) < 0) + goto error; + if ((attr = H5Acreate2(group, "attr2", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; data[0][0] = 0; data[0][1] = 1; data[1][0] = 2; data[1][1] = 3; - H5Awrite(attr, H5T_NATIVE_INT, data); - H5Sclose(space); - H5Aclose(attr); + if (H5Awrite(attr, H5T_NATIVE_INT, data) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Aclose(attr) < 0) + goto error; - H5Gclose(group); + if (H5Gclose(group) < 0) + goto error; - group = H5Gopen2(fid, "/g1/g1.1", H5P_DEFAULT); + if ((group = H5Gopen2(fid, "/g1/g1.1", H5P_DEFAULT)) < 0) + goto error; - /* dset1.1.1 */ + /* Dataset 1.1.1 */ dims[0] = 10; dims[1] = 10; - space = H5Screate_simple(2, dims, NULL); - dataset = H5Dcreate2(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if ((space = H5Screate_simple(2, dims, NULL)) < 0) + goto error; + if ((dataset = + H5Dcreate2(group, "dset1.1.1", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; for (i = 0; i < 10; i++) for (j = 0; j < 10; j++) dset1[i][j] = j * i; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1); - H5Sclose(space); + if (H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset1) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; - /* attributes of dset1.1.1 */ + /* Attributes of dset1.1.1 */ dims[0] = 27; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate2(dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT); - HDsprintf(buf, "1st attribute of dset1.1.1"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); + if ((space = H5Screate_simple(1, dims, NULL)) < 0) + goto error; + if ((attr = H5Acreate2(dataset, "attr1", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (HDsprintf(buf, "1st attribute of dset1.1.1") < 0) + goto error; + if (H5Awrite(attr, H5T_NATIVE_SCHAR, buf) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Aclose(attr) < 0) + goto error; dims[0] = 27; - space = H5Screate_simple(1, dims, NULL); - attr = H5Acreate2(dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT); - HDsprintf(buf, "2nd attribute of dset1.1.1"); - H5Awrite(attr, H5T_NATIVE_SCHAR, buf); - H5Sclose(space); - H5Aclose(attr); - - H5Dclose(dataset); - - /* dset1.1.2 */ + if ((space = H5Screate_simple(1, dims, NULL)) < 0) + goto error; + if ((attr = H5Acreate2(dataset, "attr2", H5T_STD_I8BE, space, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; + if (HDsprintf(buf, "2nd attribute of dset1.1.1") < 0) + goto error; + if (H5Awrite(attr, H5T_NATIVE_SCHAR, buf) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Aclose(attr) < 0) + goto error; + + if (H5Dclose(dataset) < 0) + goto error; + + /* Dataset 1.1.2 */ dims[0] = 20; - space = H5Screate_simple(1, dims, NULL); - dataset = H5Dcreate2(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if ((space = H5Screate_simple(1, dims, NULL)) < 0) + goto error; + if ((dataset = + H5Dcreate2(group, "dset1.1.2", H5T_STD_I32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; for (i = 0; i < 20; i++) dset2[i] = i; - H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2); - H5Sclose(space); - H5Dclose(dataset); - - H5Gclose(group); - - /* external link */ - H5Lcreate_external("somefile", "somepath", fid, "/g1/g1.2/extlink", H5P_DEFAULT, H5P_DEFAULT); - - /* soft link */ - group = H5Gopen2(fid, "/g1/g1.2/g1.2.1", H5P_DEFAULT); - H5Lcreate_soft("somevalue", group, "slink", H5P_DEFAULT, H5P_DEFAULT); - H5Gclose(group); - - group = H5Gopen2(fid, "/g2", H5P_DEFAULT); - - /* dset2.1 */ + if (H5Dwrite(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Dclose(dataset) < 0) + goto error; + + if (H5Gclose(group) < 0) + goto error; + + /* External link */ + if (H5Lcreate_external("somefile", "somepath", fid, "/g1/g1.2/extlink", H5P_DEFAULT, H5P_DEFAULT) < 0) + goto error; + + /* Soft link */ + if ((group = H5Gopen2(fid, "/g1/g1.2/g1.2.1", H5P_DEFAULT)) < 0) + goto error; + if (H5Lcreate_soft("somevalue", group, "slink", H5P_DEFAULT, H5P_DEFAULT) < 0) + goto error; + if (H5Gclose(group) < 0) + goto error; + + if ((group = H5Gopen2(fid, "/g2", H5P_DEFAULT)) < 0) + goto error; + + /* Dataset 2.1 */ dims[0] = 10; - space = H5Screate_simple(1, dims, NULL); - dataset = H5Dcreate2(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if ((space = H5Screate_simple(1, dims, NULL)) < 0) + goto error; + if ((dataset = + H5Dcreate2(group, "dset2.1", H5T_IEEE_F32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; for (i = 0; i < 10; i++) dset2_1[i] = (float)((float)i * 0.1F + 1.0F); - H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1); - H5Sclose(space); - H5Dclose(dataset); - - /* dset2.2 */ + if (H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_1) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Dclose(dataset) < 0) + goto error; + + /* Dataset 2.2 */ dims[0] = 3; dims[1] = 5; - space = H5Screate_simple(2, dims, NULL); - dataset = H5Dcreate2(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if ((space = H5Screate_simple(2, dims, NULL)) < 0) + goto error; + if ((dataset = + H5Dcreate2(group, "dset2.2", H5T_IEEE_F32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + goto error; for (i = 0; i < 3; i++) for (j = 0; j < 5; j++) dset2_2[i][j] = (float)(((float)i + 1.0F) * (float)j * 0.1F); - H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2); - H5Sclose(space); - H5Dclose(dataset); - - H5Gclose(group); - - /* user-defined link */ - H5Lregister(UD_link_class); - H5Lcreate_ud(fid, "/g2/udlink", (H5L_type_t)MY_LINKCLASS, NULL, (size_t)0, H5P_DEFAULT, H5P_DEFAULT); - - H5Fclose(fid); + if (H5Dwrite(dataset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, dset2_2) < 0) + goto error; + if (H5Sclose(space) < 0) + goto error; + if (H5Dclose(dataset) < 0) + goto error; + + if (H5Gclose(group) < 0) + goto error; + + /* User-defined link */ + if (H5Lregister(UD_link_class) < 0) + goto error; + if (H5Lcreate_ud(fid, "/g2/udlink", (H5L_type_t)MY_LINKCLASS, NULL, (size_t)0, H5P_DEFAULT, H5P_DEFAULT) < + 0) + goto error; + + /* MUST close the file ID before the user block code or you risk tripping + * over file locking issues. + */ + if (H5Fclose(fid) < 0) + goto error; /* If a user block is being used, write to it here */ if (ub_size > 0) { - HDassert(ub_size <= BUF_SIZE); + char *bp; - fd = HDopen(filename, O_RDWR); - HDassert(fd >= 0); + if (ub_size > BUF_SIZE) + goto error; - /* fill buf with pattern */ + if ((fd = HDopen(filename, O_RDWR)) < 0) + goto error; + + /* Fill buf with pattern */ HDmemset(buf, '\0', ub_size); bp = buf; for (u = 0; u < ub_fill; u++) *bp++ = pattern[u % 10]; - (void)HDwrite(fd, buf, ub_size); + if (HDwrite(fd, buf, ub_size) < 0) + goto error; + + if (HDclose(fd) < 0) + goto error; + } + return SUCCEED; + +error: + if (fd >= 0) HDclose(fd); + + H5E_BEGIN_TRY + { + H5Fclose(fid); + H5Gclose(group); + H5Aclose(attr); + H5Dclose(dataset); + H5Sclose(space); + H5Pclose(create_plist); } + H5E_END_TRY; + + return FAIL; } -static void +/* Creates a simple (i.e., not HDF5) text file and fills it with a pattern */ +static herr_t create_textfile(const char *name, size_t size) { - char * buf; - int fd; + char * buf = NULL; + int fd = -1; size_t i; - char * bp; + char * bp = NULL; - fd = HDcreat(name, 0777); - HDassert(fd >= 0); - buf = (char *)HDcalloc(size, (size_t)1); - HDassert(buf); + if ((fd = HDcreat(name, 0777)) < 0) + goto error; + if (NULL == (buf = (char *)HDcalloc(size, 1))) + goto error; - /* fill buf with pattern */ + /* Fill buf with pattern */ bp = buf; for (i = 0; i < size; i++) *bp++ = pattern[i % 10]; - (void)HDwrite(fd, buf, size); + if (HDwrite(fd, buf, size) < 0) + goto error; HDfree(buf); - HDclose(fd); -} - -#ifdef notdef -/* not used yet */ -void -create_binfile(char *name, off_t size) -{ - char *buf; - int fd; - int i; - char *bp; - fd = creat(name, 0777); - HDassert(fd >= 0); + return SUCCEED; - buf = HDcalloc(size, 1); - HDassert(buf); - - /* fill buf with pattern */ - bp = buf; - for (i = 0; i < size; i++) - *bp++ = (char)i & 0xff; - - (void)HDwrite(fd, buf, size); +error: + HDfree(buf); + if (fd >= 0) + HDclose(fd); - HDclose(fd); + return FAIL; } -#endif /*------------------------------------------------------------------------- * Function: main * *------------------------------------------------------------------------- */ - int main(void) { - - /* - create_textfile(UBTXT1, (size_t)0); - */ - create_textfile(UBTXT2, (size_t)10); - create_textfile(UBTXT3, (size_t)511); - create_textfile(UBTXT4, (size_t)512); - create_textfile(UBTXT5, (size_t)513); - /* - create_textfile(UBTXT6, (size_t)1023); - create_textfile(UBTXT7, (size_t)1024); - create_textfile(UBTXT8, (size_t)1025); - create_textfile(UBTXT9, (size_t)2047); - create_textfile(UBTXT10, (size_t)2048); - create_textfile(UBTXT11, (size_t)2049); - - create_binfile(UBBIN1, (off_t)0); - create_binfile(UBBIN2, (off_t)10); - create_binfile(UBBIN3, (off_t)511); - create_binfile(UBBIN4, (off_t)512); - create_binfile(UBBIN5, (off_t)513); - - */ - gent_ub(FILE7, (size_t)0, (size_t)0); - gent_ub(FILE8, (size_t)512, HDstrlen(pattern)); - gent_ub(FILE9, (size_t)1024, (size_t)513); - - return 0; + if (create_textfile(UBTXT2, 10) < 0) + goto error; + if (create_textfile(UBTXT3, 511) < 0) + goto error; + if (create_textfile(UBTXT4, 512) < 0) + goto error; + if (create_textfile(UBTXT5, 513) < 0) + goto error; + + if (gent_ub(FILE7, 0, 0) < 0) + goto error; + if (gent_ub(FILE8, 512, HDstrlen(pattern)) < 0) + goto error; + if (gent_ub(FILE9, 1024, 513) < 0) + goto error; + + return EXIT_SUCCESS; + +error: + HDfprintf(stderr, "h5jam test generator FAILED\n"); + return EXIT_FAILURE; } diff --git a/tools/test/h5repack/h5repacktst.c b/tools/test/h5repack/h5repacktst.c index acad74e..b62fa53 100644 --- a/tools/test/h5repack/h5repacktst.c +++ b/tools/test/h5repack/h5repacktst.c @@ -111,8 +111,8 @@ const char *H5REPACK_FILENAMES[] = {"h5repack_big_out", NULL}; #define DIM1 40 #define DIM2 20 -#define CDIM1 DIM1 / 2 -#define CDIM2 DIM2 / 2 +#define CDIM1 (DIM1 / 2) +#define CDIM2 (DIM2 / 2) #define RANK 2 /* Size of userblock (for userblock test) */ diff --git a/tools/test/h5stat/CMakeTests.cmake b/tools/test/h5stat/CMakeTests.cmake index 79de6b9..d4238b5 100644 --- a/tools/test/h5stat/CMakeTests.cmake +++ b/tools/test/h5stat/CMakeTests.cmake @@ -207,7 +207,7 @@ # -d --di=15 ADD_H5_ERR_TEST (h5stat_err1_dims 1 -d --dims=-1 h5stat_threshold.h5) ADD_H5_TEST (h5stat_dims1 0 -gd -m 5 h5stat_threshold.h5) - ADD_H5_TEST (h5stat_dims2 0 -d --di=15 h5stat_threshold.h5) + ADD_H5_TEST (h5stat_dims2 0 -d --dims=15 h5stat_threshold.h5) # # Tests for -a option on h5stat_threshold.h5 # -a -2 (incorrect threshold value) diff --git a/tools/test/h5stat/h5stat_gentest.c b/tools/test/h5stat/h5stat_gentest.c index a9813e7..c775d6a 100644 --- a/tools/test/h5stat/h5stat_gentest.c +++ b/tools/test/h5stat/h5stat_gentest.c @@ -51,7 +51,7 @@ * Generate HDF5 file with latest format with * NUM_GRPS groups and NUM_ATTRS attributes for the dataset */ -static void +static herr_t gen_newgrat_file(const char *fname) { hid_t fcpl = H5I_INVALID_HID; /* File creation property */ @@ -117,6 +117,21 @@ gen_newgrat_file(const char *fname) } /* end for */ /* Close dataset, dataspace, datatype, file */ + if (H5Pclose(fapl) < 0) + goto error; + if (H5Pclose(fcpl) < 0) + goto error; + if (H5Dclose(did) < 0) + goto error; + if (H5Tclose(tid) < 0) + goto error; + if (H5Sclose(sid) < 0) + goto error; + if (H5Fclose(fid) < 0) + goto error; + + return SUCCEED; + error: H5E_BEGIN_TRY { @@ -130,6 +145,8 @@ error: H5Fclose(fid); } H5E_END_TRY; + + return FAIL; } /* gen_newgrat_file() */ /* @@ -139,7 +156,7 @@ error: * datasets. -a N (--numattrs=N): Set the threshold for the # of attributes when printing information for * small # of attributes. */ -static void +static herr_t gen_threshold_file(const char *fname) { hid_t fid = H5I_INVALID_HID; /* File ID */ @@ -302,6 +319,23 @@ gen_threshold_file(const char *fname) goto error; } + if (H5Gclose(gid) < 0) + goto error; + if (H5Sclose(sid0) < 0) + goto error; + if (H5Sclose(sid1) < 0) + goto error; + if (H5Sclose(sid2) < 0) + goto error; + if (H5Sclose(sid3) < 0) + goto error; + if (H5Sclose(sid4) < 0) + goto error; + if (H5Fclose(fid) < 0) + goto error; + + return SUCCEED; + error: H5E_BEGIN_TRY { @@ -317,6 +351,8 @@ error: } H5E_END_TRY; + return FAIL; + } /* gen_threshold_file() */ /* @@ -327,18 +363,21 @@ error: * one dataset: fixed dimension, chunked layout, w/ filters * */ -static void +static herr_t gen_idx_file(const char *fname) { - hid_t fapl = H5I_INVALID_HID; /* file access property id */ - hid_t fid = H5I_INVALID_HID; /* file id */ - hid_t sid = H5I_INVALID_HID; /* space id */ - hid_t dcpl = H5I_INVALID_HID; /* dataset creation property id */ - hid_t did = -1, did2 = H5I_INVALID_HID; /* dataset id */ - hsize_t dims[1] = {10}; /* dataset dimension */ - hsize_t c_dims[1] = {2}; /* chunk dimension */ - int i; /* local index variable */ - int buf[10]; /* data buffer */ + hid_t fapl = H5I_INVALID_HID; /* file access property id */ + hid_t fid = H5I_INVALID_HID; /* file id */ + hid_t sid = H5I_INVALID_HID; /* space id */ + hid_t dcpl = H5I_INVALID_HID; /* dataset creation property id */ + hid_t did = H5I_INVALID_HID; /* dataset id */ +#if defined(H5_HAVE_FILTER_DEFLATE) + hid_t did2 = H5I_INVALID_HID; /* dataset id (compressed) */ +#endif + hsize_t dims[1] = {10}; /* dataset dimension */ + hsize_t c_dims[1] = {2}; /* chunk dimension */ + int i; /* local index variable */ + int buf[10]; /* data buffer */ /* Get a copy of the file access property */ if ((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) @@ -390,6 +429,19 @@ gen_idx_file(const char *fname) #endif /* closing: dataspace, dataset, file */ + if (H5Pclose(fapl) < 0) + goto error; + if (H5Pclose(dcpl) < 0) + goto error; + if (H5Sclose(sid) < 0) + goto error; + if (H5Dclose(did) < 0) + goto error; + if (H5Fclose(fid) < 0) + goto error; + + return SUCCEED; + error: H5E_BEGIN_TRY { @@ -404,6 +456,8 @@ error: } H5E_END_TRY; + return FAIL; + } /* gen_idx_file() */ /* @@ -419,20 +473,21 @@ error: * H5O_refcount_decode in the jira issue. * */ -static void +static herr_t gen_err_refcount(const char *fname) { - hid_t fid = H5I_INVALID_HID; /* File identifier */ - hid_t sid = H5I_INVALID_HID; /* Dataspace message */ - hid_t did = H5I_INVALID_HID; /* Dataset identifier */ - hid_t gid = H5I_INVALID_HID; /* Group identifier */ - hid_t aid1 = -1, aid2 = H5I_INVALID_HID; /* Attribute identifier */ - hid_t tid = H5I_INVALID_HID; /* Datatype identifier */ - int i, n; /* Local index variables */ - int buf[10]; /* Data buffer */ - hsize_t dims[1]; /* Dimension size */ - int fd = -1; /* File descriptor */ - unsigned short val = 22; /* The refcount message ID */ + hid_t fid = H5I_INVALID_HID; /* File identifier */ + hid_t sid = H5I_INVALID_HID; /* Dataspace message */ + hid_t did = H5I_INVALID_HID; /* Dataset identifier */ + hid_t gid = H5I_INVALID_HID; /* Group identifier */ + hid_t aid1 = H5I_INVALID_HID; /* Attribute identifier */ + hid_t aid2 = H5I_INVALID_HID; /* Attribute identifier */ + hid_t tid = H5I_INVALID_HID; /* Datatype identifier */ + int i, n; /* Local index variables */ + int buf[10]; /* Data buffer */ + hsize_t dims[1]; /* Dimension size */ + int fd = -1; /* File descriptor */ + unsigned short val = 22; /* The refcount message ID */ /* Initialize data buffer */ n = 0; @@ -485,6 +540,10 @@ gen_err_refcount(const char *fname) goto error; if (H5Tclose(tid) < 0) goto error; + + /* Be sure to close this before opening the file again via open(), below, + * or you'll possibly trip over the file locking. + */ if (H5Fclose(fid) < 0) goto error; @@ -495,11 +554,16 @@ gen_err_refcount(const char *fname) with the committed datatype */ /* 24: the offset in the object header containing the version of the attribute message */ - if ((fd = HDopen(fname, O_RDWR, 0633)) >= 0) { - HDlseek(fd, 4520 + 24, SEEK_SET); - (void)HDwrite(fd, &val, 2); - HDclose(fd); - } + if ((fd = HDopen(fname, O_RDWR, 0633)) < 0) + goto error; + if (HDlseek(fd, 4520 + 24, SEEK_SET) < 0) + goto error; + if (HDwrite(fd, &val, 2) < 0) + goto error; + if (HDclose(fd) < 0) + goto error; + + return SUCCEED; error: H5E_BEGIN_TRY @@ -513,6 +577,11 @@ error: H5Fclose(fid); } H5E_END_TRY; + + if (fd >= 0) + HDclose(fd); + + return FAIL; } /* gen_err_refcount() */ /* @@ -542,14 +611,22 @@ error: int main(void) { - gen_newgrat_file(NEWGRAT_FILE); - gen_threshold_file(THRESHOLD_FILE); + if (gen_newgrat_file(NEWGRAT_FILE) < 0) + goto error; + if (gen_threshold_file(THRESHOLD_FILE) < 0) + goto error; /* Generate an HDF file to test for datasets with Fixed Array indexing */ - gen_idx_file(IDX_FILE); + if (gen_idx_file(IDX_FILE) < 0) + goto error; /* Generate a file with a refcount message ID */ - gen_err_refcount(ERR_REFCOUNT_FILE); + if (gen_err_refcount(ERR_REFCOUNT_FILE) < 0) + goto error; + + return EXIT_SUCCESS; - return 0; +error: + HDfprintf(stderr, "h5stat test generator FAILED\n"); + return EXIT_FAILURE; } diff --git a/tools/test/h5stat/testh5stat.sh.in b/tools/test/h5stat/testh5stat.sh.in index 470c381..647f06a 100644 --- a/tools/test/h5stat/testh5stat.sh.in +++ b/tools/test/h5stat/testh5stat.sh.in @@ -304,7 +304,7 @@ TOOLTEST h5stat_links5.ddl -g -l 40000 h5stat_newgrat.h5 # -d --di=15 TOOLTEST h5stat_err1_dims.ddl -d --dims=-1 h5stat_threshold.h5 TOOLTEST h5stat_dims1.ddl -gd -m 5 h5stat_threshold.h5 -TOOLTEST h5stat_dims2.ddl -d --di=15 h5stat_threshold.h5 +TOOLTEST h5stat_dims2.ddl -d --dims=15 h5stat_threshold.h5 # # Tests for -a option on h5stat_threshold.h5 # -a -2 (incorrect threshold value) diff --git a/tools/test/misc/CMakeTestsClear.cmake b/tools/test/misc/CMakeTestsClear.cmake index ec24a61..198a363 100644 --- a/tools/test/misc/CMakeTestsClear.cmake +++ b/tools/test/misc/CMakeTestsClear.cmake @@ -397,7 +397,7 @@ # # The following are tests to verify the expected exit code from h5clear: # "h5clear -m h5clear_mdc_image.h5" (valid option, existing file, succeed exit code) -# "h5clear --vers" (valid option, version #, succeed exit code) +# "h5clear --version" (valid option, version #, succeed exit code) # "h5clear -k" (invalid 1 option, no file, fail exit code) # "h5clear -k junk.h5" (invalid 1 option, nonexisting file, fail exit code) # "h5clear -l h5clear_sec2_v2.h5" (invalid 1 option, existing file, fail exit code) @@ -408,7 +408,7 @@ # "h5clear -m -l h5clear_sec2_v0.h5" (valid/invalid 2 options, existing file, fail exit code) # "h5clear -l -m h5clear_sec2_v0.h5" (invalid/valid 2 options, existing file, fail exit code) ADD_H5_RETTEST (h5clr_mdc_image "false" "-m" h5clear_mdc_image.h5) - ADD_H5_RETTEST (h5clr_vers "false" "--vers") + ADD_H5_RETTEST (h5clr_vers "false" "--version") ADD_H5_RETTEST (h5clr_k "true" "-k") ADD_H5_RETTEST (h5clr_k_junk "true" "-k" junk.h5) ADD_H5_RETTEST (h5clr_l_sec2 "true" "-l" h5clear_sec2_v2.h5) diff --git a/tools/test/misc/testh5clear.sh.in b/tools/test/misc/testh5clear.sh.in index c05e43d..a01fa4a 100644 --- a/tools/test/misc/testh5clear.sh.in +++ b/tools/test/misc/testh5clear.sh.in @@ -315,7 +315,7 @@ TOOLTEST_ERR orig_h5clear_sec2_v0.h5 -s -m "" h5clear_no_mdc_image.err # # The following are tests to verify the expected exit code from h5clear: # "h5clear -m h5clear_mdc_image.h5" (valid option, existing file, succeed exit code) -# "h5clear --vers" (valid option, version #, succeed exit code) +# "h5clear --version" (valid option, version #, succeed exit code) # "h5clear -k" (invalid 1 option, no file, fail exit code) # "h5clear -k junk.h5" (invalid 1 option, nonexisting file, fail exit code) # "h5clear -l h5clear_sec2_v2.h5" (invalid 1 option, existing file, fail exit code) @@ -326,7 +326,7 @@ TOOLTEST_ERR orig_h5clear_sec2_v0.h5 -s -m "" h5clear_no_mdc_image.err # "h5clear -m -l h5clear_sec2_v0.h5" (valid/invalid 2 options, existing file, fail exit code) # "h5clear -l -m h5clear_sec2_v0.h5" (invalid/valid 2 options, existing file, fail exit code) TOOLTEST h5clear_mdc_image.h5 -m "" $SUCCEED -TOOLTEST "" --vers "" $SUCCEED +TOOLTEST "" --version "" $SUCCEED TOOLTEST "" -k "" $FAIL TOOLTEST junk.h5 -k "" $FAIL TOOLTEST h5clear_sec2_v2.h5 -l "" $FAIL diff --git a/tools/test/perform/CMakeLists.txt b/tools/test/perform/CMakeLists.txt index 7399723..7bf79c5 100644 --- a/tools/test/perform/CMakeLists.txt +++ b/tools/test/perform/CMakeLists.txt @@ -4,39 +4,17 @@ project (HDF5_TOOLS_TEST_PERFORM C) # -------------------------------------------------------------------- # Add the executables # -------------------------------------------------------------------- -#-- Adding test for h5perf_serial -set (h5perf_serial_SOURCES - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/sio_perf.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/sio_engine.c -) -add_executable (h5perf_serial ${h5perf_serial_SOURCES}) -target_include_directories (h5perf_serial PRIVATE "${HDF5_TEST_SRC_DIR};${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") -if (NOT BUILD_SHARED_LIBS) - TARGET_C_PROPERTIES (h5perf_serial STATIC) - target_link_libraries (h5perf_serial PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_LIB_TARGET}) -else () - TARGET_C_PROPERTIES (h5perf_serial SHARED) - target_link_libraries (h5perf_serial PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) -endif () -set_target_properties (h5perf_serial PROPERTIES FOLDER perform) - -#----------------------------------------------------------------------------- -# Add Target to clang-format -#----------------------------------------------------------------------------- -if (HDF5_ENABLE_FORMATTERS) - clang_format (HDF5_TOOLS_TEST_PERFORM_h5perf_serial_FORMAT h5perf_serial) -endif () if (HDF5_BUILD_PERFORM_STANDALONE) #-- Adding test for h5perf_serial_alone - io_timer.c includes set (h5perf_serial_alone_SOURCES ${HDF5_TOOLS_DIR}/lib/io_timer.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/sio_perf.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/sio_engine.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/sio_perf.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/sio_engine.c ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/sio_standalone.c ) add_executable (h5perf_serial_alone ${h5perf_serial_alone_SOURCES}) - target_include_directories (h5perf_serial_alone PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};${HDF5_TOOLS_DIR}/lib;$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") + target_include_directories (h5perf_serial_alone PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};${HDF5_TOOLS_DIR}/lib;${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR};${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") if (NOT BUILD_SHARED_LIBS) TARGET_C_PROPERTIES (h5perf_serial_alone STATIC) target_link_libraries (h5perf_serial_alone PRIVATE ${HDF5_LIB_TARGET} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") @@ -188,63 +166,16 @@ if (HDF5_ENABLE_FORMATTERS) endif () if (H5_HAVE_PARALLEL AND HDF5_TEST_PARALLEL) - if (UNIX) - #-- Adding test for perf - only on unix systems - set (perf_SOURCES - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/perf.c - ) - add_executable (perf ${perf_SOURCES}) - target_include_directories (perf PRIVATE "${HDF5_TEST_SRC_DIR};${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") - if (NOT BUILD_SHARED_LIBS) - TARGET_C_PROPERTIES (perf STATIC) - target_link_libraries (perf PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_TEST_LIB_TARGET} ${HDF5_LIB_TARGET}) - else () - TARGET_C_PROPERTIES (perf SHARED) - target_link_libraries (perf PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_TEST_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) - endif () - set_target_properties (perf PROPERTIES FOLDER perform) - - #----------------------------------------------------------------------------- - # Add Target to clang-format - #----------------------------------------------------------------------------- - if (HDF5_ENABLE_FORMATTERS) - clang_format (HDF5_TOOLS_TEST_PERFORM_perf_FORMAT perf) - endif () - endif () - - #-- Adding test for h5perf - set (h5perf_SOURCES - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/pio_perf.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/pio_engine.c - ) - add_executable (h5perf ${h5perf_SOURCES}) - target_include_directories (h5perf PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") - if (NOT BUILD_SHARED_LIBS) - TARGET_C_PROPERTIES (h5perf STATIC) - target_link_libraries (h5perf PRIVATE ${HDF5_TOOLS_LIB_TARGET} ${HDF5_TEST_LIB_TARGET} ${HDF5_LIB_TARGET}) - else () - TARGET_C_PROPERTIES (h5perf SHARED) - target_link_libraries (h5perf PRIVATE ${HDF5_TOOLS_LIBSH_TARGET} ${HDF5_TEST_LIBSH_TARGET} ${HDF5_LIBSH_TARGET}) - endif () - set_target_properties (h5perf PROPERTIES FOLDER perform) - - #----------------------------------------------------------------------------- - # Add Target to clang-format - #----------------------------------------------------------------------------- - if (HDF5_ENABLE_FORMATTERS) - clang_format (HDF5_TOOLS_TEST_PERFORM_h5perf_FORMAT h5perf) - endif () - if (HDF5_BUILD_PERFORM_STANDALONE) #-- Adding test for h5perf set (h5perf_alone_SOURCES ${HDF5_TOOLS_DIR}/lib/io_timer.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/pio_perf.c - ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/pio_engine.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/pio_perf.c + ${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR}/pio_engine.c ${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR}/pio_standalone.c ) add_executable (h5perf_alone ${h5perf_alone_SOURCES}) - target_include_directories (h5perf_alone PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};${HDF5_TOOLS_DIR}/lib;$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") + target_include_directories (h5perf_alone PRIVATE "${HDF5_SRC_DIR};${HDF5_SRC_BINARY_DIR};${HDF5_TOOLS_DIR}/lib;${HDF5_TOOLS_SRC_H5PERF_SOURCE_DIR};${HDF5_TOOLS_TEST_PERFORM_SOURCE_DIR};$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_INCLUDE_DIRS}>") if (NOT BUILD_SHARED_LIBS) TARGET_C_PROPERTIES (h5perf_alone STATIC) target_link_libraries (h5perf_alone PRIVATE ${HDF5_LIB_TARGET} ${LINK_LIBS} "$<$<BOOL:${HDF5_ENABLE_PARALLEL}>:${MPI_C_LIBRARIES}>") diff --git a/tools/test/perform/Makefile.am b/tools/test/perform/Makefile.am index 244ef3a..10b13fe 100644 --- a/tools/test/perform/Makefile.am +++ b/tools/test/perform/Makefile.am @@ -21,17 +21,6 @@ include $(top_srcdir)/config/commence.am AM_CPPFLAGS+=-I$(top_srcdir)/src -I$(top_srcdir)/test -I$(top_srcdir)/tools/lib -# bin_PROGRAMS will be installed. -if BUILD_PARALLEL_CONDITIONAL - bin_PROGRAMS=h5perf_serial h5perf -else - bin_PROGRAMS=h5perf_serial -endif - -# Add h5perf and h5perf_serial specific linker flags here -h5perf_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) -h5perf_serial_LDFLAGS = $(LT_STATIC_EXEC) $(AM_LDFLAGS) - # Some programs are not built or run by default, but can be built by hand or by # specifying --enable-build-all at configure time. # Also, some of these programs should only be built in parallel. @@ -47,18 +36,15 @@ endif # List them in the order they should be run. # Parallel test programs. if BUILD_PARALLEL_CONDITIONAL - TEST_PROG_PARA=h5perf perf + TEST_PROG_PARA= endif # Serial test programs. -TEST_PROG = iopipe chunk chunk_cache overhead zip_perf perf_meta h5perf_serial $(BUILD_ALL_PROGS) +TEST_PROG = iopipe chunk chunk_cache overhead zip_perf perf_meta $(BUILD_ALL_PROGS) # check_PROGRAMS will be built but not installed. Do not any executable # that is in bin_PROGRAMS already. Otherwise, it will be removed twice in # "make clean" and some systems, e.g., AIX, do not like it. -check_PROGRAMS= iopipe chunk chunk_cache overhead zip_perf perf_meta $(BUILD_ALL_PROGS) perf - -h5perf_SOURCES=pio_perf.c pio_engine.c -h5perf_serial_SOURCES=sio_perf.c sio_engine.c +check_PROGRAMS= $(TEST_PROG) $(BUILD_ALL_PROGS) # These are the files that `make clean' (and derivatives) will remove from # this directory. @@ -67,9 +53,6 @@ CLEANFILES=*.h5 *.raw *.dat x-gnuplot perftest.out # All of the programs depend on the main hdf5 library, and some of them # depend on test or tools library. LDADD=$(LIBHDF5) -h5perf_LDADD=$(LIBH5TOOLS) $(LIBH5TEST) $(LIBHDF5) -h5perf_serial_LDADD=$(LIBH5TOOLS) $(LIBH5TEST) $(LIBHDF5) -perf_LDADD=$(LIBH5TEST) $(LIBHDF5) iopipe_LDADD=$(LIBH5TEST) $(LIBHDF5) zip_perf_LDADD=$(LIBH5TOOLS) $(LIBH5TEST) $(LIBHDF5) perf_meta_LDADD=$(LIBH5TEST) $(LIBHDF5) diff --git a/tools/test/perform/chunk_cache.c b/tools/test/perform/chunk_cache.c index 25fa34c..b515961 100644 --- a/tools/test/perform/chunk_cache.c +++ b/tools/test/perform/chunk_cache.c @@ -26,9 +26,9 @@ #define RANK 2 #define DSET1_NAME "partial_chunks" -#define DSET1_DIM1 9 * 1000 +#define DSET1_DIM1 (9 * 1000) #define DSET1_DIM2 9 -#define CHUNK1_DIM1 2 * 1000 +#define CHUNK1_DIM1 (2 * 1000) #define CHUNK1_DIM2 2 #define DSET2_NAME "hash_value" @@ -38,7 +38,7 @@ #define CHUNK2_DIM2 100 #define RDCC_NSLOTS 5 -#define RDCC_NBYTES 1024 * 1024 * 10 +#define RDCC_NBYTES (1024 * 1024 * 10) #define RDCC_W0 0.75F #define FILTER_COUNTER 306 diff --git a/tools/test/perform/perf.c b/tools/test/perform/perf.c deleted file mode 100644 index 875f932..0000000 --- a/tools/test/perform/perf.c +++ /dev/null @@ -1,471 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * Copyright by the Board of Trustees of the University of Illinois. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Author: Albert Cheng of NCSA, May 1, 2001. - * This is derived from code given to me by Robert Ross. - * - * NOTE: This code assumes that all command line arguments make it out to all - * the processes that make up the parallel job, which isn't always the case. - * So if it doesn't work on some platform, that might be why. - */ - -#include "hdf5.h" -#include "H5private.h" -#include "h5test.h" - -#ifdef H5_HAVE_PARALLEL - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifdef H5_HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef H5_HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - -#ifdef H5_HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#ifdef H5_HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <mpi.h> -#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */ -#include <mpio.h> -#endif - -/* Macro definitions */ -/* Verify: - * if val is false (0), print mesg and if fatal is true (non-zero), die. - */ -#define H5FATAL 1 -#define VRFY(val, mesg, fatal) \ - do { \ - if (!val) { \ - printf("Proc %d: ", mynod); \ - printf("*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ - if (fatal) { \ - fflush(stdout); \ - goto die_jar_jar_die; \ - } \ - } \ - } while (0) -#define RANK 1 -#define MAX_PATH 1024 - -hsize_t dims[RANK]; /* dataset dim sizes */ -hsize_t block[RANK], stride[RANK], count[RANK]; -hsize_t start[RANK]; -hid_t fid; /* HDF5 file ID */ -hid_t acc_tpl; /* File access templates */ -hid_t sid; /* Dataspace ID */ -hid_t file_dataspace; /* File dataspace ID */ -hid_t mem_dataspace; /* memory dataspace ID */ -hid_t dataset; /* Dataset ID */ -hsize_t opt_alignment = 1; -hsize_t opt_threshold = 1; -int opt_split_vfd = 0; -char * meta_ext, *raw_ext; /* holds the meta and raw file extension if */ - /* opt_split_vfd is set */ - -/* DEFAULT VALUES FOR OPTIONS */ -int64_t opt_block = 1048576 * 16; -int opt_iter = 1; -int opt_stripe = -1; -int opt_correct = 0; -int amode = O_RDWR | O_CREAT; -char opt_file[256] = "perftest.out"; -char opt_pvfstab[256] = "notset"; -int opt_pvfstab_set = 0; - -const char *FILENAME[] = {opt_file, NULL}; - -/* function prototypes */ -static int parse_args(int argc, char **argv); - -#ifndef H5_HAVE_UNISTD_H -/* globals needed for getopt */ -extern char *optarg; -#endif - -int -main(int argc, char **argv) -{ - char * buf, *tmp, *buf2 = NULL, *tmp2 = NULL, *check; - int i, j, mynod = 0, nprocs = 1, my_correct = 1, correct, myerrno; - double stim, etim; - double write_tim = 0; - double read_tim = 0; - double read_bw, write_bw; - double max_read_tim, max_write_tim; - double min_read_tim, min_write_tim; - double ave_read_tim, ave_write_tim; - int64_t iter_jump = 0; - char filename[MAX_PATH]; - herr_t ret; /* Generic return value */ - - /* startup MPI and determine the rank of this process */ - MPI_Init(&argc, &argv); - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - MPI_Comm_rank(MPI_COMM_WORLD, &mynod); - - /* parse the command line arguments */ - parse_args(argc, argv); - - if (mynod == 0) - printf("# Using hdf5-io calls.\n"); - -#ifdef H5_HAVE_UNISTD_H - /* Kind of a weird hack- if the location of the pvfstab file was - * specified on the command line, then spit out this location into - * the appropriate environment variable. - */ - if (opt_pvfstab_set) { - if ((setenv("PVFSTAB_FILE", opt_pvfstab, 1)) < 0) { - perror("setenv"); - goto die_jar_jar_die; - } - } -#endif - - /* this is how much of the file data is covered on each iteration of - * the test. used to help determine the seek offset on each - * iteration */ - iter_jump = nprocs * opt_block; - - /* setup a buffer of data to write */ - if (!(tmp = (char *)malloc((size_t)opt_block + 256))) { - perror("malloc"); - goto die_jar_jar_die; - } - buf = tmp + 128 - (((long)tmp) % 128); /* align buffer */ - - if (opt_correct) { - /* do the same buffer setup for verifiable data */ - if (!(tmp2 = (char *)malloc((size_t)opt_block + 256))) { - perror("malloc2"); - goto die_jar_jar_die; - } - buf2 = tmp + 128 - (((long)tmp) % 128); - } - - /* setup file access template with parallel IO access. */ - if (opt_split_vfd) { - hid_t mpio_pl; - - mpio_pl = H5Pcreate(H5P_FILE_ACCESS); - VRFY((acc_tpl >= 0), "", H5FATAL); - ret = H5Pset_fapl_mpio(mpio_pl, MPI_COMM_WORLD, MPI_INFO_NULL); - VRFY((ret >= 0), "", H5FATAL); - - /* set optional allocation alignment */ - if (opt_alignment * opt_threshold != 1) { - ret = H5Pset_alignment(acc_tpl, opt_threshold, opt_alignment); - VRFY((ret >= 0), "H5Pset_alignment succeeded", !H5FATAL); - } - - /* setup file access template */ - acc_tpl = H5Pcreate(H5P_FILE_ACCESS); - VRFY((acc_tpl >= 0), "", H5FATAL); - ret = H5Pset_fapl_split(acc_tpl, meta_ext, mpio_pl, raw_ext, mpio_pl); - VRFY((ret >= 0), "H5Pset_fapl_split succeeded", H5FATAL); - ret = H5Pclose(mpio_pl); - VRFY((ret >= 0), "H5Pclose mpio_pl succeeded", H5FATAL); - } - else { - /* setup file access template */ - acc_tpl = H5Pcreate(H5P_FILE_ACCESS); - VRFY((acc_tpl >= 0), "", H5FATAL); - ret = H5Pset_fapl_mpio(acc_tpl, MPI_COMM_WORLD, MPI_INFO_NULL); - VRFY((ret >= 0), "", H5FATAL); - - /* set optional allocation alignment */ - if (opt_alignment * opt_threshold != 1) { - ret = H5Pset_alignment(acc_tpl, opt_threshold, opt_alignment); - VRFY((ret >= 0), "H5Pset_alignment succeeded", !H5FATAL); - } - } - - h5_fixname_no_suffix(FILENAME[0], acc_tpl, filename, sizeof filename); - - /* create the parallel file */ - fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl); - VRFY((fid >= 0), "H5Fcreate succeeded", H5FATAL); - - /* define a contiquous dataset of opt_iter*nprocs*opt_block chars */ - dims[0] = (hsize_t)opt_iter * (hsize_t)nprocs * (hsize_t)opt_block; - sid = H5Screate_simple(RANK, dims, NULL); - VRFY((sid >= 0), "H5Screate_simple succeeded", H5FATAL); - dataset = H5Dcreate2(fid, "Dataset1", H5T_NATIVE_CHAR, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - VRFY((dataset >= 0), "H5Dcreate2 succeeded", H5FATAL); - - /* create the memory dataspace and the file dataspace */ - dims[0] = (hsize_t)opt_block; - mem_dataspace = H5Screate_simple(RANK, dims, NULL); - VRFY((mem_dataspace >= 0), "", H5FATAL); - file_dataspace = H5Dget_space(dataset); - VRFY((file_dataspace >= 0), "H5Dget_space succeeded", H5FATAL); - - /* now each process writes a block of opt_block chars in round robbin - * fashion until the whole dataset is covered. - */ - for (j = 0; j < opt_iter; j++) { - /* setup a file dataspace selection */ - start[0] = (hsize_t)((j * iter_jump) + (mynod * opt_block)); - stride[0] = block[0] = (hsize_t)opt_block; - count[0] = 1; - ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block); - VRFY((ret >= 0), "H5Sset_hyperslab succeeded", H5FATAL); - - if (opt_correct) /* fill in buffer for iteration */ { - for (i = mynod + j, check = buf; i < opt_block; i++, check++) - *check = (char)i; - } - - /* discover the starting time of the operation */ - MPI_Barrier(MPI_COMM_WORLD); - stim = MPI_Wtime(); - - /* write data */ - ret = H5Dwrite(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf); - VRFY((ret >= 0), "H5Dwrite dataset1 succeeded", !H5FATAL); - - /* discover the ending time of the operation */ - etim = MPI_Wtime(); - - write_tim += (etim - stim); - - /* we are done with this "write" iteration */ - } - - /* close dataset and file */ - ret = H5Dclose(dataset); - VRFY((ret >= 0), "H5Dclose succeeded", H5FATAL); - ret = H5Fclose(fid); - VRFY((ret >= 0), "H5Fclose succeeded", H5FATAL); - - /* wait for everyone to synchronize at this point */ - MPI_Barrier(MPI_COMM_WORLD); - - /* reopen the file for reading */ - fid = H5Fopen(filename, H5F_ACC_RDONLY, acc_tpl); - VRFY((fid >= 0), "", H5FATAL); - - /* open the dataset */ - dataset = H5Dopen2(fid, "Dataset1", H5P_DEFAULT); - VRFY((dataset >= 0), "H5Dopen succeeded", H5FATAL); - - /* we can re-use the same mem_dataspace and file_dataspace - * the H5Dwrite used since the dimension size is the same. - */ - - /* we are going to repeat the read the same pattern the write used */ - for (j = 0; j < opt_iter; j++) { - /* setup a file dataspace selection */ - start[0] = (hsize_t)((j * iter_jump) + (mynod * opt_block)); - stride[0] = block[0] = (hsize_t)opt_block; - count[0] = 1; - ret = H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, start, stride, count, block); - VRFY((ret >= 0), "H5Sset_hyperslab succeeded", H5FATAL); - /* seek to the appropriate spot give the current iteration and - * rank within the MPI processes */ - - /* discover the start time */ - MPI_Barrier(MPI_COMM_WORLD); - stim = MPI_Wtime(); - - /* read in the file data */ - if (!opt_correct) { - ret = H5Dread(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf); - } - else { - ret = H5Dread(dataset, H5T_NATIVE_CHAR, mem_dataspace, file_dataspace, H5P_DEFAULT, buf2); - } - myerrno = errno; - - /* discover the end time */ - etim = MPI_Wtime(); - read_tim += (etim - stim); - VRFY((ret >= 0), "H5Dwrite dataset1 succeeded", !H5FATAL); - - if (ret < 0) - HDfprintf(stderr, "node %d, read error, loc = %" PRId64 ": %s\n", mynod, mynod * opt_block, - strerror(myerrno)); - - /* if the user wanted to check correctness, compare the write - * buffer to the read buffer */ - if (opt_correct && memcmp(buf, buf2, (size_t)opt_block)) { - HDfprintf(stderr, "node %d, correctness test failed\n", mynod); - my_correct = 0; - MPI_Allreduce(&my_correct, &correct, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); - } - - /* we are done with this read iteration */ - } - - /* close dataset and file */ - ret = H5Dclose(dataset); - VRFY((ret >= 0), "H5Dclose succeeded", H5FATAL); - ret = H5Fclose(fid); - VRFY((ret >= 0), "H5Fclose succeeded", H5FATAL); - ret = H5Pclose(acc_tpl); - VRFY((ret >= 0), "H5Pclose succeeded", H5FATAL); - - /* compute the read and write times */ - MPI_Allreduce(&read_tim, &max_read_tim, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); - MPI_Allreduce(&read_tim, &min_read_tim, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); - MPI_Allreduce(&read_tim, &ave_read_tim, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - - /* calculate the average from the sum */ - ave_read_tim = ave_read_tim / nprocs; - - MPI_Allreduce(&write_tim, &max_write_tim, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); - MPI_Allreduce(&write_tim, &min_write_tim, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); - MPI_Allreduce(&write_tim, &ave_write_tim, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); - - /* calculate the average from the sum */ - ave_write_tim = ave_write_tim / nprocs; - - /* print out the results on one node */ - if (mynod == 0) { - read_bw = (double)((int64_t)(opt_block * nprocs * opt_iter)) / (max_read_tim * 1000000.0); - write_bw = (double)((int64_t)(opt_block * nprocs * opt_iter)) / (max_write_tim * 1000000.0); - - printf("nr_procs = %d, nr_iter = %d, blk_sz = %ld\n", nprocs, opt_iter, (long)opt_block); - - printf("# total_size = %ld\n", (long)(opt_block * nprocs * opt_iter)); - - printf("# Write: min_time = %f, max_time = %f, mean_time = %f\n", min_write_tim, max_write_tim, - ave_write_tim); - printf("# Read: min_time = %f, max_time = %f, mean_time = %f\n", min_read_tim, max_read_tim, - ave_read_tim); - - printf("Write bandwidth = %f Mbytes/sec\n", write_bw); - printf("Read bandwidth = %f Mbytes/sec\n", read_bw); - - if (opt_correct) { - printf("Correctness test %s.\n", correct ? "passed" : "failed"); - } - } - -die_jar_jar_die: - -#ifdef H5_HAVE_UNISTD - /* Clear the environment variable if it was set earlier */ - if (opt_pvfstab_set) { - unsetenv("PVFSTAB_FILE"); - } -#endif - - free(tmp); - if (opt_correct) - free(tmp2); - - MPI_Finalize(); - - return (0); -} - -static int -parse_args(int argc, char **argv) -{ - int c; - - while ((c = getopt(argc, argv, "s:b:i:f:p:a:2:c")) != EOF) { - switch (c) { - case 's': /* stripe */ - opt_stripe = atoi(optarg); - break; - case 'b': /* block size */ - opt_block = atoi(optarg); - break; - case 'i': /* iterations */ - opt_iter = atoi(optarg); - break; - case 'f': /* filename */ - strncpy(opt_file, optarg, 255); - FILENAME[0] = opt_file; - break; - case 'p': /* pvfstab file */ - strncpy(opt_pvfstab, optarg, 255); - opt_pvfstab_set = 1; - break; - case 'a': /* aligned allocation. - * syntax: -a<alignment>/<threshold> - * e.g., -a4096/512 allocate at 4096 bytes - * boundary if request size >= 512. - */ - { - char *p; - - opt_alignment = (hsize_t)HDatoi(optarg); - if (NULL != (p = (char *)HDstrchr(optarg, '/'))) - opt_threshold = (hsize_t)HDatoi(p + 1); - } - HDfprintf(stdout, "alignment/threshold=%" PRIuHSIZE "/%" PRIuHSIZE "\n", opt_alignment, - opt_threshold); - break; - case '2': /* use 2-files, i.e., split file driver */ - opt_split_vfd = 1; - /* get meta and raw file extension. */ - /* syntax is <raw_ext>,<meta_ext> */ - meta_ext = raw_ext = optarg; - while (*raw_ext != '\0') { - if (*raw_ext == ',') { - *raw_ext = '\0'; - raw_ext++; - break; - } - raw_ext++; - } - printf("split-file-vfd used: %s,%s\n", meta_ext, raw_ext); - break; - case 'c': /* correctness */ - opt_correct = 1; - break; - case '?': /* unknown */ - default: - break; - } - } - - return (0); -} - -/* - * Local variables: - * c-indent-level: 3 - * c-basic-offset: 3 - * tab-width: 3 - * End: - */ - -#else /* H5_HAVE_PARALLEL */ -/* dummy program since H5_HAVE_PARALLEL is not configured in */ -int -main(int H5_ATTR_UNUSED argc, char H5_ATTR_UNUSED **argv) -{ - printf("No parallel performance because parallel is not configured in\n"); - return (0); -} -#endif /* H5_HAVE_PARALLEL */ diff --git a/tools/test/perform/pio_engine.c b/tools/test/perform/pio_engine.c deleted file mode 100644 index cac36d7..0000000 --- a/tools/test/perform/pio_engine.c +++ /dev/null @@ -1,2745 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Author: Albert Cheng of NCSA, Oct 24, 2001. - */ - -#include "hdf5.h" - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> - -#ifdef H5_HAVE_UNISTD_H -#include <sys/types.h> -#include <unistd.h> -#endif - -#ifdef H5_HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#ifdef H5_HAVE_PARALLEL - -#include <mpi.h> - -#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */ -#include <mpio.h> -#endif /* !MPI_FILE_NULL */ - -#include "pio_perf.h" - -/* Macro definitions */ - -#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR == 6 -#define H5DCREATE(fd, name, type, space, dcpl) H5Dcreate(fd, name, type, space, dcpl) -#define H5DOPEN(fd, name) H5Dopen(fd, name) -#else -#define H5DCREATE(fd, name, type, space, dcpl) \ - H5Dcreate2(fd, name, type, space, H5P_DEFAULT, dcpl, H5P_DEFAULT) -#define H5DOPEN(fd, name) H5Dopen2(fd, name, H5P_DEFAULT) -#endif - -/* sizes of various items. these sizes won't change during program execution */ -/* The following three must have the same type */ -#define ELMT_H5_TYPE H5T_NATIVE_UCHAR - -#define GOTOERROR(errcode) \ - { \ - ret_code = errcode; \ - goto done; \ - } -#define ERRMSG(mesg) \ - { \ - HDfprintf(stderr, "Proc %d: ", pio_mpi_rank_g); \ - HDfprintf(stderr, "*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ - } - -/* verify: if val is false (0), print mesg. */ -#define VRFY(val, mesg) \ - do { \ - if (!val) { \ - ERRMSG(mesg); \ - GOTOERROR(FAIL); \ - } \ - } while (0) - -/* POSIX I/O macros */ -#ifdef H5_HAVE_WIN32_API -/* Can't link against the library, so this test will use the older, non-Unicode - * _open() call on Windows. - */ -#define HDopen(S, F, ...) _open(S, F | _O_BINARY, __VA_ARGS__) -#endif /* H5_HAVE_WIN32_API */ -#define POSIXCREATE(fn) HDopen(fn, O_CREAT | O_TRUNC | O_RDWR, 0600) -#define POSIXOPEN(fn, F) HDopen(fn, F, 0600) -#define POSIXCLOSE(F) HDclose(F) -#define POSIXSEEK(F, L) HDlseek(F, L, SEEK_SET) -#define POSIXWRITE(F, B, S) HDwrite(F, B, S) -#define POSIXREAD(F, B, S) HDread(F, B, S) - -enum { PIO_CREATE = 1, PIO_WRITE = 2, PIO_READ = 4 }; - -/* Global variables */ -static int clean_file_g = -1; /*whether to cleanup temporary test */ -/*files. -1 is not defined; */ -/*0 is no cleanup; 1 is do cleanup */ - -/* - * In a parallel machine, the filesystem suitable for compiling is - * unlikely a parallel file system that is suitable for parallel I/O. - * There is no standard pathname for the parallel file system. /tmp - * is about the best guess. - */ -#ifndef HDF5_PARAPREFIX -#define HDF5_PARAPREFIX "" -#endif /* !HDF5_PARAPREFIX */ - -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif /* !MIN */ - -/* the different types of file descriptors we can expect */ -typedef union _file_descr { - int posixfd; /* POSIX file handle*/ - MPI_File mpifd; /* MPI file */ - hid_t h5fd; /* HDF5 file */ -} file_descr; - -/* local functions */ -static char * pio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size); -static herr_t do_write(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nelmts, - size_t buf_size, void *buffer); -static herr_t do_read(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nelmts, - size_t buf_size, void *buffer /*out*/); -static herr_t do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags); -static herr_t do_fclose(iotype iot, file_descr *fd); -static void do_cleanupfile(iotype iot, char *fname); -static off_t sqrto(off_t); - -/* - * Function: do_pio - * Purpose: PIO Engine where Parallel IO are executed. - * Return: results - * Programmer: Albert Cheng, Bill Wendling 2001/12/12 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -results -do_pio(parameters param) -{ - /* return codes */ - herr_t ret_code = 0; /*return code */ - results res; - - file_descr fd; - iotype iot; - - char fname[FILENAME_MAX]; - long nf; - long ndsets; - off_t nbytes; /*number of bytes per dataset */ - off_t snbytes; /*general dataset size */ - /*for 1D, it is the actual dataset size */ - /*for 2D, it is the size of a side of the dataset square */ - char * buffer = NULL; /*data buffer pointer */ - size_t buf_size; /*general buffer size in bytes */ - /*for 1D, it is the actual buffer size */ - /*for 2D, it is the length of the buffer rectangle */ - size_t blk_size; /*data block size in bytes */ - size_t bsize; /*actual buffer size */ - - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - - /* Sanity check parameters */ - - /* IO type */ - iot = param.io_type; - - switch (iot) { - case MPIO: - fd.mpifd = MPI_FILE_NULL; - res.timers = io_time_new(MPI_CLOCK); - break; - case POSIXIO: - fd.posixfd = -1; - res.timers = io_time_new(MPI_CLOCK); - break; - case PHDF5: - fd.h5fd = -1; - res.timers = io_time_new(MPI_CLOCK); - break; - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", iot); - GOTOERROR(FAIL); - } - - ndsets = param.num_dsets; /* number of datasets per file */ - nbytes = param.num_bytes; /* number of bytes per dataset */ - buf_size = param.buf_size; - blk_size = param.blk_size; - - if (!param.dim2d) { - snbytes = nbytes; /* General dataset size */ - bsize = buf_size; /* Actual buffer size */ - } - else { - snbytes = sqrto(nbytes); /* General dataset size */ - bsize = buf_size * blk_size; /* Actual buffer size */ - } - - if (param.num_files < 0) { - HDfprintf(stderr, "number of files must be >= 0 (%ld)\n", param.num_files); - GOTOERROR(FAIL); - } - - if (ndsets < 0) { - HDfprintf(stderr, "number of datasets per file must be >= 0 (%ld)\n", ndsets); - GOTOERROR(FAIL); - } - - if (param.num_procs <= 0) { - HDfprintf(stderr, "maximum number of process to use must be > 0 (%d)\n", param.num_procs); - GOTOERROR(FAIL); - } - - /* Validate transfer buffer size & block size*/ - if (blk_size <= 0) { - HDfprintf(stderr, "Transfer block size (%zu) must be > 0\n", blk_size); - GOTOERROR(FAIL); - } - if (buf_size <= 0) { - HDfprintf(stderr, "Transfer buffer size (%zu) must be > 0\n", buf_size); - GOTOERROR(FAIL); - } - if ((buf_size % blk_size) != 0) { - HDfprintf(stderr, - "Transfer buffer size (%zu) must be a multiple of the " - "interleaved I/O block size (%zu)\n", - buf_size, blk_size); - GOTOERROR(FAIL); - } - if ((snbytes % pio_mpi_nprocs_g) != 0) { - HDfprintf(stderr, - "Dataset size (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "number of processes (%d)\n", - (long long)snbytes, pio_mpi_nprocs_g); - GOTOERROR(FAIL); - } - - if (!param.dim2d) { - if (((size_t)(snbytes / pio_mpi_nprocs_g) % buf_size) != 0) { - HDfprintf(stderr, - "Dataset size/process (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "trasfer buffer size (%zu)\n", - (long long)(snbytes / pio_mpi_nprocs_g), buf_size); - GOTOERROR(FAIL); - } - } - else { - if (((size_t)snbytes % buf_size) != 0) { - HDfprintf(stderr, - "Dataset side size (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "trasfer buffer size (%zu)\n", - (long long)snbytes, buf_size); - GOTOERROR(FAIL); - } - } - - /* Allocate transfer buffer */ - if ((buffer = malloc(bsize)) == NULL) { - HDfprintf(stderr, "malloc for transfer buffer size (%zu) failed\n", bsize); - GOTOERROR(FAIL); - } - - if (pio_debug_level >= 4) { - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - /* output all of the times for all iterations */ - if (myrank == 0) - HDfprintf(output, "Timer details:\n"); - } - - for (nf = 1; nf <= param.num_files; nf++) { - /* - * Write performance measurement - */ - /* Open file for write */ - char base_name[256]; - - HDsprintf(base_name, "#pio_tmp_%lu", nf); - pio_create_filename(iot, base_name, fname, sizeof(fname)); - if (pio_debug_level > 0) - HDfprintf(output, "rank %d: data filename=%s\n", pio_mpi_rank_g, fname); - - /* Need barrier to make sure everyone starts at the same time */ - MPI_Barrier(pio_comm_g); - - io_time_set(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, PIO_CREATE | PIO_WRITE); - - VRFY((hrc == SUCCESS), "do_fopen failed"); - - io_time_set(res.timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTART); - hrc = do_write(&res, &fd, ¶m, ndsets, nbytes, buf_size, buffer); - io_time_set(res.timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTOP); - - VRFY((hrc == SUCCESS), "do_write failed"); - - /* Close file for write */ - hrc = do_fclose(iot, &fd); - - io_time_set(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - - if (!param.h5_write_only) { - /* - * Read performance measurement - */ - /* Need barrier to make sure everyone is done writing and has - * closed the file. Also to make sure everyone starts reading - * at the same time. - */ - MPI_Barrier(pio_comm_g); - - /* Open file for read */ - io_time_set(res.timers, HDF5_GROSS_READ_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, PIO_READ); - - VRFY((hrc == SUCCESS), "do_fopen failed"); - - io_time_set(res.timers, HDF5_FINE_READ_FIXED_DIMS, TSTART); - hrc = do_read(&res, &fd, ¶m, ndsets, nbytes, buf_size, buffer); - io_time_set(res.timers, HDF5_FINE_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_read failed"); - - /* Close file for read */ - hrc = do_fclose(iot, &fd); - - io_time_set(res.timers, HDF5_GROSS_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - } - - /* Need barrier to make sure everyone is done with the file */ - /* before it may be removed by do_cleanupfile */ - MPI_Barrier(pio_comm_g); - do_cleanupfile(iot, fname); - } - -done: - /* clean up */ - /* release HDF5 objects */ - - /* close any opened files */ - /* no remove(fname) because that should have happened normally. */ - switch (iot) { - case POSIXIO: - if (fd.posixfd != -1) - hrc = do_fclose(iot, &fd); - break; - case MPIO: - if (fd.mpifd != MPI_FILE_NULL) - hrc = do_fclose(iot, &fd); - break; - case PHDF5: - if (fd.h5fd != -1) - hrc = do_fclose(iot, &fd); - break; - default: - break; - } - - /* release generic resources */ - if (buffer) - HDfree(buffer); - res.ret_code = ret_code; - return res; -} - -/* - * Function: pio_create_filename - * Purpose: Create a new filename to write to. Determine the correct - * suffix to append to the filename by the type of I/O we're - * doing. Also, place in the /tmp/{$USER,$LOGIN} directory if - * USER or LOGIN are specified in the environment. - * Return: Pointer to filename or NULL - * Programmer: Bill Wendling, 21. November 2001 - * Modifications: - */ -static char * -pio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size) -{ - const char *prefix, *suffix = ""; - char * ptr, last = '\0'; - size_t i, j; - - if (!base_name || !fullname || size < 1) - return NULL; - - HDmemset(fullname, 0, size); - - switch (iot) { - case POSIXIO: - suffix = ".posix"; - break; - case MPIO: - suffix = ".mpio"; - break; - case PHDF5: - suffix = ".h5"; - break; - default: - break; - } - - /* First use the environment variable and then try the constant */ - prefix = HDgetenv("HDF5_PARAPREFIX"); - -#ifdef HDF5_PARAPREFIX - if (!prefix) - prefix = HDF5_PARAPREFIX; -#endif /* HDF5_PARAPREFIX */ - - /* Prepend the prefix value to the base name */ - if (prefix && *prefix) { - /* If the prefix specifies the HDF5_PARAPREFIX directory, then - * default to using the "/tmp/$USER" or "/tmp/$LOGIN" - * directory instead. */ - register char *user, *login, *subdir; - - user = HDgetenv("USER"); - login = HDgetenv("LOGIN"); - subdir = (user ? user : login); - - if (subdir) { - for (i = 0; i < size - 1 && prefix[i]; i++) - fullname[i] = prefix[i]; - - fullname[i++] = '/'; - - for (j = 0; i < size && subdir[j]; i++, j++) - fullname[i] = subdir[j]; - } - else { - /* We didn't append the prefix yet */ - HDstrncpy(fullname, prefix, size); - fullname[size - 1] = '\0'; - } - - if ((HDstrlen(fullname) + HDstrlen(base_name) + 1) < size) { - /* Append the base_name with a slash first. Multiple slashes are - * handled below. */ - h5_stat_t buf; - - if (HDstat(fullname, &buf) < 0) - /* The directory doesn't exist just yet */ - if (HDmkdir(fullname, (mode_t)0755) < 0 && errno != EEXIST) { - /* We couldn't make the "/tmp/${USER,LOGIN}" subdirectory. - * Default to PREFIX's original prefix value. */ - HDstrcpy(fullname, prefix); - } - - HDstrcat(fullname, "/"); - HDstrcat(fullname, base_name); - } - else { - /* Buffer is too small */ - return NULL; - } - } - else if (HDstrlen(base_name) >= size) { - /* Buffer is too small */ - return NULL; - } - else { - HDstrcpy(fullname, base_name); - } - - /* Append a suffix */ - if (suffix) { - if (HDstrlen(fullname) + HDstrlen(suffix) >= size) - return NULL; - - HDstrcat(fullname, suffix); - } - - /* Remove any double slashes in the filename */ - for (ptr = fullname, i = j = 0; ptr && i < size; i++, ptr++) { - if (*ptr != '/' || last != '/') - fullname[j++] = *ptr; - - last = *ptr; - } - - return fullname; -} - -/* - * Function: do_write - * Purpose: Write the required amount of data to the file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static herr_t -do_write(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nbytes, size_t buf_size, - void *buffer) -{ - int ret_code = SUCCESS; - int rc; /*routine return code */ - long ndset; - size_t blk_size; /* The block size to subdivide the xfer buffer into */ - off_t nbytes_xfer; /* Total number of bytes transferred so far */ - size_t nbytes_xfer_advance; /* Number of bytes transferred in a single I/O operation */ - size_t nbytes_toxfer; /* Number of bytes to transfer a particular time */ - char dname[64]; - off_t dset_offset = 0; /*dataset offset in a file */ - off_t bytes_begin[2]; /*first elmt this process transfer */ - off_t bytes_count; /*number of elmts this process transfer */ - off_t snbytes = 0; /*size of a side of the dataset square */ - unsigned char *buf_p; /* Current buffer pointer */ - - /* POSIX variables */ - off_t file_offset; /* File offset of the next transfer */ - off_t file_offset_advance; /* File offset advance after each I/O operation */ - off_t posix_file_offset; /* Base file offset of the next transfer */ - - /* MPI variables */ - MPI_Offset mpi_file_offset; /* Base file offset of the next transfer*/ - MPI_Offset mpi_offset; /* Offset in MPI file */ - MPI_Offset mpi_offset_advance; /* Offset advance after each I/O operation */ - MPI_Datatype mpi_file_type; /* MPI derived type for 1D file */ - MPI_Datatype mpi_blk_type; /* MPI derived type for 1D buffer */ - MPI_Datatype mpi_cont_type; /* MPI derived type for 2D contiguous file */ - MPI_Datatype mpi_partial_buffer_cont; /* MPI derived type for partial 2D contiguous buffer */ - MPI_Datatype mpi_inter_type; /* MPI derived type for 2D interleaved file */ - MPI_Datatype mpi_partial_buffer_inter; /* MPI derived type for partial 2D interleaved buffer */ - MPI_Datatype mpi_full_buffer; /* MPI derived type for 2D full buffer */ - MPI_Datatype mpi_full_chunk; /* MPI derived type for 2D full chunk */ - MPI_Datatype mpi_chunk_inter_type; /* MPI derived type for 2D chunk interleaved file */ - MPI_Datatype mpi_collective_type; /* Generic MPI derived type for 2D collective access */ - MPI_Status mpi_status; - int mrc; /* MPI return code */ - - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[2]; /*dataset dim sizes */ - hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ - hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ - hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ - hsize_t h5block[2]; /*dataspace selection */ - hsize_t h5stride[2]; - hsize_t h5count[2]; - hsize_t h5start[2]; - hssize_t h5offset[2]; /* Selection offset within dataspace */ - hid_t h5dcpl = H5I_INVALID_HID; /* Dataset creation property list */ - hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ - - /* Get the parameters from the parameter block */ - blk_size = parms->blk_size; - - /* There are two kinds of transfer patterns, contiguous and interleaved. - * Let 0,1,2,...,n be data accessed by process 0,1,2,...,n - * where n is rank of the last process. - * In contiguous pattern, data are accessed as - * 000...111...222...nnn... - * In interleaved pattern, data are accessed as - * 012...n012...n... - * These are all in the scope of one dataset. - */ - - /* 1D dataspace */ - if (!parms->dim2d) { - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = (off_t)(blk_size * (size_t)pio_mpi_rank_g); - } /* end else */ - - /* Prepare buffer for verifying data */ - if (parms->verify) - memset(buffer, pio_mpi_rank_g + 1, buf_size); - } /* end if */ - /* 2D dataspace */ - else { - /* nbytes is always the number of bytes per dataset (1D or 2D). If the - dataspace is 2D, snbytes is the size of a side of the dataset square. - */ - snbytes = sqrto(nbytes); - - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)((double)snbytes * pio_mpi_rank_g / pio_mpi_nprocs_g); - bytes_begin[1] = 0; - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = 0; - - if (!parms->h5_use_chunks || parms->io_type == PHDF5) - bytes_begin[1] = (off_t)(blk_size * (size_t)pio_mpi_rank_g); - else - bytes_begin[1] = (off_t)(blk_size * blk_size * (size_t)pio_mpi_rank_g); - } /* end else */ - - /* Prepare buffer for verifying data */ - if (parms->verify) - HDmemset(buffer, pio_mpi_rank_g + 1, buf_size * blk_size); - } /* end else */ - - /* Calculate the total number of bytes (bytes_count) to be - * transferred by this process. It may be different for different - * transfer pattern due to rounding to integral values. - */ - /* - * Calculate the beginning bytes of this process and the next. - * bytes_count is the difference between these two beginnings. - * This way, it eliminates any rounding errors. - * (This is tricky, don't mess with the formula, rounding errors - * can easily get introduced) */ - bytes_count = (off_t)(((double)nbytes * (pio_mpi_rank_g + 1)) / pio_mpi_nprocs_g) - - (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); - - /* debug */ - if (pio_debug_level >= 4) { - HDprint_rank(output); - if (!parms->dim2d) { - HDfprintf(output, - "Debug(do_write): " - "buf_size=%zu, bytes_begin=%" H5_PRINTF_LL_WIDTH "d, bytes_count=%" H5_PRINTF_LL_WIDTH - "d\n", - buf_size, (long long)bytes_begin[0], (long long)bytes_count); - } - else { - HDfprintf(output, - "Debug(do_write): " - "linear buf_size=%zu, bytes_begin=(%" H5_PRINTF_LL_WIDTH "d,%" H5_PRINTF_LL_WIDTH - "d), bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", - buf_size * blk_size, (long long)bytes_begin[0], (long long)bytes_begin[1], - (long long)bytes_count); - } - } - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - /* No extra setup */ - break; - - case MPIO: /* MPI-I/O setup */ - /* 1D dataspace */ - if (!parms->dim2d) { - /* Build block's derived type */ - mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Build file's derived type */ - mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)pio_mpi_nprocs_g, mpi_blk_type, - &mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit file type */ - mrc = MPI_Type_commit(&mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Commit buffer type */ - mrc = MPI_Type_commit(&mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - } /* end if */ - /* 2D dataspace */ - else { - /* Build partial buffer derived type for contiguous access */ - - mrc = MPI_Type_contiguous((int)buf_size, MPI_BYTE, &mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build contiguous file's derived type */ - mrc = MPI_Type_vector((int)blk_size, (int)1, (int)((size_t)snbytes / buf_size), - mpi_partial_buffer_cont, &mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit contiguous file type */ - mrc = MPI_Type_commit(&mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build partial buffer derived type for interleaved access */ - mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build interleaved file's derived type */ - mrc = MPI_Type_vector((int)buf_size, (int)1, (int)((size_t)snbytes / blk_size), - mpi_partial_buffer_inter, &mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit interleaved file type */ - mrc = MPI_Type_commit(&mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full buffer derived type */ - mrc = MPI_Type_contiguous((int)(blk_size * buf_size), MPI_BYTE, &mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full buffer derived type */ - mrc = MPI_Type_commit(&mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full chunk derived type */ - mrc = MPI_Type_contiguous((int)(blk_size * blk_size), MPI_BYTE, &mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full chunk derived type */ - mrc = MPI_Type_commit(&mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build chunk interleaved file's derived type */ - mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)((size_t)snbytes / blk_size), - mpi_full_chunk, &mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit chunk interleaved file type */ - mrc = MPI_Type_commit(&mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - } /* end else */ - break; - - case PHDF5: /* HDF5 setup */ - /* 1D dataspace */ - if (!parms->dim2d) { - if (nbytes > 0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = (hsize_t)nbytes; - h5dset_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5stride[0] = h5block[0] = blk_size; - h5count[0] = buf_size / blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5stride[0] = blk_size * (size_t)pio_mpi_nprocs_g; - h5block[0] = blk_size; - h5count[0] = buf_size / blk_size; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, - h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if (buf_size > 0) { - h5dims[0] = buf_size; - h5mem_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - if (nbytes > 0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = (hsize_t)snbytes; - h5dims[1] = (hsize_t)snbytes; - h5dset_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5start[1] = (hsize_t)bytes_begin[1]; - h5stride[0] = 1; - h5stride[1] = h5block[0] = h5block[1] = blk_size; - h5count[0] = 1; - h5count[1] = buf_size / blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5start[1] = (hsize_t)bytes_begin[1]; - h5stride[0] = blk_size; - h5stride[1] = blk_size * (size_t)pio_mpi_nprocs_g; - h5block[0] = h5block[1] = blk_size; - h5count[0] = buf_size / blk_size; - h5count[1] = 1; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, - h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if (buf_size > 0) { - if (!parms->interleaved) { - h5dims[0] = blk_size; - h5dims[1] = buf_size; - } - else { - h5dims[0] = buf_size; - h5dims[1] = blk_size; - } - h5mem_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end else */ - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - /* Change to collective I/O, if asked */ - if (parms->collective) { - hrc = H5Pset_dxpl_mpio(h5dxpl, H5FD_MPIO_COLLECTIVE); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - break; - - default: - break; - } /* end switch */ - - for (ndset = 1; ndset <= ndsets; ++ndset) { - - /* Calculate dataset offset within a file */ - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - case MPIO: - /* both posix and mpi io just need dataset offset in file*/ - dset_offset = (ndset - 1) * nbytes; - break; - - case PHDF5: - h5dcpl = H5Pcreate(H5P_DATASET_CREATE); - if (h5dcpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - /* 1D dataspace */ - if (!parms->dim2d) { - /* Make the dataset chunked if asked */ - if (parms->h5_use_chunks) { - /* Set the chunk size to be the same as the buffer size */ - h5dims[0] = blk_size; - hrc = H5Pset_chunk(h5dcpl, 1, h5dims); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - } /* end if */ - else { - /* 2D dataspace */ - if (parms->h5_use_chunks) { - /* Set the chunk size to be the same as the block size */ - h5dims[0] = blk_size; - h5dims[1] = blk_size; - hrc = H5Pset_chunk(h5dcpl, 2, h5dims); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - } /* end else */ - - HDsprintf(dname, "Dataset_%ld", ndset); - h5ds_id = H5DCREATE(fd->h5fd, dname, ELMT_H5_TYPE, h5dset_space_id, h5dcpl); - - if (h5ds_id < 0) { - HDfprintf(stderr, "HDF5 Dataset Create failed\n"); - GOTOERROR(FAIL); - } - - hrc = H5Pclose(h5dcpl); - /* verifying the close of the dcpl */ - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Close failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - break; - } - - /* The task is to transfer bytes_count bytes, starting at - * bytes_begin position, using transfer buffer of buf_size bytes. - * If interleaved, select buf_size at a time, in round robin - * fashion, according to number of process. Otherwise, select - * all bytes_count in contiguous. - */ - nbytes_xfer = 0; - - /* 1D dataspace */ - if (!parms->dim2d) { - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset = dset_offset + bytes_begin[0]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0]); - } /* end if */ - else { - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset = dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]); - } /* end else */ - - /* Start "raw data" write timer */ - io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTART); - - while (nbytes_xfer < bytes_count) { - /* Write */ - /* Calculate offset of write within a dataset/file */ - switch (parms->io_type) { - case POSIXIO: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Contiguous pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + (off_t)nbytes_xfer; - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are written */ - rc = ((ssize_t)buf_size == POSIXWRITE(fd->posixfd, buffer, buf_size)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to write */ - while (nbytes_toxfer > 0) { - /* Skip offset over blocks of other processes */ - file_offset = posix_file_offset + (off_t)(nbytes_xfer * pio_mpi_nprocs_g); - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are written */ - rc = ((ssize_t)blk_size == POSIXWRITE(fd->posixfd, buf_p, blk_size)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance location in buffer */ - buf_p += blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + - (off_t)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * - (blk_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / blk_size) % (size_t)snbytes)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute file offset */ - file_offset = - posix_file_offset + - (off_t)(((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / - (size_t)snbytes) * - (buf_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % - (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + (off_t)nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = 0; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute file offset */ - /* Before simplification */ - /* file_offset=posix_file_offset+(off_t)((nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))*(buf_size/blk_size - *snbytes/blk_size*(blk_size*blk_size))+((nbytes_xfer/(buf_size/blk_size)) - *pio_mpi_nprocs_g)%(snbytes/blk_size*(blk_size*blk_size))); */ - - file_offset = posix_file_offset + - (off_t)((((size_t)nbytes_xfer / (buf_size / blk_size) * - (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * blk_size)) * - (buf_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / (buf_size / blk_size)) * - (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * blk_size)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* file_offset_advance = (off_t)(snbytes/blk_size*(blk_size*blk_size)); */ - file_offset_advance = (off_t)snbytes * (off_t)blk_size; - } /* end else */ - } /* end else */ - - /* Common code for file access */ - - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size * blk_size; - - /* Loop over portions of the buffer to write */ - while (nbytes_toxfer > 0) { - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are written */ - rc = ((ssize_t)nbytes_xfer_advance == - POSIXWRITE(fd->posixfd, buf_p, nbytes_xfer_advance)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance location in buffer */ - buf_p += nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= nbytes_xfer_advance; - - /* Partially advance file offset */ - file_offset += file_offset_advance; - } /* end while */ - - } /* end else */ - - break; - - case MPIO: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Independent file access */ - if (!parms->collective) { - /* Contiguous pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Perform independent write */ - mrc = - MPI_File_write_at(fd->mpifd, mpi_offset, buffer, - (int)(buf_size / blk_size), mpi_blk_type, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to write */ - while (nbytes_toxfer > 0) { - /* Skip offset over blocks of other processes */ - mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); - - /* Perform independent write */ - mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buf_p, (int)1, - mpi_blk_type, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance location in buffer */ - buf_p += blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* Collective file access */ - else { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Perform independent write */ - mrc = MPI_File_write_at_all(fd->mpifd, mpi_offset, buffer, - (int)(buf_size / blk_size), mpi_blk_type, - &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); - - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, mpi_blk_type, mpi_file_type, - (char *)"native", h5_io_info_g); - VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform write */ - mrc = MPI_File_write_at_all(fd->mpifd, 0, buffer, (int)(buf_size / blk_size), - mpi_blk_type, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)buf_size; - } /* end else */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = - mpi_file_offset + - (MPI_Offset)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * - (blk_size * (size_t)snbytes)) + - (MPI_Offset)(((size_t)nbytes_xfer / blk_size) % (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_cont_type; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset = - mpi_file_offset + - (MPI_Offset)( - ((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / - (size_t)snbytes) * - (buf_size * (size_t)snbytes)) + - (MPI_Offset)( - (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % - (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_inter_type; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = 0; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_full_buffer; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute offset in file */ - /* Before simplification */ - /* mpi_offset=mpi_file_offset+(nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))* - (buf_size/blk_size*snbytes/blk_size*(blk_size*blk_size))+ - ((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes - /blk_size*(blk_size*blk_size)); */ - mpi_offset = mpi_file_offset + - (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size) * - (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * blk_size)) * - (buf_size * (size_t)snbytes)) + - (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size)) * - (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * blk_size)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* mpi_offset_advance = (MPI_Offset)(snbytes/blk_size*(blk_size*blk_size)); */ - mpi_offset_advance = (MPI_Offset)((size_t)snbytes * blk_size); - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_chunk_inter_type; - } /* end else */ - } /* end else */ - - /* Common code for independent file access */ - if (!parms->collective) { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size * blk_size; - - /* Loop over portions of the buffer to write */ - while (nbytes_toxfer > 0) { - /* Perform independent write */ - mrc = MPI_File_write_at(fd->mpifd, mpi_offset, buf_p, - (int)nbytes_xfer_advance, MPI_BYTE, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance location in buffer */ - buf_p += nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer += (ssize_t)nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= nbytes_xfer_advance; - - /* Partially advance global offset in dataset */ - mpi_offset += mpi_offset_advance; - } /* end while */ - } /* end if */ - - /* Common code for collective file access */ - else { - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, MPI_BYTE, mpi_collective_type, - (char *)"native", h5_io_info_g); - VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform write */ - MPI_File_write_at_all(fd->mpifd, 0, buffer, (int)(buf_size * blk_size), MPI_BYTE, - &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_WRITE"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size * (off_t)blk_size; - } /* end else */ - - } /* end else */ - - break; - - case PHDF5: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5offset[0] = nbytes_xfer; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = (nbytes_xfer * pio_mpi_nprocs_g); - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc = - H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dwrite"); - - /* Increment number of bytes transferred */ - nbytes_xfer += (ssize_t)buf_size; - } /* end if */ - /* 2D dataspace */ - else { - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5offset[0] = - (hssize_t)(((size_t)nbytes_xfer / ((size_t)snbytes * blk_size)) * blk_size); - h5offset[1] = - (hssize_t)(((size_t)nbytes_xfer % ((size_t)snbytes * blk_size)) / blk_size); - - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * buf_size)) * - buf_size); - h5offset[1] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * buf_size)) / - buf_size); - - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc = - H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dwrite"); - - /* Increment number of bytes transferred */ - nbytes_xfer += (off_t)buf_size * (off_t)blk_size; - - } /* end else */ - - break; - - default: - break; - } /* switch (parms->io_type) */ - } /* end while */ - - /* Stop "raw data" write timer */ - io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTOP); - - /* Calculate write time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == PHDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = H5I_INVALID_HID; - } /* end if */ - } /* end for */ - -done: - /* release MPI-I/O objects */ - if (parms->io_type == MPIO) { - /* 1D dataspace */ - if (!parms->dim2d) { - /* Free file type */ - mrc = MPI_Type_free(&mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free buffer type */ - mrc = MPI_Type_free(&mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end if */ - /* 2D dataspace */ - else { - /* Free partial buffer type for contiguous access */ - mrc = MPI_Type_free(&mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free contiguous file type */ - mrc = MPI_Type_free(&mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free partial buffer type for interleaved access */ - mrc = MPI_Type_free(&mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free interleaved file type */ - mrc = MPI_Type_free(&mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full buffer type */ - mrc = MPI_Type_free(&mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full chunk type */ - mrc = MPI_Type_free(&mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free chunk interleaved file type */ - mrc = MPI_Type_free(&mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end else */ - } /* end if */ - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } - else { - h5dset_space_id = H5I_INVALID_HID; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } - else { - h5mem_space_id = H5I_INVALID_HID; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } - else { - h5dxpl = H5I_INVALID_HID; - } - } - - return ret_code; -} - -static off_t -sqrto(off_t x) -{ - double root_x = sqrt((double)x); - return (off_t)root_x; -} - -/* - * Function: do_read - * Purpose: read the required amount of data from the file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng 2001/12/13 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static herr_t -do_read(results *res, file_descr *fd, parameters *parms, long ndsets, off_t nbytes, size_t buf_size, - void *buffer /*out*/) -{ - int ret_code = SUCCESS; - int rc; /*routine return code */ - long ndset; - size_t blk_size; /* The block size to subdivide the xfer buffer into */ - size_t bsize; /* Size of the actual buffer */ - off_t nbytes_xfer; /* Total number of bytes transferred so far */ - size_t nbytes_xfer_advance; /* Number of bytes transferred in a single I/O operation */ - size_t nbytes_toxfer; /* Number of bytes to transfer a particular time */ - char dname[64]; - off_t dset_offset = 0; /*dataset offset in a file */ - off_t bytes_begin[2]; /*first elmt this process transfer */ - off_t bytes_count; /*number of elmts this process transfer */ - off_t snbytes = 0; /*size of a side of the dataset square */ - unsigned char *buf_p; /* Current buffer pointer */ - - /* POSIX variables */ - off_t file_offset; /* File offset of the next transfer */ - off_t file_offset_advance; /* File offset advance after each I/O operation */ - off_t posix_file_offset; /* Base file offset of the next transfer */ - - /* MPI variables */ - MPI_Offset mpi_file_offset; /* Base file offset of the next transfer*/ - MPI_Offset mpi_offset; /* Offset in MPI file */ - MPI_Offset mpi_offset_advance; /* Offset advance after each I/O operation */ - MPI_Datatype mpi_file_type; /* MPI derived type for 1D file */ - MPI_Datatype mpi_blk_type; /* MPI derived type for 1D buffer */ - MPI_Datatype mpi_cont_type; /* MPI derived type for 2D contiguous file */ - MPI_Datatype mpi_partial_buffer_cont; /* MPI derived type for partial 2D contiguous buffer */ - MPI_Datatype mpi_inter_type; /* MPI derived type for 2D interleaved file */ - MPI_Datatype mpi_partial_buffer_inter; /* MPI derived type for partial 2D interleaved buffer */ - MPI_Datatype mpi_full_buffer; /* MPI derived type for 2D full buffer */ - MPI_Datatype mpi_full_chunk; /* MPI derived type for 2D full chunk */ - MPI_Datatype mpi_chunk_inter_type; /* MPI derived type for 2D chunk interleaved file */ - MPI_Datatype mpi_collective_type; /* Generic MPI derived type for 2D collective access */ - MPI_Status mpi_status; - int mrc; /* MPI return code */ - - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[2]; /*dataset dim sizes */ - hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ - hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ - hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ - hsize_t h5block[2]; /*dataspace selection */ - hsize_t h5stride[2]; - hsize_t h5count[2]; - hsize_t h5start[2]; - hssize_t h5offset[2]; /* Selection offset within dataspace */ - hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ - - /* Get the parameters from the parameter block */ - blk_size = parms->blk_size; - - /* There are two kinds of transfer patterns, contiguous and interleaved. - * Let 0,1,2,...,n be data accessed by process 0,1,2,...,n - * where n is rank of the last process. - * In contiguous pattern, data are accessed as - * 000...111...222...nnn... - * In interleaved pattern, data are accessed as - * 012...n012...n... - * These are all in the scope of one dataset. - */ - - /* 1D dataspace */ - if (!parms->dim2d) { - bsize = buf_size; - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = (off_t)blk_size * (off_t)pio_mpi_rank_g; - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* nbytes is always the number of bytes per dataset (1D or 2D). If the - dataspace is 2D, snbytes is the size of a side of the 'dataset square'. - */ - snbytes = sqrto(nbytes); - - bsize = buf_size * blk_size; - - /* Contiguous Pattern: */ - if (!parms->interleaved) { - bytes_begin[0] = (off_t)((double)snbytes * pio_mpi_rank_g / pio_mpi_nprocs_g); - bytes_begin[1] = 0; - } /* end if */ - /* Interleaved Pattern: */ - else { - bytes_begin[0] = 0; - - if (!parms->h5_use_chunks || parms->io_type == PHDF5) - bytes_begin[1] = (off_t)blk_size * (off_t)pio_mpi_rank_g; - else - bytes_begin[1] = (off_t)blk_size * (off_t)blk_size * (off_t)pio_mpi_rank_g; - } /* end else */ - } /* end else */ - - /* Calculate the total number of bytes (bytes_count) to be - * transferred by this process. It may be different for different - * transfer pattern due to rounding to integral values. - */ - /* - * Calculate the beginning bytes of this process and the next. - * bytes_count is the difference between these two beginnings. - * This way, it eliminates any rounding errors. - * (This is tricky, don't mess with the formula, rounding errors - * can easily get introduced) */ - bytes_count = (off_t)(((double)nbytes * (pio_mpi_rank_g + 1)) / pio_mpi_nprocs_g) - - (off_t)(((double)nbytes * pio_mpi_rank_g) / pio_mpi_nprocs_g); - - /* debug */ - if (pio_debug_level >= 4) { - HDprint_rank(output); - if (!parms->dim2d) { - HDfprintf(output, - "Debug(do_write): " - "buf_size=%zu, bytes_begin=%" H5_PRINTF_LL_WIDTH "d, bytes_count=%" H5_PRINTF_LL_WIDTH - "d\n", - buf_size, (long long)bytes_begin[0], (long long)bytes_count); - } - else { - HDfprintf(output, - "Debug(do_write): " - "linear buf_size=%zu, bytes_begin=(%" H5_PRINTF_LL_WIDTH "d,%" H5_PRINTF_LL_WIDTH - "d), bytes_count=%" H5_PRINTF_LL_WIDTH "d\n", - buf_size * blk_size, (long long)bytes_begin[0], (long long)bytes_begin[1], - (long long)bytes_count); - } - } - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - /* No extra setup */ - break; - - case MPIO: /* MPI-I/O setup */ - /* 1D dataspace */ - if (!parms->dim2d) { - /* Build block's derived type */ - mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Build file's derived type */ - mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)pio_mpi_nprocs_g, mpi_blk_type, - &mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit file type */ - mrc = MPI_Type_commit(&mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Commit buffer type */ - mrc = MPI_Type_commit(&mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - } /* end if */ - /* 2D dataspace */ - else { - /* Build partial buffer derived type for contiguous access */ - mrc = MPI_Type_contiguous((int)buf_size, MPI_BYTE, &mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build contiguous file's derived type */ - mrc = MPI_Type_vector((int)blk_size, (int)1, (int)((size_t)snbytes / buf_size), - mpi_partial_buffer_cont, &mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit contiguous file type */ - mrc = MPI_Type_commit(&mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build partial buffer derived type for interleaved access */ - mrc = MPI_Type_contiguous((int)blk_size, MPI_BYTE, &mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit partial buffer derived type */ - mrc = MPI_Type_commit(&mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build interleaved file's derived type */ - mrc = MPI_Type_vector((int)buf_size, (int)1, (int)((size_t)snbytes / blk_size), - mpi_partial_buffer_inter, &mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit interleaved file type */ - mrc = MPI_Type_commit(&mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full buffer derived type */ - mrc = MPI_Type_contiguous((int)(blk_size * buf_size), MPI_BYTE, &mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full buffer derived type */ - mrc = MPI_Type_commit(&mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build full chunk derived type */ - mrc = MPI_Type_contiguous((int)(blk_size * blk_size), MPI_BYTE, &mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit full chunk derived type */ - mrc = MPI_Type_commit(&mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - - /* Build chunk interleaved file's derived type */ - mrc = MPI_Type_vector((int)(buf_size / blk_size), (int)1, (int)((size_t)snbytes / blk_size), - mpi_full_chunk, &mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_CREATE"); - - /* Commit chunk interleaved file type */ - mrc = MPI_Type_commit(&mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_COMMIT"); - } /* end else */ - break; - - case PHDF5: /* HDF5 setup */ - /* 1D dataspace */ - if (!parms->dim2d) { - if (nbytes > 0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = (hsize_t)nbytes; - h5dset_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5stride[0] = h5block[0] = blk_size; - h5count[0] = buf_size / blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5stride[0] = blk_size * (size_t)pio_mpi_nprocs_g; - h5block[0] = blk_size; - h5count[0] = buf_size / blk_size; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, - h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if (buf_size > 0) { - h5dims[0] = buf_size; - h5mem_space_id = H5Screate_simple(1, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - if (nbytes > 0) { - /* define a contiguous dataset of nbytes native bytes */ - h5dims[0] = (hsize_t)snbytes; - h5dims[1] = (hsize_t)snbytes; - h5dset_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - /* Set up the file dset space id to select the pattern to access */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5start[1] = (hsize_t)bytes_begin[1]; - h5stride[0] = 1; - h5stride[1] = h5block[0] = h5block[1] = blk_size; - h5count[0] = 1; - h5count[1] = buf_size / blk_size; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5start[0] = (hsize_t)bytes_begin[0]; - h5start[1] = (hsize_t)bytes_begin[1]; - h5stride[0] = blk_size; - h5stride[1] = blk_size * (size_t)pio_mpi_nprocs_g; - h5block[0] = h5block[1] = blk_size; - h5count[0] = buf_size / blk_size; - h5count[1] = 1; - } /* end else */ - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, - h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - } /* end if */ - else { - h5dset_space_id = H5Screate(H5S_SCALAR); - VRFY((h5dset_space_id >= 0), "H5Screate"); - } /* end else */ - - /* Create the memory dataspace that corresponds to the xfer buffer */ - if (buf_size > 0) { - if (!parms->interleaved) { - h5dims[0] = blk_size; - h5dims[1] = buf_size; - } - else { - h5dims[0] = buf_size; - h5dims[1] = blk_size; - } - h5mem_space_id = H5Screate_simple(2, h5dims, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - } /* end if */ - else { - h5mem_space_id = H5Screate(H5S_SCALAR); - VRFY((h5mem_space_id >= 0), "H5Screate"); - } /* end else */ - } /* end else */ - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - /* Change to collective I/O, if asked */ - if (parms->collective) { - hrc = H5Pset_dxpl_mpio(h5dxpl, H5FD_MPIO_COLLECTIVE); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - break; - - default: - break; - } /* end switch */ - - for (ndset = 1; ndset <= ndsets; ++ndset) { - - /* Calculate dataset offset within a file */ - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - case MPIO: - /* both posix and mpi io just need dataset offset in file*/ - dset_offset = (ndset - 1) * nbytes; - break; - - case PHDF5: - HDsprintf(dname, "Dataset_%ld", ndset); - h5ds_id = H5DOPEN(fd->h5fd, dname); - if (h5ds_id < 0) { - HDfprintf(stderr, "HDF5 Dataset open failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - break; - } - - /* The task is to transfer bytes_count bytes, starting at - * bytes_begin position, using transfer buffer of buf_size bytes. - * If interleaved, select buf_size at a time, in round robin - * fashion, according to number of process. Otherwise, select - * all bytes_count in contiguous. - */ - nbytes_xfer = 0; - - /* 1D dataspace */ - if (!parms->dim2d) { - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset = dset_offset + bytes_begin[0]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0]); - } /* end if */ - else { - /* Set base file offset for all I/O patterns and POSIX access */ - posix_file_offset = dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]; - - /* Set base file offset for all I/O patterns and MPI access */ - mpi_file_offset = (MPI_Offset)(dset_offset + bytes_begin[0] * snbytes + bytes_begin[1]); - } /* end else */ - - /* Start "raw data" read timer */ - io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTART); - - while (nbytes_xfer < bytes_count) { - /* Read */ - /* Calculate offset of read within a dataset/file */ - switch (parms->io_type) { - case POSIXIO: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Contiguous pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + (off_t)nbytes_xfer; - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are read */ - rc = ((ssize_t)buf_size == POSIXREAD(fd->posixfd, buffer, buf_size)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to read */ - while (nbytes_toxfer > 0) { - /* Skip offset over blocks of other processes */ - file_offset = posix_file_offset + (off_t)(nbytes_xfer * pio_mpi_nprocs_g); - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are read */ - rc = ((ssize_t)blk_size == POSIXREAD(fd->posixfd, buf_p, blk_size)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance location in buffer */ - buf_p += blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + - (off_t)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * - (blk_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / blk_size) % (size_t)snbytes)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute file offset */ - file_offset = - posix_file_offset + - (off_t)(((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / - (size_t)snbytes) * - (buf_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % - (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = (off_t)snbytes; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute file offset */ - file_offset = posix_file_offset + (off_t)nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - file_offset_advance = 0; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute file offset */ - /* Before simplification */ - /* file_offset=posix_file_offset+(off_t)((nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))*(buf_size/blk_size - *snbytes/blk_size*(blk_size*blk_size))+((nbytes_xfer/(buf_size/blk_size)) - *pio_mpi_nprocs_g)%(snbytes/blk_size*(blk_size*blk_size))); */ - - file_offset = posix_file_offset + - (off_t)((((size_t)nbytes_xfer / (buf_size / blk_size) * - (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * blk_size)) * - (buf_size * (size_t)snbytes) + - (((size_t)nbytes_xfer / (buf_size / blk_size)) * - (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * blk_size)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* file_offset_advance = (off_t)(snbytes/blk_size*(blk_size*blk_size)); */ - file_offset_advance = (off_t)((size_t)snbytes * blk_size); - } /* end else */ - } /* end else */ - - /* Common code for file access */ - - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size * blk_size; - - /* Loop over portions of the buffer to read */ - while (nbytes_toxfer > 0) { - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, file_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - - /* check if all bytes are read */ - rc = ((ssize_t)nbytes_xfer_advance == - POSIXREAD(fd->posixfd, buf_p, nbytes_xfer_advance)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance location in buffer */ - buf_p += nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= nbytes_xfer_advance; - - /* Partially advance file offset */ - file_offset += file_offset_advance; - } /* end while */ - - } /* end else */ - break; - - case MPIO: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Independent file access */ - if (!parms->collective) { - /* Contiguous pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Perform independent read */ - mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buffer, - (int)(buf_size / blk_size), mpi_blk_type, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size; - - /* Loop over the buffers to read */ - while (nbytes_toxfer > 0) { - /* Skip offset over blocks of other processes */ - mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); - - /* Perform independent read */ - mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buf_p, (int)1, mpi_blk_type, - &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance location in buffer */ - buf_p += blk_size; - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)blk_size; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= blk_size; - } /* end while */ - } /* end else */ - } /* end if */ - /* Collective file access */ - else { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Perform collective read */ - mrc = MPI_File_read_at_all(fd->mpifd, mpi_offset, buffer, - (int)(buf_size / blk_size), mpi_blk_type, - &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + (nbytes_xfer * pio_mpi_nprocs_g); - - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, mpi_blk_type, mpi_file_type, - (char *)"native", h5_io_info_g); - VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform collective read */ - mrc = MPI_File_read_at_all(fd->mpifd, 0, buffer, (int)(buf_size / blk_size), - mpi_blk_type, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size; - } /* end else */ - } /* end else */ - } /* end if */ - /* 2D dataspace */ - else { - /* Contiguous storage */ - if (!parms->h5_use_chunks) { - /* Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = - mpi_file_offset + - (MPI_Offset)((((size_t)nbytes_xfer / blk_size) / (size_t)snbytes) * - (blk_size * (size_t)snbytes)) + - (MPI_Offset)(((size_t)nbytes_xfer / blk_size) % (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_cont_type; - } /* end if */ - /* Interleaved access pattern */ - else { - /* Compute offset in file */ - mpi_offset = - mpi_file_offset + - (MPI_Offset)( - ((((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) / - (size_t)snbytes) * - (buf_size * (size_t)snbytes)) + - (MPI_Offset)( - (((size_t)nbytes_xfer / buf_size) * (size_t)pio_mpi_nprocs_g) % - (size_t)snbytes); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = snbytes; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_inter_type; - } /* end else */ - } /* end if */ - /* Chunked storage */ - else { - /*Contiguous access pattern */ - if (!parms->interleaved) { - /* Compute offset in file */ - mpi_offset = mpi_file_offset + nbytes_xfer; - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * buf_size; - - /* Global offset advance after each I/O operation */ - mpi_offset_advance = 0; - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_full_buffer; - } /* end if */ - /*Interleaved access pattern */ - else { - /* Compute offset in file */ - /* Before simplification */ - /* mpi_offset=mpi_file_offset+(nbytes_xfer/(buf_size/blk_size) - *pio_mpi_nprocs_g)/(snbytes/blk_size*(blk_size*blk_size))* - (buf_size/blk_size*snbytes/blk_size*(blk_size*blk_size))+ - ((nbytes_xfer/(buf_size/blk_size))*pio_mpi_nprocs_g)%(snbytes - /blk_size*(blk_size*blk_size)); */ - mpi_offset = mpi_file_offset + - (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size) * - (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * blk_size)) * - (buf_size * (size_t)snbytes)) + - (MPI_Offset)((((size_t)nbytes_xfer / (buf_size / blk_size)) * - (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * blk_size)); - - /* Number of bytes to be transferred per I/O operation */ - nbytes_xfer_advance = blk_size * blk_size; - - /* Global offset advance after each I/O operation */ - /* mpi_offset_advance = (MPI_Offset)(snbytes/blk_size*(blk_size*blk_size)); */ - mpi_offset_advance = (MPI_Offset)((size_t)snbytes * blk_size); - - /* MPI type to be used for collective access */ - mpi_collective_type = mpi_chunk_inter_type; - } /* end else */ - } /* end else */ - - /* Common code for independent file access */ - if (!parms->collective) { - /* Set the base of user's buffer */ - buf_p = (unsigned char *)buffer; - - /* Set the number of bytes to transfer this time */ - nbytes_toxfer = buf_size * blk_size; - - /* Loop over portions of the buffer to read */ - while (nbytes_toxfer > 0) { - /* Perform independent read */ - mrc = MPI_File_read_at(fd->mpifd, mpi_offset, buf_p, (int)nbytes_xfer_advance, - MPI_BYTE, &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance location in buffer */ - buf_p += nbytes_xfer_advance; - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)nbytes_xfer_advance; - - /* Decrement number of bytes left this time */ - nbytes_toxfer -= nbytes_xfer_advance; - - /* Partially advance global offset in dataset */ - mpi_offset += mpi_offset_advance; - } /* end while */ - } /* end if */ - - /* Common code for collective file access */ - else { - /* Set the file view */ - mrc = MPI_File_set_view(fd->mpifd, mpi_offset, MPI_BYTE, mpi_collective_type, - (char *)"native", h5_io_info_g); - VRFY((mrc == MPI_SUCCESS), "MPIO_VIEW"); - - /* Perform read */ - MPI_File_read_at_all(fd->mpifd, 0, buffer, (int)(buf_size * blk_size), MPI_BYTE, - &mpi_status); - VRFY((mrc == MPI_SUCCESS), "MPIO_READ"); - - /* Advance global offset in dataset */ - nbytes_xfer += (off_t)buf_size * (off_t)blk_size; - } /* end else */ - - } /* end else */ - break; - - case PHDF5: - /* 1D dataspace */ - if (!parms->dim2d) { - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5offset[0] = nbytes_xfer; - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = (nbytes_xfer * pio_mpi_nprocs_g); - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Read the buffer in */ - hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dread"); - - /* Increment number of bytes transferred */ - nbytes_xfer += (off_t)buf_size; - } /* end if */ - /* 2D dataspace */ - else { - /* Set up the file dset space id to move the selection to process */ - if (!parms->interleaved) { - /* Contiguous pattern */ - h5offset[0] = - (hssize_t)(((size_t)nbytes_xfer / ((size_t)snbytes * blk_size)) * blk_size); - h5offset[1] = - (hssize_t)(((size_t)nbytes_xfer % ((size_t)snbytes * blk_size)) / blk_size); - } /* end if */ - else { - /* Interleaved access pattern */ - /* Skip offset over blocks of other processes */ - h5offset[0] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) / - ((size_t)snbytes * buf_size)) * - buf_size); - h5offset[1] = (hssize_t)((((size_t)nbytes_xfer * (size_t)pio_mpi_nprocs_g) % - ((size_t)snbytes * buf_size)) / - buf_size); - - } /* end else */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dread"); - - /* Increment number of bytes transferred */ - nbytes_xfer += (off_t)buf_size * (off_t)blk_size; - - } /* end else */ - break; - - default: - break; - } /* switch (parms->io_type) */ - - /* Verify raw data, if asked */ - if (parms->verify) { - /* Verify data read */ - unsigned char *ucharptr = (unsigned char *)buffer; - size_t i; - int nerror = 0; - - for (i = 0; i < bsize; ++i) { - if (*ucharptr++ != pio_mpi_rank_g + 1) { - if (++nerror < 20) { - /* report at most 20 errors */ - HDprint_rank(output); - HDfprintf(output, - "read data error, expected (%d), " - "got (%d)\n", - pio_mpi_rank_g + 1, (int)*(ucharptr - 1)); - } /* end if */ - } /* end if */ - } /* end for */ - if (nerror >= 20) { - HDprint_rank(output); - HDfprintf(output, "..."); - HDfprintf(output, "total read data errors=%d\n", nerror); - } /* end if */ - } /* if (parms->verify) */ - - } /* end while */ - - /* Stop "raw data" read timer */ - io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTOP); - - /* Calculate read time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == PHDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = H5I_INVALID_HID; - } /* end if */ - } /* end for */ - -done: - /* release MPI-I/O objects */ - if (parms->io_type == MPIO) { - /* 1D dataspace */ - if (!parms->dim2d) { - /* Free file type */ - mrc = MPI_Type_free(&mpi_file_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free buffer type */ - mrc = MPI_Type_free(&mpi_blk_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end if */ - /* 2D dataspace */ - else { - /* Free partial buffer type for contiguous access */ - mrc = MPI_Type_free(&mpi_partial_buffer_cont); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free contiguous file type */ - mrc = MPI_Type_free(&mpi_cont_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free partial buffer type for interleaved access */ - mrc = MPI_Type_free(&mpi_partial_buffer_inter); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free interleaved file type */ - mrc = MPI_Type_free(&mpi_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full buffer type */ - mrc = MPI_Type_free(&mpi_full_buffer); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free full chunk type */ - mrc = MPI_Type_free(&mpi_full_chunk); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - - /* Free chunk interleaved file type */ - mrc = MPI_Type_free(&mpi_chunk_inter_type); - VRFY((mrc == MPI_SUCCESS), "MPIO_TYPE_FREE"); - } /* end else */ - } /* end if */ - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } - else { - h5dset_space_id = H5I_INVALID_HID; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } - else { - h5mem_space_id = H5I_INVALID_HID; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } - else { - h5dxpl = H5I_INVALID_HID; - } - } - - return ret_code; -} - -/* - * Function: do_fopen - * Purpose: Open the specified file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - */ -static herr_t -do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags) -{ - int ret_code = SUCCESS, mrc; - hid_t acc_tpl = H5I_INVALID_HID; /* file access templates */ - - switch (param->io_type) { - case POSIXIO: - if (flags & (PIO_CREATE | PIO_WRITE)) - fd->posixfd = POSIXCREATE(fname); - else - fd->posixfd = POSIXOPEN(fname, O_RDONLY); - - if (fd->posixfd < 0) { - HDfprintf(stderr, "POSIX File Open failed(%s)\n", fname); - GOTOERROR(FAIL); - } - - /* The perils of POSIX I/O in a parallel environment. The problem is: - * - * - Process n opens a file with truncation and then starts - * writing to the file. - * - Process m also opens the file with truncation, but after - * process n has already started to write to the file. Thus, - * all of the stuff process n wrote is now lost. - */ - MPI_Barrier(pio_comm_g); - - break; - - case MPIO: - if (flags & (PIO_CREATE | PIO_WRITE)) { - MPI_File_delete(fname, h5_io_info_g); - mrc = MPI_File_open(pio_comm_g, fname, MPI_MODE_CREATE | MPI_MODE_RDWR, h5_io_info_g, - &fd->mpifd); - - if (mrc != MPI_SUCCESS) { - HDfprintf(stderr, "MPI File Open failed(%s)\n", fname); - GOTOERROR(FAIL); - } - - /*since MPI_File_open with MPI_MODE_CREATE does not truncate */ - /*filesize , set size to 0 explicitedly. */ - mrc = MPI_File_set_size(fd->mpifd, (MPI_Offset)0); - if (mrc != MPI_SUCCESS) { - HDfprintf(stderr, "MPI_File_set_size failed\n"); - GOTOERROR(FAIL); - } - } - else { - mrc = MPI_File_open(pio_comm_g, fname, MPI_MODE_RDONLY, h5_io_info_g, &fd->mpifd); - if (mrc != MPI_SUCCESS) { - HDfprintf(stderr, "MPI File Open failed(%s)\n", fname); - GOTOERROR(FAIL); - } - } - - break; - - case PHDF5: - if ((acc_tpl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - /* Set the file driver to the MPI-IO driver */ - if (H5Pset_fapl_mpio(acc_tpl, pio_comm_g, h5_io_info_g) < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } - - /* Set the alignment of objects in HDF5 file */ - if (H5Pset_alignment(acc_tpl, param->h5_thresh, param->h5_align) < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } - - /* create the parallel file */ - if (flags & (PIO_CREATE | PIO_WRITE)) - fd->h5fd = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl); - else - fd->h5fd = H5Fopen(fname, H5F_ACC_RDONLY, acc_tpl); - if (fd->h5fd < 0) { - HDfprintf(stderr, "HDF5 File Create failed(%s)\n", fname); - GOTOERROR(FAIL); - } - - /* verifying the close of the acc_tpl */ - if (H5Pclose(acc_tpl) < 0) { - HDfprintf(stderr, "HDF5 Property List Close failed\n"); - GOTOERROR(FAIL); - } - - break; - - default: - break; - } - -done: - return ret_code; -} - -/* - * Function: do_fclose - * Purpose: Close the specified file descriptor. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - */ -static herr_t -do_fclose(iotype iot, file_descr *fd /*out*/) -{ - herr_t ret_code = SUCCESS, hrc; - int mrc = 0, rc = 0; - - switch (iot) { - case POSIXIO: - rc = POSIXCLOSE(fd->posixfd); - - if (rc != 0) { - HDfprintf(stderr, "POSIX File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->posixfd = -1; - break; - - case MPIO: - mrc = MPI_File_close(&fd->mpifd); - - if (mrc != MPI_SUCCESS) { - HDfprintf(stderr, "MPI File close failed\n"); - GOTOERROR(FAIL); - } - - fd->mpifd = MPI_FILE_NULL; - break; - - case PHDF5: - hrc = H5Fclose(fd->h5fd); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->h5fd = -1; - break; - - default: - break; - } - -done: - return ret_code; -} - -/* - * Function: do_fclose - * Purpose: Cleanup temporary file unless HDF5_NOCLEANUP is set. - * Only Proc 0 of the PIO communicator will do the cleanup. - * Other processes just return. - * Return: void - * Programmer: Albert Cheng 2001/12/12 - * Modifications: - */ -static void -do_cleanupfile(iotype iot, char *fname) -{ - if (pio_mpi_rank_g != 0) - return; - - if (clean_file_g == -1) - clean_file_g = (getenv("HDF5_NOCLEANUP") == NULL) ? 1 : 0; - - if (clean_file_g) { - switch (iot) { - case POSIXIO: - HDremove(fname); - break; - case MPIO: - case PHDF5: - MPI_File_delete(fname, h5_io_info_g); - break; - default: - break; - } - } -} - -#ifdef TIME_MPI -/* instrument the MPI_File_wrirte_xxx and read_xxx calls to measure - * pure time spent in MPI_File code. - */ -int -MPI_File_read_at(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, - MPI_Status *status) -{ - int err; - io_time_set(timer_g, HDF5_MPI_READ, TSTART); - err = PMPI_File_read_at(fh, offset, buf, count, datatype, status); - io_time_set(timer_g, HDF5_MPI_READ, TSTOP); - return err; -} - -int -MPI_File_read_at_all(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, - MPI_Status *status) -{ - int err; - io_time_set(timer_g, HDF5_MPI_READ, TSTART); - err = PMPI_File_read_at_all(fh, offset, buf, count, datatype, status); - io_time_set(timer_g, HDF5_MPI_READ, TSTOP); - return err; -} - -int -MPI_File_write_at(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, - MPI_Status *status) -{ - int err; - io_time_set(timer_g, HDF5_MPI_WRITE, TSTART); - err = PMPI_File_write_at(fh, offset, buf, count, datatype, status); - io_time_set(timer_g, HDF5_MPI_WRITE, TSTOP); - return err; -} - -int -MPI_File_write_at_all(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype, - MPI_Status *status) -{ - int err; - io_time_set(timer_g, HDF5_MPI_WRITE, TSTART); - err = PMPI_File_write_at_all(fh, offset, buf, count, datatype, status); - io_time_set(timer_g, HDF5_MPI_WRITE, TSTOP); - return err; -} - -#endif /* TIME_MPI */ -#endif /* H5_HAVE_PARALLEL */ diff --git a/tools/test/perform/pio_perf.c b/tools/test/perform/pio_perf.c deleted file mode 100644 index d38c574..0000000 --- a/tools/test/perform/pio_perf.c +++ /dev/null @@ -1,1699 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Parallel HDF5 Performance Testing Code - * -------------------------------------- - * - * Portable code to test performance on the different platforms we support. - * This is what the report should look like: - * - * nprocs = Max#Procs - * IO API = POSIXIO - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * IO API = MPIO - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * IO API = PHDF5 - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * nprocs = Max#Procs / 2 - * - * . . . - * - */ - -/* system header files */ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> - -#include "hdf5.h" - -#ifdef H5_HAVE_PARALLEL - -/* library header files */ -#include <mpi.h> - -/* our header files */ -#include "pio_perf.h" - -/* useful macros */ -#define TAB_SPACE 4 - -#define ONE_KB 1024 -#define ONE_MB (ONE_KB * ONE_KB) -#define ONE_GB (ONE_MB * ONE_KB) - -#define PIO_POSIX 0x1 -#define PIO_MPI 0x2 -#define PIO_HDF5 0x4 - -#ifdef STANDALONE -#define DBL_EPSILON 2.2204460492503131e-16 -#define H5_DBL_ABS_EQUAL(X, Y) (fabs((X) - (Y)) < DBL_EPSILON) -#endif - -/* report 0.0 in case t is zero too */ -#define MB_PER_SEC(bytes, t) (H5_DBL_ABS_EQUAL((t), 0.0) ? 0.0 : ((((double)bytes) / ONE_MB) / (t))) - -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE (!TRUE) -#endif /* FALSE */ - -/* global variables */ -FILE * output; /* output file */ -int comm_world_rank_g; /* my rank in MPI_COMM_RANK */ -int comm_world_nprocs_g; /* num. of processes of MPI_COMM_WORLD */ -MPI_Comm pio_comm_g; /* Communicator to run the PIO */ -int pio_mpi_rank_g; /* MPI rank of pio_comm_g */ -int pio_mpi_nprocs_g; /* Number of processes of pio_comm_g */ -int pio_debug_level = 0; /* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Maximal & then some - */ - -/* local variables */ -static const char *progname = "h5perf"; - -/* - * Command-line options: The user can specify short or long-named - * parameters. The long-named ones can be partially spelled. When - * adding more, make sure that they don't clash with each other. - */ -#if 1 -static const char *s_opts = "a:A:B:cCd:D:e:F:ghi:Imno:p:P:stT:wx:X:"; -#else -static const char *s_opts = "a:A:bB:cCd:D:e:F:ghi:Imno:p:P:stT:wx:X:"; -#endif /* 1 */ -static struct h5_long_options l_opts[] = {{"align", require_arg, 'a'}, - {"alig", require_arg, 'a'}, - {"ali", require_arg, 'a'}, - {"al", require_arg, 'a'}, - {"api", require_arg, 'A'}, - {"ap", require_arg, 'A'}, -#if 0 - /* a sighting of the elusive binary option */ - { "binary", no_arg, 'b' }, - { "binar", no_arg, 'b' }, - { "bina", no_arg, 'b' }, - { "bin", no_arg, 'b' }, - { "bi", no_arg, 'b' }, -#endif /* 0 */ - {"block-size", require_arg, 'B'}, - {"block-siz", require_arg, 'B'}, - {"block-si", require_arg, 'B'}, - {"block-s", require_arg, 'B'}, - {"block-", require_arg, 'B'}, - {"block", require_arg, 'B'}, - {"bloc", require_arg, 'B'}, - {"blo", require_arg, 'B'}, - {"bl", require_arg, 'B'}, - {"chunk", no_arg, 'c'}, - {"chun", no_arg, 'c'}, - {"chu", no_arg, 'c'}, - {"ch", no_arg, 'c'}, - {"collective", no_arg, 'C'}, - {"collectiv", no_arg, 'C'}, - {"collecti", no_arg, 'C'}, - {"collect", no_arg, 'C'}, - {"collec", no_arg, 'C'}, - {"colle", no_arg, 'C'}, - {"coll", no_arg, 'C'}, - {"col", no_arg, 'C'}, - {"co", no_arg, 'C'}, - {"debug", require_arg, 'D'}, - {"debu", require_arg, 'D'}, - {"deb", require_arg, 'D'}, - {"de", require_arg, 'D'}, - {"geometry", no_arg, 'g'}, - {"geometr", no_arg, 'g'}, - {"geomet", no_arg, 'g'}, - {"geome", no_arg, 'g'}, - {"geom", no_arg, 'g'}, - {"geo", no_arg, 'g'}, - {"ge", no_arg, 'g'}, - {"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, - {"he", no_arg, 'h'}, - {"interleaved", require_arg, 'I'}, - {"interleave", require_arg, 'I'}, - {"interleav", require_arg, 'I'}, - {"interlea", require_arg, 'I'}, - {"interle", require_arg, 'I'}, - {"interl", require_arg, 'I'}, - {"inter", require_arg, 'I'}, - {"inte", require_arg, 'I'}, - {"int", require_arg, 'I'}, - {"in", require_arg, 'I'}, - {"max-num-processes", require_arg, 'P'}, - {"max-num-processe", require_arg, 'P'}, - {"max-num-process", require_arg, 'P'}, - {"max-num-proces", require_arg, 'P'}, - {"max-num-proce", require_arg, 'P'}, - {"max-num-proc", require_arg, 'P'}, - {"max-num-pro", require_arg, 'P'}, - {"max-num-pr", require_arg, 'P'}, - {"max-num-p", require_arg, 'P'}, - {"min-num-processes", require_arg, 'p'}, - {"min-num-processe", require_arg, 'p'}, - {"min-num-process", require_arg, 'p'}, - {"min-num-proces", require_arg, 'p'}, - {"min-num-proce", require_arg, 'p'}, - {"min-num-proc", require_arg, 'p'}, - {"min-num-pro", require_arg, 'p'}, - {"min-num-pr", require_arg, 'p'}, - {"min-num-p", require_arg, 'p'}, - {"max-xfer-size", require_arg, 'X'}, - {"max-xfer-siz", require_arg, 'X'}, - {"max-xfer-si", require_arg, 'X'}, - {"max-xfer-s", require_arg, 'X'}, - {"max-xfer", require_arg, 'X'}, - {"max-xfe", require_arg, 'X'}, - {"max-xf", require_arg, 'X'}, - {"max-x", require_arg, 'X'}, - {"min-xfer-size", require_arg, 'x'}, - {"min-xfer-siz", require_arg, 'x'}, - {"min-xfer-si", require_arg, 'x'}, - {"min-xfer-s", require_arg, 'x'}, - {"min-xfer", require_arg, 'x'}, - {"min-xfe", require_arg, 'x'}, - {"min-xf", require_arg, 'x'}, - {"min-x", require_arg, 'x'}, - {"num-bytes", require_arg, 'e'}, - {"num-byte", require_arg, 'e'}, - {"num-byt", require_arg, 'e'}, - {"num-by", require_arg, 'e'}, - {"num-b", require_arg, 'e'}, - {"num-dsets", require_arg, 'd'}, - {"num-dset", require_arg, 'd'}, - {"num-dse", require_arg, 'd'}, - {"num-ds", require_arg, 'd'}, - {"num-d", require_arg, 'd'}, - {"num-files", require_arg, 'F'}, - {"num-file", require_arg, 'F'}, - {"num-fil", require_arg, 'F'}, - {"num-fi", require_arg, 'F'}, - {"num-f", require_arg, 'F'}, - {"num-iterations", require_arg, 'i'}, - {"num-iteration", require_arg, 'i'}, - {"num-iteratio", require_arg, 'i'}, - {"num-iterati", require_arg, 'i'}, - {"num-iterat", require_arg, 'i'}, - {"num-itera", require_arg, 'i'}, - {"num-iter", require_arg, 'i'}, - {"num-ite", require_arg, 'i'}, - {"num-it", require_arg, 'i'}, - {"num-i", require_arg, 'i'}, - {"output", require_arg, 'o'}, - {"outpu", require_arg, 'o'}, - {"outp", require_arg, 'o'}, - {"out", require_arg, 'o'}, - {"ou", require_arg, 'o'}, - {"threshold", require_arg, 'T'}, - {"threshol", require_arg, 'T'}, - {"thresho", require_arg, 'T'}, - {"thresh", require_arg, 'T'}, - {"thres", require_arg, 'T'}, - {"thre", require_arg, 'T'}, - {"thr", require_arg, 'T'}, - {"th", require_arg, 'T'}, - {"write-only", require_arg, 'w'}, - {"write-onl", require_arg, 'w'}, - {"write-on", require_arg, 'w'}, - {"write-o", require_arg, 'w'}, - {"write", require_arg, 'w'}, - {"writ", require_arg, 'w'}, - {"wri", require_arg, 'w'}, - {"wr", require_arg, 'w'}, - {NULL, 0, '\0'}}; - -struct options { - long io_types; /* bitmask of which I/O types to test */ - const char *output_file; /* file to print report to */ - long num_dsets; /* number of datasets */ - long num_files; /* number of files */ - off_t num_bpp; /* number of bytes per proc per dset */ - int num_iters; /* number of iterations */ - int max_num_procs; /* maximum number of processes to use */ - int min_num_procs; /* minimum number of processes to use */ - size_t max_xfer_size; /* maximum transfer buffer size */ - size_t min_xfer_size; /* minimum transfer buffer size */ - size_t blk_size; /* Block size */ - unsigned interleaved; /* Interleaved vs. contiguous blocks */ - unsigned collective; /* Collective vs. independent I/O */ - unsigned dim2d; /* 1D vs. 2D geometry */ - int print_times; /* print times as well as throughputs */ - int print_raw; /* print raw data throughput info */ - off_t h5_alignment; /* alignment in HDF5 file */ - off_t h5_threshold; /* threshold for alignment in HDF5 file */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int verify; /* Verify data correctness */ -}; - -typedef struct _minmax { - double min; - double max; - double sum; - int num; -} minmax; - -/* local functions */ -static off_t parse_size_directive(const char *size); -static struct options *parse_command_line(int argc, char *argv[]); -static void run_test_loop(struct options *options); -static int run_test(iotype iot, parameters parms, struct options *opts); -static void output_all_info(minmax *mm, int count, int indent_level); -static void get_minmax(minmax *mm, double val); -static minmax accumulate_minmax_stuff(minmax *mm, int count); -static int create_comm_world(int num_procs, int *doing_pio); -static int destroy_comm_world(void); -static void output_results(const struct options *options, const char *name, minmax *table, int table_size, - off_t data_size); -static void output_times(const struct options *options, const char *name, minmax *table, int table_size); -static void output_report(const char *fmt, ...); -static void print_indent(register int indent); -static void usage(const char *prog); -static void report_parameters(struct options *opts); -static off_t squareo(off_t); - -/* - * Function: main - * Purpose: Start things up. Initialize MPI and then call the test looping - * function. - * Return: EXIT_SUCCESS or EXIT_FAILURE - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - */ -int -main(int argc, char *argv[]) -{ - int ret; - int exit_value = EXIT_SUCCESS; - struct options *opts = NULL; - -#ifndef STANDALONE - /* Initialize h5tools lib */ - h5tools_init(); -#endif - - output = stdout; - - /* initialize MPI and get the maximum num of processors we started with */ - MPI_Init(&argc, &argv); - ret = MPI_Comm_size(MPI_COMM_WORLD, &comm_world_nprocs_g); - - if (ret != MPI_SUCCESS) { - HDfprintf(stderr, "%s: MPI_Comm_size call failed\n", progname); - - if (ret == MPI_ERR_COMM) - HDfprintf(stderr, "invalid MPI communicator\n"); - else - HDfprintf(stderr, "invalid argument\n"); - - exit_value = EXIT_FAILURE; - goto finish; - } - - ret = MPI_Comm_rank(MPI_COMM_WORLD, &comm_world_rank_g); - - if (ret != MPI_SUCCESS) { - HDfprintf(stderr, "%s: MPI_Comm_rank call failed\n", progname); - - if (ret == MPI_ERR_COMM) - HDfprintf(stderr, "invalid MPI communicator\n"); - else - HDfprintf(stderr, "invalid argument\n"); - - exit_value = EXIT_FAILURE; - goto finish; - } - - pio_comm_g = MPI_COMM_WORLD; - - h5_set_info_object(); - opts = parse_command_line(argc, argv); - - if (!opts) { - exit_value = EXIT_FAILURE; - goto finish; - } - - if (opts->output_file) { - if ((output = HDfopen(opts->output_file, "w")) == NULL) { - HDfprintf(stderr, "%s: cannot open output file\n", progname); - perror(opts->output_file); - goto finish; - } - } - - if ((pio_debug_level == 0 && comm_world_rank_g == 0) || pio_debug_level > 0) - report_parameters(opts); - - run_test_loop(opts); - -finish: - MPI_Finalize(); - free(opts); - return exit_value; -} - -off_t -squareo(off_t x) -{ - return x * x; -} - -/* - * Function: run_test_loop - * Purpose: Run the I/O tests. Write the results to OUTPUT. - * - * - The slowest changing part of the test is the number of - * processors to use. For each loop iteration, we divide that - * number by 2 and rerun the test. - * - * - The second slowest is what type of IO API to perform. We have - * three choices: POSIXIO, MPI-IO, and PHDF5. - * - * - Then we change the size of the buffer. This information is - * inferred from the number of datasets to create and the number - * of integers to put into each dataset. The backend code figures - * this out. - * - * Return: Nothing - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static void -run_test_loop(struct options *opts) -{ - parameters parms; - int num_procs; - int doing_pio; /* if this process is doing PIO */ - - parms.num_files = opts->num_files; - parms.num_dsets = opts->num_dsets; - parms.num_iters = opts->num_iters; - parms.blk_size = opts->blk_size; - parms.interleaved = opts->interleaved; - parms.collective = opts->collective; - parms.dim2d = opts->dim2d; - parms.h5_align = (hsize_t)opts->h5_alignment; - parms.h5_thresh = (hsize_t)opts->h5_threshold; - parms.h5_use_chunks = opts->h5_use_chunks; - parms.h5_write_only = opts->h5_write_only; - parms.verify = opts->verify; - - /* start with max_num_procs and decrement it by half for each loop. */ - /* if performance needs restart, fewer processes may be needed. */ - for (num_procs = opts->max_num_procs; num_procs >= opts->min_num_procs; num_procs >>= 1) { - register size_t buf_size; - - parms.num_procs = num_procs; - - if (create_comm_world(parms.num_procs, &doing_pio) != SUCCESS) { - /* do something harsh */ - } - - /* only processes doing PIO will run the tests */ - if (doing_pio) { - output_report("Number of processors = %ld\n", parms.num_procs); - - /* multiply the xfer buffer size by 2 for each loop iteration */ - for (buf_size = opts->min_xfer_size; buf_size <= opts->max_xfer_size; buf_size <<= 1) { - parms.buf_size = buf_size; - - if (parms.dim2d) { - parms.num_bytes = squareo(opts->num_bpp * parms.num_procs); - if (parms.interleaved) - output_report("Transfer Buffer Size: %ldx%ld bytes, File size: %.2f MB\n", buf_size, - opts->blk_size, - ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); - else - output_report("Transfer Buffer Size: %ldx%ld bytes, File size: %.2f MB\n", - opts->blk_size, buf_size, - ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); - - print_indent(1); - output_report(" # of files: %ld, # of datasets: %ld, dataset size: %.2fx%.2f KB\n", - parms.num_files, parms.num_dsets, - (double)(opts->num_bpp * parms.num_procs) / ONE_KB, - (double)(opts->num_bpp * parms.num_procs) / ONE_KB); - } - else { - parms.num_bytes = (off_t)opts->num_bpp * parms.num_procs; - output_report("Transfer Buffer Size: %ld bytes, File size: %.2f MB\n", buf_size, - ((double)parms.num_dsets * (double)parms.num_bytes) / ONE_MB); - - print_indent(1); - output_report(" # of files: %ld, # of datasets: %ld, dataset size: %.2f MB\n", - parms.num_files, parms.num_dsets, - (double)(opts->num_bpp * parms.num_procs) / ONE_MB); - } - - if (opts->io_types & PIO_POSIX) - run_test(POSIXIO, parms, opts); - - if (opts->io_types & PIO_MPI) - run_test(MPIO, parms, opts); - - if (opts->io_types & PIO_HDF5) - run_test(PHDF5, parms, opts); - - /* Run the tests once if buf_size==0, but then break out */ - if (buf_size == 0) - break; - } - - if (destroy_comm_world() != SUCCESS) { - /* do something harsh */ - } - } - } -} - -/* - * Function: run_test - * Purpose: Inner loop call to actually run the I/O test. - * Return: Nothing - * Programmer: Bill Wendling, 18. December 2001 - * Modifications: - */ -static int -run_test(iotype iot, parameters parms, struct options *opts) -{ - results res; - register int i, ret_value = SUCCESS; - int comm_size; - off_t raw_size; - minmax * write_mpi_mm_table = NULL; - minmax * write_mm_table = NULL; - minmax * write_gross_mm_table = NULL; - minmax * write_raw_mm_table = NULL; - minmax * read_mpi_mm_table = NULL; - minmax * read_mm_table = NULL; - minmax * read_gross_mm_table = NULL; - minmax * read_raw_mm_table = NULL; - minmax * read_open_mm_table = NULL; - minmax * read_close_mm_table = NULL; - minmax * write_open_mm_table = NULL; - minmax * write_close_mm_table = NULL; - minmax write_mpi_mm = {0.0, 0.0, 0.0, 0}; - minmax write_mm = {0.0, 0.0, 0.0, 0}; - minmax write_gross_mm = {0.0, 0.0, 0.0, 0}; - minmax write_raw_mm = {0.0, 0.0, 0.0, 0}; - minmax read_mpi_mm = {0.0, 0.0, 0.0, 0}; - minmax read_mm = {0.0, 0.0, 0.0, 0}; - minmax read_gross_mm = {0.0, 0.0, 0.0, 0}; - minmax read_raw_mm = {0.0, 0.0, 0.0, 0}; - minmax read_open_mm = {0.0, 0.0, 0.0, 0}; - minmax read_close_mm = {0.0, 0.0, 0.0, 0}; - minmax write_open_mm = {0.0, 0.0, 0.0, 0}; - minmax write_close_mm = {0.0, 0.0, 0.0, 0}; - - raw_size = parms.num_files * (off_t)parms.num_dsets * (off_t)parms.num_bytes; - parms.io_type = iot; - print_indent(2); - output_report("IO API = "); - - switch (iot) { - case POSIXIO: - output_report("POSIX\n"); - break; - case MPIO: - output_report("MPIO\n"); - break; - case PHDF5: - output_report("PHDF5 (w/MPI-IO driver)\n"); - break; - default: - break; - } - - MPI_Comm_size(pio_comm_g, &comm_size); - - /* allocate space for tables minmax and that it is sufficient */ - /* to initialize all elements to zeros by calloc. */ - write_mpi_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - write_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - write_gross_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - write_raw_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - write_open_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - write_close_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - if (!parms.h5_write_only) { - read_mpi_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - read_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - read_gross_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - read_raw_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - read_open_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - read_close_mm_table = calloc((size_t)parms.num_iters, sizeof(minmax)); - } - - /* Do IO iteration times, collecting statistics each time */ - for (i = 0; i < parms.num_iters; ++i) { - double t; - - MPI_Barrier(pio_comm_g); - res = do_pio(parms); - - /* gather all of the "mpi write" times */ - t = io_time_get(res.timers, HDF5_MPI_WRITE); - get_minmax(&write_mpi_mm, t); - - write_mpi_mm_table[i] = write_mpi_mm; - - /* gather all of the "write" times */ - t = io_time_get(res.timers, HDF5_FINE_WRITE_FIXED_DIMS); - get_minmax(&write_mm, t); - - write_mm_table[i] = write_mm; - - /* gather all of the "write" times from open to close */ - t = io_time_get(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS); - get_minmax(&write_gross_mm, t); - - write_gross_mm_table[i] = write_gross_mm; - - /* gather all of the raw "write" times */ - t = io_time_get(res.timers, HDF5_RAW_WRITE_FIXED_DIMS); - get_minmax(&write_raw_mm, t); - - write_raw_mm_table[i] = write_raw_mm; - - /* gather all of the file open times (time from open to first write) */ - t = io_time_get(res.timers, HDF5_FILE_WRITE_OPEN); - get_minmax(&write_open_mm, t); - - write_open_mm_table[i] = write_open_mm; - - /* gather all of the file close times (time from last write to close) */ - t = io_time_get(res.timers, HDF5_FILE_WRITE_CLOSE); - get_minmax(&write_close_mm, t); - - write_close_mm_table[i] = write_close_mm; - - if (!parms.h5_write_only) { - /* gather all of the "mpi read" times */ - t = io_time_get(res.timers, HDF5_MPI_READ); - get_minmax(&read_mpi_mm, t); - - read_mpi_mm_table[i] = read_mpi_mm; - - /* gather all of the "read" times */ - t = io_time_get(res.timers, HDF5_FINE_READ_FIXED_DIMS); - get_minmax(&read_mm, t); - - read_mm_table[i] = read_mm; - - /* gather all of the "read" times from open to close */ - t = io_time_get(res.timers, HDF5_GROSS_READ_FIXED_DIMS); - get_minmax(&read_gross_mm, t); - - read_gross_mm_table[i] = read_gross_mm; - - /* gather all of the raw "read" times */ - t = io_time_get(res.timers, HDF5_RAW_READ_FIXED_DIMS); - get_minmax(&read_raw_mm, t); - - read_raw_mm_table[i] = read_raw_mm; - - /* gather all of the file open times (time from open to first read) */ - t = io_time_get(res.timers, HDF5_FILE_READ_OPEN); - get_minmax(&read_open_mm, t); - - read_open_mm_table[i] = read_open_mm; - - /* gather all of the file close times (time from last read to close) */ - t = io_time_get(res.timers, HDF5_FILE_READ_CLOSE); - get_minmax(&read_close_mm, t); - - read_close_mm_table[i] = read_close_mm; - } - - io_time_destroy(res.timers); - } - - /* - * Show various statistics - */ - /* Write statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw write" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Write details:\n"); - output_all_info(write_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Raw Data Write", write_raw_mm_table, parms.num_iters, raw_size); - } /* end if */ - - /* show mpi write statics */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Write details:\n"); - output_all_info(write_mpi_mm_table, parms.num_iters, 4); - } - - /* We don't currently output the MPI write results */ - - /* accumulate and output the max, min, and average "write" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write details:\n"); - output_all_info(write_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Write", write_mm_table, parms.num_iters, raw_size); - - /* accumulate and output the max, min, and average "gross write" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write Open-Close details:\n"); - output_all_info(write_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Write Open-Close", write_gross_mm_table, parms.num_iters, raw_size); - - if (opts->print_times) { - output_times(opts, "Write File Open", write_open_mm_table, parms.num_iters); - output_times(opts, "Write File Close", write_close_mm_table, parms.num_iters); - } - - /* Print out time from open to first write */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write file open details:\n"); - output_all_info(write_open_mm_table, parms.num_iters, 4); - } - - /* Print out time from last write to close */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write file close details:\n"); - output_all_info(write_close_mm_table, parms.num_iters, 4); - } - - if (!parms.h5_write_only) { - /* Read statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw read" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Read details:\n"); - output_all_info(read_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Raw Data Read", read_raw_mm_table, parms.num_iters, raw_size); - } /* end if */ - - /* show mpi read statics */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Read details:\n"); - output_all_info(read_mpi_mm_table, parms.num_iters, 4); - } - - /* We don't currently output the MPI read results */ - - /* accumulate and output the max, min, and average "read" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read details:\n"); - output_all_info(read_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read", read_mm_table, parms.num_iters, raw_size); - - /* accumulate and output the max, min, and average "gross read" times */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read Open-Close details:\n"); - output_all_info(read_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read Open-Close", read_gross_mm_table, parms.num_iters, raw_size); - - if (opts->print_times) { - output_times(opts, "Read File Open", read_open_mm_table, parms.num_iters); - output_times(opts, "Read File Close", read_close_mm_table, parms.num_iters); - } - - /* Print out time from open to first read */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read file open details:\n"); - output_all_info(read_open_mm_table, parms.num_iters, 4); - } - - /* Print out time from last read to close */ - if (pio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read file close details:\n"); - output_all_info(read_close_mm_table, parms.num_iters, 4); - } - } - - /* clean up our mess */ - free(write_mpi_mm_table); - free(write_mm_table); - free(write_gross_mm_table); - free(write_raw_mm_table); - free(write_open_mm_table); - free(write_close_mm_table); - - if (!parms.h5_write_only) { - free(read_mpi_mm_table); - free(read_mm_table); - free(read_gross_mm_table); - free(read_raw_mm_table); - free(read_open_mm_table); - free(read_close_mm_table); - } - - return ret_value; -} - -/* - * Function: output_all_info - * Purpose: - * Return: Nothing - * Programmer: Bill Wendling, 29. January 2002 - * Modifications: - */ -static void -output_all_info(minmax *mm, int count, int indent_level) -{ - int i; - - for (i = 0; i < count; ++i) { - print_indent(indent_level); - output_report("Iteration %d:\n", i + 1); - print_indent(indent_level + 1); - output_report("Minimum Time: %.2fs\n", mm[i].min); - print_indent(indent_level + 1); - output_report("Maximum Time: %.2fs\n", mm[i].max); - } -} - -/* - * Function: get_minmax - * Purpose: Gather all the min, max and total of val. - * Return: Nothing - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Use MPI_Allreduce to do it. -akc, 2002/01/11 - */ -static void -get_minmax(minmax *mm, double val) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - MPI_Comm_size(pio_comm_g, &mm->num); - - MPI_Allreduce(&val, &mm->max, 1, MPI_DOUBLE, MPI_MAX, pio_comm_g); - MPI_Allreduce(&val, &mm->min, 1, MPI_DOUBLE, MPI_MIN, pio_comm_g); - MPI_Allreduce(&val, &mm->sum, 1, MPI_DOUBLE, MPI_SUM, pio_comm_g); -} - -/* - * Function: accumulate_minmax_stuff - * Purpose: Accumulate the minimum, maximum, and average of the times - * across all processes. - * Return: TOTAL_MM - the total of all of these. - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Changed to use seconds instead of MB/s - QAK, 5/9/02 - */ -static minmax -accumulate_minmax_stuff(minmax *mm, int count) -{ - int i; - minmax total_mm; - - total_mm.sum = 0.0f; - total_mm.max = -DBL_MAX; - total_mm.min = DBL_MAX; - total_mm.num = count; - - for (i = 0; i < count; ++i) { - double m = mm[i].max; - - total_mm.sum += m; - - if (m < total_mm.min) - total_mm.min = m; - - if (m > total_mm.max) - total_mm.max = m; - } - - return total_mm; -} - -/* - * Function: create_comm_world - * Purpose: Create an MPI Comm world and store it in pio_comm_g, which - * is a global variable. - * Return: SUCCESS on success. - * FAIL otherwise. - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static int -create_comm_world(int num_procs, int *doing_pio) -{ - /* MPI variables */ - int mrc; /* return values */ - int color; /* for communicator creation */ - int myrank, nprocs; - - pio_comm_g = MPI_COMM_NULL; - - /* - * Create a sub communicator for this PIO run. Easier to use the first N - * processes. - */ - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - - if (num_procs > nprocs) { - HDfprintf(stderr, "number of process(%d) must be <= number of processes in MPI_COMM_WORLD(%d)\n", - num_procs, nprocs); - goto error_done; - } - - MPI_Comm_rank(MPI_COMM_WORLD, &myrank); - color = (myrank < num_procs); - mrc = MPI_Comm_split(MPI_COMM_WORLD, color, myrank, &pio_comm_g); - - if (mrc != MPI_SUCCESS) { - HDfprintf(stderr, "MPI_Comm_split failed\n"); - goto error_done; - } - - if (!color) { - /* not involved in this run */ - mrc = destroy_comm_world(); - goto done; - } - - /* determine the MPI rank in the PIO communicator */ - MPI_Comm_size(pio_comm_g, &pio_mpi_nprocs_g); - MPI_Comm_rank(pio_comm_g, &pio_mpi_rank_g); - -done: - *doing_pio = color; - return SUCCESS; - -error_done: - destroy_comm_world(); - return FAIL; -} - -/* - * Function: destroy_comm_world - * Purpose: Destroy the created MPI Comm world which is stored in the - * pio_comm_g global variable. - * Return: SUCCESS on success. - * FAIL otherwise. - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static int -destroy_comm_world(void) -{ - int mrc = SUCCESS; /* return code */ - - /* release MPI resources */ - if (pio_comm_g != MPI_COMM_NULL) - mrc = (MPI_Comm_free(&pio_comm_g) == MPI_SUCCESS ? SUCCESS : FAIL); - - return mrc; -} - -/* - * Function: output_results - * Purpose: Print information about the time & bandwidth for a given - * minmax & # of iterations. - * Return: Nothing - * Programmer: Quincey Koziol, 9. May 2002 - * Modifications: - */ -static void -output_results(const struct options *opts, const char *name, minmax *table, int table_size, off_t data_size) -{ - minmax total_mm; - - total_mm = accumulate_minmax_stuff(table, table_size); - - print_indent(3); - output_report("%s (%d iteration(s)):\n", name, table_size); - - /* Note: The maximum throughput uses the minimum amount of time & vice versa */ - - print_indent(4); - output_report("Maximum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.min)); - if (opts->print_times) - output_report(" (%7.3f s)\n", total_mm.min); - else - output_report("\n"); - - print_indent(4); - output_report("Average Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.sum / total_mm.num)); - if (opts->print_times) - output_report(" (%7.3f s)\n", (total_mm.sum / total_mm.num)); - else - output_report("\n"); - - print_indent(4); - output_report("Minimum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.max)); - if (opts->print_times) - output_report(" (%7.3f s)\n", total_mm.max); - else - output_report("\n"); -} - -static void -output_times(const struct options *opts, const char *name, minmax *table, int table_size) -{ - minmax total_mm; - - total_mm = accumulate_minmax_stuff(table, table_size); - - print_indent(3); - output_report("%s (%d iteration(s)):\n", name, table_size); - - /* Note: The maximum throughput uses the minimum amount of time & vice versa */ - - print_indent(4); - output_report("Minimum Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, (total_mm.min)); - - print_indent(4); - output_report("Average Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, - (total_mm.sum / total_mm.num)); - - print_indent(4); - output_report("Maximum Accumulated Time using %d file(s): %7.5f s\n", opts->num_files, (total_mm.max)); -} - -/* - * Function: output_report - * Purpose: Print a line of the report. Only do so if I'm the 0 process. - * Return: Nothing - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static void -output_report(const char *fmt, ...) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - if (myrank == 0) { - va_list ap; - - HDva_start(ap, fmt); - HDvfprintf(output, fmt, ap); - HDva_end(ap); - } -} - -/* - * Function: print_indent - * Purpose: Print spaces to indent a new line of text for pretty printing - * things. - * Return: Nothing - * Programmer: Bill Wendling, 29. October 2001 - * Modifications: - */ -static void -print_indent(register int indent) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - if (myrank == 0) { - indent *= TAB_SPACE; - - for (; indent > 0; --indent) - HDfputc(' ', output); - } -} - -static void -recover_size_and_print(long long val, const char *end) -{ - if (val >= ONE_KB && (val % ONE_KB) == 0) { - if (val >= ONE_MB && (val % ONE_MB) == 0) { - if (val >= ONE_GB && (val % ONE_GB) == 0) - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "GB%s", - val / ONE_GB, end); - else - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "MB%s", - val / ONE_MB, end); - } - else { - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "KB%s", - val / ONE_KB, end); - } - } - else { - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "%s", - val, end); - } -} - -static void -print_io_api(long io_types) -{ - if (io_types & PIO_POSIX) - HDfprintf(output, "posix "); - if (io_types & PIO_MPI) - HDfprintf(output, "mpiio "); - if (io_types & PIO_HDF5) - HDfprintf(output, "phdf5 "); - HDfprintf(output, "\n"); -} - -static void -report_parameters(struct options *opts) -{ - int rank = comm_world_rank_g; - - print_version("HDF5 Library"); /* print library version */ - HDfprintf(output, "rank %d: ==== Parameters ====\n", rank); - - HDfprintf(output, "rank %d: IO API=", rank); - print_io_api(opts->io_types); - - HDfprintf(output, "rank %d: Number of files=%ld\n", rank, opts->num_files); - HDfprintf(output, "rank %d: Number of datasets=%ld\n", rank, opts->num_dsets); - HDfprintf(output, "rank %d: Number of iterations=%d\n", rank, opts->num_iters); - HDfprintf(output, "rank %d: Number of processes=%d:%d\n", rank, opts->min_num_procs, opts->max_num_procs); - - if (opts->dim2d) { - HDfprintf(output, "rank %d: Number of bytes per process per dataset=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->num_bpp * opts->min_num_procs), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->num_bpp * opts->max_num_procs), "\n"); - - HDfprintf(output, "rank %d: Size of dataset(s)=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), "x"); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "x"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "\n"); - - HDfprintf(output, "rank %d: File size=", rank); - recover_size_and_print((long long)(squareo(opts->num_bpp * opts->min_num_procs) * opts->num_dsets), - ":"); - recover_size_and_print((long long)(squareo(opts->num_bpp * opts->max_num_procs) * opts->num_dsets), - "\n"); - - HDfprintf(output, "rank %d: Transfer buffer size=", rank); - if (opts->interleaved) { - recover_size_and_print((long long)opts->min_xfer_size, "x"); - recover_size_and_print((long long)opts->blk_size, ":"); - recover_size_and_print((long long)opts->max_xfer_size, "x"); - recover_size_and_print((long long)opts->blk_size, "\n"); - } - else { - recover_size_and_print((long long)opts->blk_size, "x"); - recover_size_and_print((long long)opts->min_xfer_size, ":"); - recover_size_and_print((long long)opts->blk_size, "x"); - recover_size_and_print((long long)opts->max_xfer_size, "\n"); - } - HDfprintf(output, "rank %d: Block size=", rank); - recover_size_and_print((long long)opts->blk_size, "x"); - recover_size_and_print((long long)opts->blk_size, "\n"); - } - else { - HDfprintf(output, "rank %d: Number of bytes per process per dataset=", rank); - recover_size_and_print((long long)opts->num_bpp, "\n"); - - HDfprintf(output, "rank %d: Size of dataset(s)=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs), "\n"); - - HDfprintf(output, "rank %d: File size=", rank); - recover_size_and_print((long long)(opts->num_bpp * opts->min_num_procs * opts->num_dsets), ":"); - recover_size_and_print((long long)(opts->num_bpp * opts->max_num_procs * opts->num_dsets), "\n"); - - HDfprintf(output, "rank %d: Transfer buffer size=", rank); - recover_size_and_print((long long)opts->min_xfer_size, ":"); - recover_size_and_print((long long)opts->max_xfer_size, "\n"); - HDfprintf(output, "rank %d: Block size=", rank); - recover_size_and_print((long long)opts->blk_size, "\n"); - } - - HDfprintf(output, "rank %d: Block Pattern in Dataset=", rank); - if (opts->interleaved) - HDfprintf(output, "Interleaved\n"); - else - HDfprintf(output, "Contiguous\n"); - - HDfprintf(output, "rank %d: I/O Method for MPI and HDF5=", rank); - if (opts->collective) - HDfprintf(output, "Collective\n"); - else - HDfprintf(output, "Independent\n"); - - HDfprintf(output, "rank %d: Geometry=", rank); - if (opts->dim2d) - HDfprintf(output, "2D\n"); - else - HDfprintf(output, "1D\n"); - - HDfprintf(output, "rank %d: VFL used for HDF5 I/O=%s\n", rank, "MPI-IO driver"); - - HDfprintf(output, "rank %d: Data storage method in HDF5=", rank); - if (opts->h5_use_chunks) - HDfprintf(output, "Chunked\n"); - else - HDfprintf(output, "Contiguous\n"); - - { - char *prefix = HDgetenv("HDF5_PARAPREFIX"); - - HDfprintf(output, "rank %d: Env HDF5_PARAPREFIX=%s\n", rank, (prefix ? prefix : "not set")); - } - - HDfprintf(output, "rank %d: ", rank); - h5_dump_info_object(h5_io_info_g); - - HDfprintf(output, "rank %d: ==== End of Parameters ====\n", rank); - HDfprintf(output, "\n"); -} - -/* - * Function: parse_command_line - * Purpose: Parse the command line options and return a STRUCT OPTIONS - * structure which will need to be freed by the calling function. - * Return: Pointer to an OPTIONS structure - * Programmer: Bill Wendling, 31. October 2001 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static struct options * -parse_command_line(int argc, char *argv[]) -{ - register int opt; - struct options *cl_opts; - - cl_opts = (struct options *)malloc(sizeof(struct options)); - - cl_opts->output_file = NULL; - cl_opts->io_types = 0; /* will set default after parsing options */ - cl_opts->num_dsets = 1; - cl_opts->num_files = 1; - cl_opts->num_bpp = 0; - cl_opts->num_iters = 1; - cl_opts->max_num_procs = comm_world_nprocs_g; - cl_opts->min_num_procs = 1; - cl_opts->max_xfer_size = 0; - cl_opts->min_xfer_size = 0; - cl_opts->blk_size = 0; - cl_opts->interleaved = 0; /* Default to contiguous blocks in dataset */ - cl_opts->collective = 0; /* Default to independent I/O access */ - cl_opts->dim2d = 0; /* Default to 1D */ - cl_opts->print_times = FALSE; /* Printing times is off by default */ - cl_opts->print_raw = FALSE; /* Printing raw data throughput is off by default */ - cl_opts->h5_alignment = 1; /* No alignment for HDF5 objects by default */ - cl_opts->h5_threshold = 1; /* No threshold for aligning HDF5 objects by default */ - cl_opts->h5_use_chunks = FALSE; /* Don't chunk the HDF5 dataset by default */ - cl_opts->h5_write_only = FALSE; /* Do both read and write by default */ - cl_opts->verify = FALSE; /* No Verify data correctness by default */ - - while ((opt = H5_get_option(argc, (const char **)argv, s_opts, l_opts)) != EOF) { - switch ((char)opt) { - case 'a': - cl_opts->h5_alignment = parse_size_directive(H5_optarg); - break; - case 'A': { - const char *end = H5_optarg; - - while (end && *end != '\0') { - char buf[10]; - int i; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (isalnum(*end) && i < 10) - buf[i++] = *end; - - if (!HDstrcasecmp(buf, "phdf5")) { - cl_opts->io_types |= PIO_HDF5; - } - else if (!HDstrcasecmp(buf, "mpiio")) { - cl_opts->io_types |= PIO_MPI; - } - else if (!HDstrcasecmp(buf, "posix")) { - cl_opts->io_types |= PIO_POSIX; - } - else { - HDfprintf(stderr, "pio_perf: invalid --api option %s\n", buf); - HDexit(EXIT_FAILURE); - } - - if (*end == '\0') - break; - - end++; - } - } - - break; -#if 0 - case 'b': - /* the future "binary" option */ - break; -#endif /* 0 */ - case 'B': - cl_opts->blk_size = (size_t)parse_size_directive(H5_optarg); - break; - case 'c': - /* Turn on chunked HDF5 dataset creation */ - cl_opts->h5_use_chunks = TRUE; - break; - case 'C': - cl_opts->collective = 1; - break; - case 'd': - cl_opts->num_dsets = atoi(H5_optarg); - break; - case 'D': { - const char *end = H5_optarg; - - while (end && *end != '\0') { - char buf[10]; - int i; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - if (HDstrlen(buf) > 1 || HDisdigit(buf[0])) { - size_t j; - - for (j = 0; j < 10 && buf[j] != '\0'; ++j) - if (!isdigit(buf[j])) { - HDfprintf(stderr, "pio_perf: invalid --debug option %s\n", buf); - HDexit(EXIT_FAILURE); - } - - pio_debug_level = atoi(buf); - - if (pio_debug_level > 4) - pio_debug_level = 4; - else if (pio_debug_level < 0) - pio_debug_level = 0; - } - else { - switch (*buf) { - case 'r': - /* Turn on raw data throughput info */ - cl_opts->print_raw = TRUE; - break; - case 't': - /* Turn on time printing */ - cl_opts->print_times = TRUE; - break; - case 'v': - /* Turn on verify data correctness*/ - cl_opts->verify = TRUE; - break; - default: - HDfprintf(stderr, "pio_perf: invalid --debug option %s\n", buf); - HDexit(EXIT_FAILURE); - } - } - - if (*end == '\0') - break; - - end++; - } - } - - break; - case 'e': - cl_opts->num_bpp = parse_size_directive(H5_optarg); - break; - case 'F': - cl_opts->num_files = HDatoi(H5_optarg); - break; - case 'g': - cl_opts->dim2d = 1; - break; - case 'i': - cl_opts->num_iters = HDatoi(H5_optarg); - break; - case 'I': - cl_opts->interleaved = 1; - break; - case 'o': - cl_opts->output_file = H5_optarg; - break; - case 'p': - cl_opts->min_num_procs = HDatoi(H5_optarg); - break; - case 'P': - cl_opts->max_num_procs = HDatoi(H5_optarg); - break; - case 'T': - cl_opts->h5_threshold = parse_size_directive(H5_optarg); - break; - case 'w': - cl_opts->h5_write_only = TRUE; - break; - case 'x': - cl_opts->min_xfer_size = (size_t)parse_size_directive(H5_optarg); - break; - case 'X': - cl_opts->max_xfer_size = (size_t)parse_size_directive(H5_optarg); - break; - case 'h': - case '?': - default: - usage(progname); - HDfree(cl_opts); - return NULL; - } - } - - if (cl_opts->num_bpp == 0) { - if (cl_opts->dim2d == 0) - cl_opts->num_bpp = 256 * ONE_KB; - else - cl_opts->num_bpp = 8 * ONE_KB; - } - - if (cl_opts->max_xfer_size == 0) - cl_opts->max_xfer_size = (size_t)cl_opts->num_bpp; - - if (cl_opts->min_xfer_size == 0) - cl_opts->min_xfer_size = (size_t)(cl_opts->num_bpp) / 2; - - if (cl_opts->blk_size == 0) - cl_opts->blk_size = (size_t)(cl_opts->num_bpp) / 2; - - /* set default if none specified yet */ - if (!cl_opts->io_types) - cl_opts->io_types = PIO_HDF5 | PIO_MPI | PIO_POSIX; /* run all API */ - - /* verify parameters sanity. Adjust if needed. */ - /* cap xfer_size with bytes per process */ - if (!cl_opts->dim2d) { - if (cl_opts->min_xfer_size > (size_t)cl_opts->num_bpp) - cl_opts->min_xfer_size = (size_t)cl_opts->num_bpp; - if (cl_opts->max_xfer_size > (size_t)cl_opts->num_bpp) - cl_opts->max_xfer_size = (size_t)cl_opts->num_bpp; - } - if (cl_opts->min_xfer_size > cl_opts->max_xfer_size) - cl_opts->min_xfer_size = cl_opts->max_xfer_size; - if (cl_opts->blk_size > (size_t)cl_opts->num_bpp) - cl_opts->blk_size = (size_t)cl_opts->num_bpp; - /* check range of number of processes */ - if (cl_opts->min_num_procs <= 0) - cl_opts->min_num_procs = 1; - if (cl_opts->max_num_procs <= 0) - cl_opts->max_num_procs = 1; - if (cl_opts->min_num_procs > cl_opts->max_num_procs) - cl_opts->min_num_procs = cl_opts->max_num_procs; - /* check iteration */ - if (cl_opts->num_iters <= 0) - cl_opts->num_iters = 1; - - return cl_opts; -} - -/* - * Function: parse_size_directive - * Purpose: Parse the size directive passed on the commandline. The size - * directive is an integer followed by a size indicator: - * - * K, k - Kilobyte - * M, m - Megabyte - * G, g - Gigabyte - * - * Return: The size as a off_t because this is related to file size. - * If an unknown size indicator is used, then the program will - * exit with EXIT_FAILURE as the return value. - * Programmer: Bill Wendling, 18. December 2001 - * Modifications: - */ -static off_t -parse_size_directive(const char *size) -{ - off_t s; - char *endptr; - - s = HDstrtol(size, &endptr, 10); - - if (endptr && *endptr) { - while (*endptr != '\0' && (*endptr == ' ' || *endptr == '\t')) - ++endptr; - - switch (*endptr) { - case 'K': - case 'k': - s *= ONE_KB; - break; - case 'M': - case 'm': - s *= ONE_MB; - break; - case 'G': - case 'g': - s *= ONE_GB; - break; - default: - HDfprintf(stderr, "Illegal size specifier '%c'\n", *endptr); - HDexit(EXIT_FAILURE); - } - } - - return s; -} - -/* - * Function: usage - * Purpose: Print a usage message and then exit. - * Return: Nothing - * Programmer: Bill Wendling, 31. October 2001 - * Modifications: - * Added 2D testing (Christian Chilan, 10. August 2005) - */ -static void -usage(const char *prog) -{ - int myrank; - - MPI_Comm_rank(pio_comm_g, &myrank); - - if (myrank == 0) { - print_version(prog); - HDprintf("usage: %s [OPTIONS]\n", prog); - HDprintf(" OPTIONS\n"); - HDprintf(" -h, --help Print a usage message and exit\n"); - HDprintf(" -a S, --align=S Alignment of objects in HDF5 file [default: 1]\n"); - HDprintf(" -A AL, --api=AL Which APIs to test [default: all of them]\n"); -#if 0 - HDprintf(" -b, --binary The elusive binary option\n"); -#endif /* 0 */ - HDprintf(" -B S, --block-size=S Block size within transfer buffer\n"); - HDprintf(" (see below for description)\n"); - HDprintf(" [default: half the number of bytes per process\n"); - HDprintf(" per dataset]\n"); - HDprintf(" -c, --chunk Create HDF5 datasets using chunked storage\n"); - HDprintf(" [default: contiguous storage]\n"); - HDprintf(" -C, --collective Use collective I/O for MPI and HDF5 APIs\n"); - HDprintf(" [default: independent I/O)\n"); - HDprintf(" -d N, --num-dsets=N Number of datasets per file [default: 1]\n"); - HDprintf(" -D DL, --debug=DL Indicate the debugging level\n"); - HDprintf(" [default: no debugging]\n"); - HDprintf(" -e S, --num-bytes=S Number of bytes per process per dataset\n"); - HDprintf(" (see below for description)\n"); - HDprintf(" [default: 256K for 1D, 8K for 2D]\n"); - HDprintf(" -F N, --num-files=N Number of files [default: 1]\n"); - HDprintf(" -g, --geometry Use 2D geometry [default: 1D geometry]\n"); - HDprintf(" -i N, --num-iterations=N Number of iterations to perform [default: 1]\n"); - HDprintf(" -I, --interleaved Interleaved access pattern\n"); - HDprintf(" (see below for example)\n"); - HDprintf(" [default: Contiguous access pattern]\n"); - HDprintf(" -o F, --output=F Output raw data into file F [default: none]\n"); - HDprintf(" -p N, --min-num-processes=N Minimum number of processes to use [default: 1]\n"); - HDprintf(" -P N, --max-num-processes=N Maximum number of processes to use\n"); - HDprintf(" [default: all MPI_COMM_WORLD processes ]\n"); - HDprintf(" -T S, --threshold=S Threshold for alignment of objects in HDF5 file\n"); - HDprintf(" [default: 1]\n"); - HDprintf(" -w, --write-only Perform write tests not the read tests\n"); - HDprintf(" -x S, --min-xfer-size=S Minimum transfer buffer size\n"); - HDprintf(" (see below for description)\n"); - HDprintf(" [default: half the number of bytes per process\n"); - HDprintf(" per dataset]\n"); - HDprintf(" -X S, --max-xfer-size=S Maximum transfer buffer size\n"); - HDprintf(" [default: the number of bytes per process per\n"); - HDprintf(" dataset]\n"); - HDprintf("\n"); - HDprintf(" F - is a filename.\n"); - HDprintf(" N - is an integer >=0.\n"); - HDprintf(" S - is a size specifier, an integer >=0 followed by a size indicator:\n"); - HDprintf(" K - Kilobyte (%d)\n", ONE_KB); - HDprintf(" M - Megabyte (%d)\n", ONE_MB); - HDprintf(" G - Gigabyte (%d)\n", ONE_GB); - HDprintf("\n"); - HDprintf(" Example: '37M' is 37 megabytes or %d bytes\n", 37 * ONE_MB); - HDprintf("\n"); - HDprintf(" AL - is an API list. Valid values are:\n"); - HDprintf(" phdf5 - Parallel HDF5\n"); - HDprintf(" mpiio - MPI-I/O\n"); - HDprintf(" posix - POSIX\n"); - HDprintf("\n"); - HDprintf(" Example: --api=mpiio,phdf5\n"); - HDprintf("\n"); - HDprintf(" Dataset size:\n"); - HDprintf(" Depending on the selected geometry, each test dataset is either a linear\n"); - HDprintf(" array of size bytes-per-process * num-processes, or a square array of size\n"); - HDprintf(" (bytes-per-process * num-processes) x (bytes-per-process * num-processes).\n"); - HDprintf("\n"); - HDprintf(" Block size vs. Transfer buffer size:\n"); - HDprintf(" buffer-size controls the size of the memory buffer, which is broken into\n"); - HDprintf(" blocks and written to the file. Depending on the selected geometry, each\n"); - HDprintf(" block can be a linear array of size block-size or a square array of size\n"); - HDprintf(" block-size x block-size. The arrangement in which blocks are written is\n"); - HDprintf(" determined by the access pattern.\n"); - HDprintf("\n"); - HDprintf(" In 1D geometry, the transfer buffer is a linear array of size buffer-size.\n"); - HDprintf(" In 2D geometry, it is a rectangular array of size block-size x buffer-size\n"); - HDprintf(" or buffer-size x block-size if interleaved pattern is selected.\n"); - HDprintf("\n"); - HDprintf(" Interleaved and Contiguous patterns in 1D geometry:\n"); - HDprintf(" When contiguous access pattern is chosen, the dataset is evenly divided\n"); - HDprintf(" into num-processes regions and each process writes data to its own region.\n"); - HDprintf(" When interleaved blocks are written to a dataset, space for the first\n"); - HDprintf(" block of the first process is allocated in the dataset, then space is\n"); - HDprintf(" allocated for the first block of the second process, etc. until space is\n"); - HDprintf(" allocated for the first block of each process, then space is allocated for\n"); - HDprintf(" the second block of the first process, the second block of the second\n"); - HDprintf(" process, etc.\n"); - HDprintf("\n"); - HDprintf(" For example, with a 3 process run, 512KB bytes-per-process, 256KB transfer\n"); - HDprintf(" buffer size, and 64KB block size, each process must issue 2 transfer\n"); - HDprintf(" requests to complete access to the dataset.\n"); - HDprintf(" Contiguous blocks of the first transfer request are written like so:\n"); - HDprintf(" 1111----2222----3333----\n"); - HDprintf(" Interleaved blocks of the first transfer request are written like so:\n"); - HDprintf(" 123123123123------------\n"); - HDprintf(" The actual number of I/O operations involved in a transfer request\n"); - HDprintf(" depends on the access pattern and communication mode.\n"); - HDprintf(" When using independent I/O with interleaved pattern, each process\n"); - HDprintf(" performs 4 small non-contiguous I/O operations per transfer request.\n"); - HDprintf(" If collective I/O is turned on, the combined content of the buffers of\n"); - HDprintf(" the 3 processes will be written using one collective I/O operation\n"); - HDprintf(" per transfer request.\n"); - HDprintf("\n"); - HDprintf(" For information about access patterns in 2D geometry, please refer to the\n"); - HDprintf(" HDF5 Reference Manual.\n"); - HDprintf("\n"); - HDprintf(" DL - is a list of debugging flags. Valid values are:\n"); - HDprintf(" 1 - Minimal\n"); - HDprintf(" 2 - Not quite everything\n"); - HDprintf(" 3 - Everything\n"); - HDprintf(" 4 - The kitchen sink\n"); - HDprintf(" r - Raw data I/O throughput information\n"); - HDprintf(" t - Times as well as throughputs\n"); - HDprintf(" v - Verify data correctness\n"); - HDprintf("\n"); - HDprintf(" Example: --debug=2,r,t\n"); - HDprintf("\n"); - HDprintf(" Environment variables:\n"); - HDprintf(" HDF5_NOCLEANUP Do not remove data files if set [default remove]\n"); - HDprintf(" HDF5_MPI_INFO MPI INFO object key=value separated by ;\n"); - HDprintf(" HDF5_PARAPREFIX Paralllel data files prefix\n"); - fflush(stdout); - } /* end if */ -} /* end usage() */ - -#else /* H5_HAVE_PARALLEL */ - -/* - * Function: main - * Purpose: Dummy main() function for if HDF5 was configured without - * parallel stuff. - * Return: EXIT_SUCCESS - * Programmer: Bill Wendling, 14. November 2001 - */ -int -main(void) -{ - HDprintf("No parallel IO performance because parallel is not configured\n"); - return EXIT_SUCCESS; -} /* end main */ - -#endif /* !H5_HAVE_PARALLEL */ diff --git a/tools/test/perform/pio_perf.h b/tools/test/perform/pio_perf.h deleted file mode 100644 index 24621da..0000000 --- a/tools/test/perform/pio_perf.h +++ /dev/null @@ -1,100 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef PIO_PERF_H -#define PIO_PERF_H - -#ifndef STANDALONE -#include "io_timer.h" -#include "h5test.h" -#include "h5tools.h" -#include "h5tools_utils.h" -#else -#include "io_timer.h" -#include "pio_standalone.h" -#endif - -/* setup the dataset no fill option if this is v1.5 or more */ -#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR > 4 -#define H5_HAVE_NOFILL 1 -#endif - -typedef enum iotype_ { - POSIXIO, - MPIO, - PHDF5 - /*NUM_TYPES*/ -} iotype; - -typedef struct parameters_ { - iotype io_type; /* The type of IO test to perform */ - int num_procs; /* Maximum number of processes to use */ - long num_files; /* Number of files to create */ - long num_dsets; /* Number of datasets to create */ - off_t num_bytes; /* Number of bytes in each dset */ - int num_iters; /* Number of times to loop doing the IO */ - size_t buf_size; /* Buffer size */ - size_t blk_size; /* Block size */ - unsigned interleaved; /* Interleaved vs. contiguous blocks */ - unsigned collective; /* Collective vs. independent I/O */ - unsigned dim2d; /* 1D vs. 2D */ - hsize_t h5_align; /* HDF5 object alignment */ - hsize_t h5_thresh; /* HDF5 object alignment threshold */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int verify; /* Verify data correctness */ -} parameters; - -typedef struct results_ { - herr_t ret_code; - io_time_t *timers; -} results; - -#ifndef SUCCESS -#define SUCCESS 0 -#endif /* !SUCCESS */ - -#ifndef FAIL -#define FAIL -1 -#endif /* !FAIL */ - -extern FILE * output; /* output file */ -extern io_time_t *timer_g; /* timer: global for stub functions */ -extern int comm_world_rank_g; /* my rank in MPI_COMM_RANK */ -extern int comm_world_nprocs_g; /* num. of processes of MPI_COMM_WORLD */ -extern MPI_Comm pio_comm_g; /* Communicator to run the PIO */ -extern int pio_mpi_rank_g; /* MPI rank of pio_comm_g */ -extern int pio_mpi_nprocs_g; /* number of processes of pio_comm_g */ -extern int pio_debug_level; /* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Even More Debugging (timer stuff) - */ - -#define HDprint_rank(f) /* print rank in MPI_COMM_WORLD */ HDfprintf(f, "%d: ", comm_world_rank_g); -#define HDprint_size(f) /* print size of MPI_COMM_WORLD */ HDfprintf(f, "%d", comm_world_nprocs_g); -#define HDprint_rank_size(f) /* print rank/size of MPI_COMM_WORLD */ \ - HDfprintf(f, "%d/%d: ", comm_world_rank_g, comm_world_nprocs_g); - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern results do_pio(parameters param); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* PIO_PERF_H */ diff --git a/tools/test/perform/pio_standalone.c b/tools/test/perform/pio_standalone.c index db8633e..032bfba 100644 --- a/tools/test/perform/pio_standalone.c +++ b/tools/test/perform/pio_standalone.c @@ -17,20 +17,11 @@ #include "pio_perf.h" -#ifdef STANDALONE -MPI_Info h5_io_info_g = MPI_INFO_NULL; /* MPI INFO object for IO */ -#endif - /** From h5tools_utils.c **/ /* global variables */ int nCols = 80; -/* ``get_option'' variables */ -int H5_opterr = 1; /*get_option prints errors if this is on */ -int H5_optind = 1; /*token pointer */ -const char *H5_optarg; /*flag argument (or value) */ - int get_option(int argc, const char **argv, const char *opts, const struct h5_long_options *l_opts) { @@ -161,134 +152,3 @@ print_version(const char *progname) printf("%s: Version %u.%u.%u%s%s\n", progname, H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE, H5_VERS_SUBRELEASE[0] ? "-" : "", H5_VERS_SUBRELEASE); } - -#ifdef STANDALONE -/* - * Function: h5_set_info_object - * Purpose: Process environment variables setting to set up MPI Info - * object. - * Return: 0 if all is fine; otherwise non-zero. - * Programmer: Albert Cheng, 2002/05/21. - * Modifications: - * Bill Wendling, 2002/05/31 - * Modified so that the HDF5_MPI_INFO environment variable can - * be a semicolon separated list of "key=value" pairings. Most - * of the code is to remove any whitespaces which might be - * surrounding the "key=value" pairs. - */ -int -h5_set_info_object(void) -{ - char *envp; /* environment pointer */ - int ret_value = 0; - - /* handle any MPI INFO hints via $HDF5_MPI_INFO */ - if ((envp = HDgetenv("HDF5_MPI_INFO")) != NULL) { - char *next, *valp; - - valp = envp = next = HDstrdup(envp); - - if (!valp) - return 0; - - /* create an INFO object if not created yet */ - if (h5_io_info_g == MPI_INFO_NULL) - MPI_Info_create(&h5_io_info_g); - - do { - size_t len; - char * key_val, *endp, *namep; - - if (*valp == ';') - valp++; - - /* copy key/value pair into temporary buffer */ - len = strcspn(valp, ";"); - next = &valp[len]; - key_val = (char *)HDcalloc(1, len + 1); - - /* increment the next pointer past the terminating semicolon */ - if (*next == ';') - ++next; - - namep = HDstrncpy(key_val, valp, len); - - /* pass up any beginning whitespaces */ - while (*namep && (*namep == ' ' || *namep == '\t')) - namep++; - - if (!*namep) - continue; /* was all white space, so move to next k/v pair */ - - /* eat up any ending white spaces */ - endp = &namep[HDstrlen(namep) - 1]; - - while (endp && (*endp == ' ' || *endp == '\t')) - *endp-- = '\0'; - - /* find the '=' */ - valp = HDstrchr(namep, '='); - - if (valp != NULL) { /* it's a valid key/value pairing */ - char *tmp_val = valp + 1; - - /* change '=' to \0, move valp down one */ - *valp-- = '\0'; - - /* eat up ending whitespace on the "key" part */ - while (*valp == ' ' || *valp == '\t') - *valp-- = '\0'; - - valp = tmp_val; - - /* eat up beginning whitespace on the "value" part */ - while (*valp == ' ' || *valp == '\t') - *valp++ = '\0'; - - /* actually set the darned thing */ - if (MPI_SUCCESS != MPI_Info_set(h5_io_info_g, namep, valp)) { - HDprintf("MPI_Info_set failed\n"); - ret_value = -1; - } - } - - valp = next; - HDfree(key_val); - } while (next && *next); - - HDfree(envp); - } - - return ret_value; -} - -/* - * Function: h5_dump_info_object - * Purpose: Display content of an MPI Info object - * Return: void - * Programmer: Albert Cheng 2002/05/21 - * Modifications: - */ -void -h5_dump_info_object(MPI_Info info) -{ - char key[MPI_MAX_INFO_KEY + 1]; - char value[MPI_MAX_INFO_VAL + 1]; - int flag; - int i, nkeys; - - HDprintf("Dumping MPI Info Object (up to %d bytes per item):\n", MPI_MAX_INFO_VAL); - if (info == MPI_INFO_NULL) { - HDprintf("object is MPI_INFO_NULL\n"); - } - else { - MPI_Info_get_nkeys(info, &nkeys); - HDprintf("object has %d items\n", nkeys); - for (i = 0; i < nkeys; i++) { - MPI_Info_get_nthkey(info, i, key); - MPI_Info_get(info, key, MPI_MAX_INFO_VAL, value, &flag); - HDprintf("%s=%s\n", key, value); - } - } -} -#endif /* STANDALONE */ diff --git a/tools/test/perform/pio_standalone.h b/tools/test/perform/pio_standalone.h index 4b5c7b2..f1fb946 100644 --- a/tools/test/perform/pio_standalone.h +++ b/tools/test/perform/pio_standalone.h @@ -441,22 +441,11 @@ extern char * strdup(const char *s); #define TRUE true #endif -/** From h5test.h **/ - -#ifdef H5_HAVE_PARALLEL -extern MPI_Info h5_io_info_g; /* MPI INFO object for IO */ -#endif - -#ifdef H5_HAVE_PARALLEL -int h5_set_info_object(void); -void h5_dump_info_object(MPI_Info info); -#endif - /** From h5tools_utils.h **/ -extern int H5_opterr; /* getoption prints errors if this is on */ -extern int H5_optind; /* token pointer */ -extern const char *H5_optarg; /* flag argument (or value) */ +H5_DLLVAR int H5_opterr; /* getoption prints errors if this is on */ +H5_DLLVAR int H5_optind; /* token pointer */ +H5_DLLVAR const char *H5_optarg; /* flag argument (or value) */ enum h5_arg_level { no_arg = 0, /* doesn't take an argument */ diff --git a/tools/test/perform/sio_engine.c b/tools/test/perform/sio_engine.c deleted file mode 100644 index 1af2318..0000000 --- a/tools/test/perform/sio_engine.c +++ /dev/null @@ -1,1328 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Author: Christian Chilan, April 2008 - */ - -#include "hdf5.h" - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> - -#ifdef H5_HAVE_UNISTD_H -#include <sys/types.h> -#include <unistd.h> -#endif - -#ifdef H5_HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif - -#include "sio_perf.h" - -/* Macro definitions */ - -/* sizes of various items. these sizes won't change during program execution */ -#define ELMT_H5_TYPE H5T_NATIVE_UCHAR - -#define GOTOERROR(errcode) \ - { \ - ret_code = errcode; \ - goto done; \ - } -#define ERRMSG(mesg) \ - { \ - HDfprintf(stderr, "*** Assertion failed (%s) at line %4d in %s\n", mesg, (int)__LINE__, __FILE__); \ - } - -/* verify: if val is false (0), print mesg. */ -#define VRFY(val, mesg) \ - do { \ - if (!val) { \ - ERRMSG(mesg); \ - GOTOERROR(FAIL); \ - } \ - } while (0) - -/* POSIX I/O macros */ -#ifdef H5_HAVE_WIN32_API -/* Can't link against the library, so this test will use the older, non-Unicode - * _open() call on Windows. - */ -#define HDopen(S, F, ...) _open(S, F | _O_BINARY, __VA_ARGS__) -#endif /* H5_HAVE_WIN32_API */ -#define POSIXCREATE(fn) HDopen(fn, O_CREAT | O_TRUNC | O_RDWR, 0600) -#define POSIXOPEN(fn, F) HDopen(fn, F, 0600) -#define POSIXCLOSE(F) HDclose(F) -#define POSIXSEEK(F, L) HDlseek(F, L, SEEK_SET) -#define POSIXWRITE(F, B, S) HDwrite(F, B, S) -#define POSIXREAD(F, B, S) HDread(F, B, S) - -enum { SIO_CREATE = 1, SIO_WRITE = 2, SIO_READ = 4 }; - -/* Global variables */ -static int clean_file_g = -1; /*whether to cleanup temporary test */ -/*files. -1 is not defined; */ -/*0 is no cleanup; 1 is do cleanup */ - -/* the different types of file descriptors we can expect */ -typedef union { - int posixfd; /* POSIX file handle*/ - hid_t h5fd; /* HDF5 file */ -} file_descr; - -/* local functions */ -static char * sio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size, - parameters *param); -static herr_t do_write(results *res, file_descr *fd, parameters *parms, void *buffer); -static herr_t do_read(results *res, file_descr *fd, parameters *parms, void *buffer); -static herr_t dset_write(int local_dim, file_descr *fd, parameters *parms, void *buffer); -static herr_t posix_buffer_write(int local_dim, file_descr *fd, parameters *parms, void *buffer); -static herr_t dset_read(int localrank, file_descr *fd, parameters *parms, void *buffer, const char *buffer2); -static herr_t posix_buffer_read(int local_dim, file_descr *fd, parameters *parms, void *buffer); -static herr_t do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags); -hid_t set_vfd(parameters *param); -static herr_t do_fclose(iotype iot, file_descr *fd); -static void do_cleanupfile(iotype iot, char *fname); - -/* global variables */ -static HDoff_t offset[MAX_DIMS]; /* dataset size in bytes */ -static size_t buf_offset[MAX_DIMS]; /* dataset size in bytes */ -static int order[MAX_DIMS]; /* dimension access order */ -static size_t linear_buf_size; /* linear buffer size */ -static int cont_dim; /* lowest dimension for contiguous POSIX - access */ -static size_t cont_size; /* size of contiguous POSIX access */ -static hid_t fapl; /* file access list */ -static unsigned char *buf_p; /* buffer pointer */ -static const char * multi_letters = "msbrglo"; /* string for multi driver */ - -/* HDF5 global variables */ -static hsize_t h5count[MAX_DIMS]; /*selection count */ -static hssize_t h5offset[MAX_DIMS]; /* Selection offset within dataspace */ -static hid_t h5dset_space_id = H5I_INVALID_HID; /*dataset space ID */ -static hid_t h5mem_space_id = H5I_INVALID_HID; /*memory dataspace ID */ -static hid_t h5ds_id = H5I_INVALID_HID; /*dataset handle */ -static hid_t h5dcpl = H5I_INVALID_HID; /* Dataset creation property list */ -static hid_t h5dxpl = H5I_INVALID_HID; /* Dataset transfer property list */ - -/* - * Function: do_sio - * Purpose: SIO Engine where IO are executed. - * Return: results - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -void -do_sio(parameters param, results *res) -{ - char * buffer = NULL; /*data buffer pointer */ - size_t buf_size[MAX_DIMS]; /* general buffer size in bytes */ - file_descr fd; /* file handles */ - iotype iot; /* API type */ - char base_name[256]; /* test file base name */ - /* return codes */ - herr_t ret_code = 0; /*return code */ - - char fname[FILENAME_MAX]; /* test file name */ - int i; - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - - /* Sanity check parameters */ - - /* IO type */ - iot = param.io_type; - - switch (iot) { - case POSIXIO: - fd.posixfd = -1; - res->timers = io_time_new(SYS_CLOCK); - break; - case HDF5: - fd.h5fd = -1; - res->timers = io_time_new(SYS_CLOCK); - break; - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - GOTOERROR(FAIL); - } - - linear_buf_size = 1; - - for (i = 0; i < param.rank; i++) { - buf_size[i] = param.buf_size[i]; - order[i] = param.order[i]; - linear_buf_size *= buf_size[i]; - buf_offset[i] = 0; - offset[i] = 0; - - /* Validate transfer buffer size */ - if (param.buf_size[i] <= 0) { - HDfprintf(stderr, "Transfer buffer size[%d] (%zu) must be > 0\n", i, buf_size[i]); - GOTOERROR(FAIL); - } - - if ((param.dset_size[i] % param.buf_size[i]) != 0) { - HDfprintf(stderr, - "Dataset size[%d] (%" H5_PRINTF_LL_WIDTH "d) must be a multiple of the " - "trasfer buffer size[%d] (%zu)\n", - param.rank, (long long)param.dset_size[i], param.rank, param.buf_size[i]); - GOTOERROR(FAIL); - } - } - - /* Allocate transfer buffer */ - if ((buffer = (char *)malloc(linear_buf_size)) == NULL) { - HDfprintf(stderr, "malloc for transfer buffer size (%zu) failed\n", linear_buf_size); - GOTOERROR(FAIL); - } - - if (sio_debug_level >= 4) - - /* output all of the times for all iterations */ - HDfprintf(output, "Timer details:\n"); - - /* - * Write performance measurement - */ - /* Open file for write */ - - HDstrcpy(base_name, "#sio_tmp"); - sio_create_filename(iot, base_name, fname, sizeof(fname), ¶m); - - if (sio_debug_level > 0) - HDfprintf(output, "data filename=%s\n", fname); - - io_time_set(res->timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, SIO_CREATE | SIO_WRITE); - VRFY((hrc == SUCCESS), "do_fopen failed"); - - io_time_set(res->timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTART); - hrc = do_write(res, &fd, ¶m, buffer); - io_time_set(res->timers, HDF5_FINE_WRITE_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_write failed"); - - /* Close file for write */ - hrc = do_fclose(iot, &fd); - io_time_set(res->timers, HDF5_GROSS_WRITE_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - - if (!param.h5_write_only) { - /* - * Read performance measurement - */ - - /* Open file for read */ - io_time_set(res->timers, HDF5_GROSS_READ_FIXED_DIMS, TSTART); - hrc = do_fopen(¶m, fname, &fd, SIO_READ); - VRFY((hrc == SUCCESS), "do_fopen failed"); - - io_time_set(res->timers, HDF5_FINE_READ_FIXED_DIMS, TSTART); - hrc = do_read(res, &fd, ¶m, buffer); - io_time_set(res->timers, HDF5_FINE_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_read failed"); - - /* Close file for read */ - hrc = do_fclose(iot, &fd); - - io_time_set(res->timers, HDF5_GROSS_READ_FIXED_DIMS, TSTOP); - VRFY((hrc == SUCCESS), "do_fclose failed"); - } - - do_cleanupfile(iot, fname); - -done: - /* clean up */ - /* release HDF5 objects */ - - /* close any opened files */ - /* no remove(fname) because that should have happened normally. */ - switch (iot) { - case POSIXIO: - if (fd.posixfd != -1) - hrc = do_fclose(iot, &fd); - break; - case HDF5: - if (fd.h5fd != -1) - hrc = do_fclose(iot, &fd); - break; - default: - /* unknown request */ - HDassert(0 && "Unknown IO type"); - break; - } - - /* release generic resources */ - if (buffer) - free(buffer); - - res->ret_code = ret_code; -} - -/* - * Function: sio_create_filename - * Purpose: Create a new filename to write to. Determine the correct - * suffix to append to the filename by the type of I/O we're - * doing. Also, place in the /tmp/{$USER,$LOGIN} directory if - * USER or LOGIN are specified in the environment. - * Return: Pointer to filename or NULL - * Programmer: Bill Wendling, 21. November 2001 - * Modifications: Support for file drivers. Christian Chilan, April, 2008 - */ -static char * -sio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size, parameters *param) -{ - const char *prefix, *suffix = ""; - char * ptr, last = '\0'; - size_t i, j; - vfdtype vfd; - vfd = param->vfd; - - if (!base_name || !fullname || size < 1) - return NULL; - - memset(fullname, 0, size); - - switch (iot) { - case POSIXIO: - suffix = ".posix"; - break; - case HDF5: - suffix = ".h5"; - if (vfd == family) - suffix = "%05d.h5"; - else if (vfd == multi) - suffix = NULL; - break; - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - HDassert(0 && "Unknown IO type"); - break; - } - - /* First use the environment variable and then try the constant */ - prefix = HDgetenv("HDF5_PREFIX"); - -#ifdef HDF5_PREFIX - if (!prefix) - prefix = HDF5_PREFIX; -#endif /* HDF5_PREFIX */ - - /* Prepend the prefix value to the base name */ - if (prefix && *prefix) { - /* If the prefix specifies the HDF5_PREFIX directory, then - * default to using the "/tmp/$USER" or "/tmp/$LOGIN" - * directory instead. */ - register char *user, *login, *subdir; - - user = HDgetenv("USER"); - login = HDgetenv("LOGIN"); - subdir = (user ? user : login); - - if (subdir) { - for (i = 0; i < size - 1 && prefix[i]; i++) - fullname[i] = prefix[i]; - - fullname[i++] = '/'; - - for (j = 0; i < size && subdir[j]; i++, j++) - fullname[i] = subdir[j]; - } - else { - /* We didn't append the prefix yet */ - HDstrncpy(fullname, prefix, size); - fullname[size - 1] = '\0'; - } - - if ((HDstrlen(fullname) + HDstrlen(base_name) + 1) < size) { - /* Append the base_name with a slash first. Multiple slashes are - * handled below. */ - h5_stat_t buf; - - if (HDstat(fullname, &buf) < 0) - /* The directory doesn't exist just yet */ - if (HDmkdir(fullname, 0755) < 0 && errno != EEXIST) { - /* We couldn't make the "/tmp/${USER,LOGIN}" subdirectory. - * Default to PREFIX's original prefix value. */ - HDstrcpy(fullname, prefix); - } - - HDstrcat(fullname, "/"); - HDstrcat(fullname, base_name); - } - else { - /* Buffer is too small */ - return NULL; - } - } - else if (strlen(base_name) >= size) { - /* Buffer is too small */ - return NULL; - } - else { - HDstrcpy(fullname, base_name); - } - - /* Append a suffix */ - if (suffix) { - if (HDstrlen(fullname) + HDstrlen(suffix) >= size) - return NULL; - - HDstrcat(fullname, suffix); - } - - /* Remove any double slashes in the filename */ - for (ptr = fullname, i = j = 0; ptr && (i < size); i++, ptr++) { - if (*ptr != '/' || last != '/') - fullname[j++] = *ptr; - - last = *ptr; - } - - return fullname; -} - -/* - * Function: do_write - * Purpose: Write the required amount of data to the file. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -static herr_t -do_write(results *res, file_descr *fd, parameters *parms, void *buffer) -{ - int ret_code = SUCCESS; - char dname[64]; - int i; - size_t u; - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[MAX_DIMS]; /*dataset dim sizes */ - hsize_t h5chunk[MAX_DIMS]; /*dataset dim sizes */ - hsize_t h5block[MAX_DIMS]; /*dataspace selection */ - hsize_t h5stride[MAX_DIMS]; /*selection stride */ - hsize_t h5start[MAX_DIMS]; /*selection start */ - hsize_t h5maxdims[MAX_DIMS]; - int rank; /*rank of dataset */ - - /* Prepare buffer for verifying data */ - /* if (parms->verify) - memset(buffer,1,linear_buf_size); */ - - buf_p = (unsigned char *)buffer; - - for (u = 0; u < linear_buf_size; u++) - buf_p[u] = u % 128; - - rank = parms->rank; - - for (i = 0; i < rank; i++) - h5offset[i] = offset[i] = 0; - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - - /* determine lowest dimension for contiguous POSIX access */ - cont_dim = rank; - - for (i = rank - 1; i >= 0; i--) { - if (parms->buf_size[i] == parms->dset_size[i]) - cont_dim = i; - else - break; - } - - /* determine size of the contiguous POSIX access */ - cont_size = (!cont_dim) ? 1 : parms->buf_size[cont_dim - 1]; - for (i = cont_dim; i < rank; i++) - cont_size *= parms->buf_size[i]; - - break; - - case HDF5: /* HDF5 setup */ - - for (i = 0; i < rank; i++) { - h5dims[i] = parms->dset_size[i]; - h5start[i] = 0; - h5stride[i] = 1; - h5block[i] = 1; - h5count[i] = parms->buf_size[i]; - h5chunk[i] = parms->chk_size[i]; - h5maxdims[i] = H5S_UNLIMITED; - } - - if (parms->h5_use_chunks && parms->h5_extendable) { - h5dset_space_id = H5Screate_simple(rank, h5count, h5maxdims); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - } - else { - h5dset_space_id = H5Screate_simple(rank, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - } - - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - - /* Create the memory dataspace that corresponds to the xfer buffer */ - h5mem_space_id = H5Screate_simple(rank, h5count, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - break; - - default: - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } /* end switch */ - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - break; - - case HDF5: - h5dcpl = H5Pcreate(H5P_DATASET_CREATE); - - if (h5dcpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - if (parms->h5_use_chunks) { - /* Set the chunk size to be the same as the buffer size */ - hrc = H5Pset_chunk(h5dcpl, rank, h5chunk); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Set failed\n"); - GOTOERROR(FAIL); - } /* end if */ - } /* end if */ - - HDsprintf(dname, "Dataset_%ld", (unsigned long)parms->num_bytes); - h5ds_id = - H5Dcreate2(fd->h5fd, dname, ELMT_H5_TYPE, h5dset_space_id, H5P_DEFAULT, h5dcpl, H5P_DEFAULT); - - if (h5ds_id < 0) { - HDfprintf(stderr, "HDF5 Dataset Create failed\n"); - GOTOERROR(FAIL); - } - - hrc = H5Pclose(h5dcpl); - /* verifying the close of the dcpl */ - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Property List Close failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } - - /* Start "raw data" write timer */ - io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTART); - - /* Perform write */ - hrc = dset_write(rank - 1, fd, parms, buffer); - - if (hrc < 0) { - HDfprintf(stderr, "Error in dataset write\n"); - GOTOERROR(FAIL); - } - - /* Stop "raw data" write timer */ - io_time_set(res->timers, HDF5_RAW_WRITE_FIXED_DIMS, TSTOP); - - /* Calculate write time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == HDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = H5I_INVALID_HID; - } /* end if */ - -done: - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } - else { - h5dset_space_id = H5I_INVALID_HID; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } - else { - h5mem_space_id = H5I_INVALID_HID; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } - else { - h5dxpl = H5I_INVALID_HID; - } - } - - return ret_code; -} - -/* - * Function: dset_write - * Purpose: Write buffer into the dataset. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -static herr_t -dset_write(int local_dim, file_descr *fd, parameters *parms, void *buffer) -{ - int cur_dim = order[local_dim] - 1; - int ret_code = SUCCESS; - int k; - hsize_t dims[MAX_DIMS], maxdims[MAX_DIMS]; - hsize_t i; - int j; - herr_t hrc; - - /* iterates according to the dimensions in order array */ - for (i = 0; i < parms->dset_size[cur_dim]; i += parms->buf_size[cur_dim]) { - - h5offset[cur_dim] = (hssize_t)i; - offset[cur_dim] = (HDoff_t)i; - - if (local_dim > 0) { - - dset_write(local_dim - 1, fd, parms, buffer); - } - else { - - switch (parms->io_type) { - - case POSIXIO: - /* initialize POSIX offset in the buffer */ - for (j = 0; j < parms->rank; j++) - buf_offset[j] = 0; - buf_p = (unsigned char *)buffer; - /* write POSIX buffer */ - posix_buffer_write(0, fd, parms, buffer); - break; - - case HDF5: - /* if dimensions are extendable, extend them as needed during access */ - if (parms->h5_use_chunks && parms->h5_extendable) { - - hrc = H5Sget_simple_extent_dims(h5dset_space_id, dims, maxdims); - VRFY((hrc >= 0), "H5Sget_simple_extent_dims"); - - for (k = 0; k < parms->rank; k++) { - - HDassert(h5offset[k] >= 0); - if (dims[k] <= (hsize_t)h5offset[k]) { - dims[k] = dims[k] + h5count[k]; - hrc = H5Sset_extent_simple(h5dset_space_id, parms->rank, dims, maxdims); - VRFY((hrc >= 0), "H5Sset_extent_simple"); - hrc = H5Dset_extent(h5ds_id, dims); - VRFY((hrc >= 0), "H5Dextend"); - } - } - } - /* applies offset */ - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - - /* Write the buffer out */ - hrc = H5Sget_simple_extent_dims(h5dset_space_id, dims, maxdims); - hrc = H5Dwrite(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dwrite"); - - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - HDassert(0 && "Unknown IO type"); - break; - } /* switch (parms->io_type) */ - } - } -done: - return ret_code; -} - -/* - * Function: posix_buffer_write - * Purpose: Write buffer into the POSIX file considering contiguity. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -static herr_t -posix_buffer_write(int local_dim, file_descr *fd, parameters *parms, void *buffer) -{ - int ret_code = SUCCESS; - - /* if dimension is not contiguous, call recursively */ - if (local_dim < parms->rank - 1 && local_dim != cont_dim) { - size_t u; - - for (u = 0; u < parms->buf_size[local_dim]; u++) { - buf_offset[local_dim] = u; - posix_buffer_write(local_dim + 1, fd, parms, buffer); - - /* if next dimension is cont_dim, it will fill out the buffer - traversing the entire dimension local_dim without the need - of performing iteration */ - if (local_dim + 1 == cont_dim) - break; - } - /* otherwise, perform contiguous POSIX access */ - } - else { - HDoff_t d_offset; - HDoff_t linear_dset_offset = 0; - int i, j, rc; - - buf_offset[local_dim] = 0; - - /* determine offset in the buffer */ - for (i = 0; i < parms->rank; i++) { - d_offset = 1; - - for (j = i + 1; j < parms->rank; j++) - d_offset *= (HDoff_t)parms->dset_size[j]; - - linear_dset_offset += (offset[i] + (HDoff_t)buf_offset[i]) * d_offset; - } - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, linear_dset_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - /* check if all bytes are written */ - rc = ((ssize_t)cont_size == POSIXWRITE(fd->posixfd, buf_p, cont_size)); - VRFY((rc != 0), "POSIXWRITE"); - - /* Advance location in buffer */ - buf_p += cont_size; - } - -done: - return ret_code; -} - -/* - * Function: do_read - * Purpose: Read the required amount of data to the file. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ -static herr_t -do_read(results *res, file_descr *fd, parameters *parms, void *buffer) -{ - char * buffer2 = NULL; /* Buffer for data verification */ - int ret_code = SUCCESS; - char dname[64]; - int i; - size_t u; - /* HDF5 variables */ - herr_t hrc; /*HDF5 return code */ - hsize_t h5dims[MAX_DIMS]; /*dataset dim sizes */ - hsize_t h5block[MAX_DIMS]; /*dataspace selection */ - hsize_t h5stride[MAX_DIMS]; /*selection stride */ - hsize_t h5start[MAX_DIMS]; /*selection start */ - int rank; - - /* Allocate data verification buffer */ - if (NULL == (buffer2 = (char *)malloc(linear_buf_size))) { - HDfprintf(stderr, "malloc for data verification buffer size (%zu) failed\n", linear_buf_size); - GOTOERROR(FAIL); - } /* end if */ - - /* Prepare buffer for verifying data */ - for (u = 0; u < linear_buf_size; u++) - buffer2[u] = (char)(u % 128); - - rank = parms->rank; - for (i = 0; i < rank; i++) - h5offset[i] = offset[i] = 0; - - /* I/O Access specific setup */ - switch (parms->io_type) { - case POSIXIO: - cont_dim = rank; - - for (i = rank - 1; i >= 0; i--) { - if (parms->buf_size[i] == parms->dset_size[i]) - cont_dim = i; - else - break; - } - cont_size = (!cont_dim) ? 1 : parms->buf_size[cont_dim - 1]; - for (i = cont_dim; i < rank; i++) - cont_size *= parms->buf_size[i]; - - break; - - case HDF5: /* HDF5 setup */ - for (i = 0; i < rank; i++) { - h5dims[i] = parms->dset_size[i]; - h5start[i] = 0; - h5stride[i] = 1; - h5block[i] = 1; - h5count[i] = parms->buf_size[i]; - } - - h5dset_space_id = H5Screate_simple(rank, h5dims, NULL); - VRFY((h5dset_space_id >= 0), "H5Screate_simple"); - - hrc = H5Sselect_hyperslab(h5dset_space_id, H5S_SELECT_SET, h5start, h5stride, h5count, h5block); - VRFY((hrc >= 0), "H5Sselect_hyperslab"); - - /* Create the memory dataspace that corresponds to the xfer buffer */ - h5mem_space_id = H5Screate_simple(rank, h5count, NULL); - VRFY((h5mem_space_id >= 0), "H5Screate_simple"); - - /* Create the dataset transfer property list */ - h5dxpl = H5Pcreate(H5P_DATASET_XFER); - if (h5dxpl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } /* end switch */ - - /* create dataset */ - switch (parms->io_type) { - case POSIXIO: - break; - - case HDF5: - HDsprintf(dname, "Dataset_%ld", (long)parms->num_bytes); - h5ds_id = H5Dopen2(fd->h5fd, dname, H5P_DEFAULT); - if (h5ds_id < 0) { - HDfprintf(stderr, "HDF5 Dataset open failed\n"); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - GOTOERROR(FAIL); - break; - } /* end switch */ - - /* Start "raw data" read timer */ - io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTART); - hrc = dset_read(rank - 1, fd, parms, buffer, buffer2); - - if (hrc < 0) { - HDfprintf(stderr, "Error in dataset read\n"); - GOTOERROR(FAIL); - } - - /* Stop "raw data" read timer */ - io_time_set(res->timers, HDF5_RAW_READ_FIXED_DIMS, TSTOP); - - /* Calculate read time */ - - /* Close dataset. Only HDF5 needs to do an explicit close. */ - if (parms->io_type == HDF5) { - hrc = H5Dclose(h5ds_id); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Close failed\n"); - GOTOERROR(FAIL); - } - - h5ds_id = H5I_INVALID_HID; - } /* end if */ - -done: - - /* release HDF5 objects */ - if (h5dset_space_id != -1) { - hrc = H5Sclose(h5dset_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Space Close failed\n"); - ret_code = FAIL; - } - else { - h5dset_space_id = H5I_INVALID_HID; - } - } - - if (h5mem_space_id != -1) { - hrc = H5Sclose(h5mem_space_id); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Memory Space Close failed\n"); - ret_code = FAIL; - } - else { - h5mem_space_id = H5I_INVALID_HID; - } - } - - if (h5dxpl != -1) { - hrc = H5Pclose(h5dxpl); - if (hrc < 0) { - HDfprintf(stderr, "HDF5 Dataset Transfer Property List Close failed\n"); - ret_code = FAIL; - } - else { - h5dxpl = H5I_INVALID_HID; - } - } - - /* release generic resources */ - if (buffer2) - free(buffer2); - - return ret_code; -} - -/* - * Function: dset_read - * Purpose: Read buffer into the dataset. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -static herr_t -dset_read(int local_dim, file_descr *fd, parameters *parms, void *buffer, const char *buffer2) -{ - int cur_dim = order[local_dim] - 1; - hsize_t i; - int j; - herr_t hrc; - int ret_code = SUCCESS; - - /* iterate on the current dimension */ - for (i = 0; i < parms->dset_size[cur_dim]; i += parms->buf_size[cur_dim]) { - - h5offset[cur_dim] = (hssize_t)i; - offset[cur_dim] = (HDoff_t)i; - - /* if traverse in order array is incomplete, recurse */ - if (local_dim > 0) { - - ret_code = dset_read(local_dim - 1, fd, parms, buffer, buffer2); - - /* otherwise, write buffer into dataset */ - } - else { - - switch (parms->io_type) { - - case POSIXIO: - for (j = 0; j < parms->rank; j++) { - buf_offset[j] = 0; - } - buf_p = (unsigned char *)buffer; - posix_buffer_read(0, fd, parms, buffer); - break; - - case HDF5: - hrc = H5Soffset_simple(h5dset_space_id, h5offset); - VRFY((hrc >= 0), "H5Soffset_simple"); - /* Read the buffer out */ - hrc = H5Dread(h5ds_id, ELMT_H5_TYPE, h5mem_space_id, h5dset_space_id, h5dxpl, buffer); - VRFY((hrc >= 0), "H5Dread"); - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)parms->io_type); - HDassert(0 && "Unknown IO type"); - break; - } /* switch (parms->io_type) */ - } - } -done: - return ret_code; -} - -/* - * Function: posix_buffer_read - * Purpose: Read buffer into the POSIX file considering contiguity. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -static herr_t -posix_buffer_read(int local_dim, file_descr *fd, parameters *parms, void *buffer) -{ - int ret_code = SUCCESS; - - /* if local dimension is not contiguous, recurse */ - if (local_dim < parms->rank - 1 && local_dim != cont_dim) { - size_t u; - - for (u = 0; u < parms->buf_size[local_dim]; u++) { - buf_offset[local_dim] = u; - ret_code = posix_buffer_read(local_dim + 1, fd, parms, buffer); - if (local_dim + 1 == cont_dim) - break; - } - /* otherwise, perform contiguous POSIX access */ - } - else { - HDoff_t d_offset; - HDoff_t linear_dset_offset = 0; - int i, j, rc; - - buf_offset[local_dim] = 0; - /* determine offset in buffer */ - for (i = 0; i < parms->rank; i++) { - d_offset = 1; - - for (j = i + 1; j < parms->rank; j++) - d_offset *= (HDoff_t)parms->dset_size[j]; - - linear_dset_offset += (offset[i] + (HDoff_t)buf_offset[i]) * d_offset; - } - - /* only care if seek returns error */ - rc = POSIXSEEK(fd->posixfd, linear_dset_offset) < 0 ? -1 : 0; - VRFY((rc == 0), "POSIXSEEK"); - /* check if all bytes are read */ - rc = ((ssize_t)cont_size == POSIXREAD(fd->posixfd, buf_p, cont_size)); - VRFY((rc != 0), "POSIXREAD"); - - /* Advance location in buffer */ - buf_p += cont_size; - } -done: - return ret_code; -} - -/* - * Function: do_fopen - * Purpose: Open the specified file. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: Support for file drivers, Christian Chilan, April, 2008 - */ -static herr_t -do_fopen(parameters *param, char *fname, file_descr *fd /*out*/, int flags) -{ - int ret_code = SUCCESS; - hid_t fcpl; - - switch (param->io_type) { - case POSIXIO: - if (flags & (SIO_CREATE | SIO_WRITE)) - fd->posixfd = POSIXCREATE(fname); - else - fd->posixfd = POSIXOPEN(fname, O_RDONLY); - - if (fd->posixfd < 0) { - HDfprintf(stderr, "POSIX File Open failed(%s)\n", fname); - GOTOERROR(FAIL); - } - - break; - - case HDF5: - - fapl = set_vfd(param); - - if (fapl < 0) { - HDfprintf(stderr, "HDF5 Property List Create failed\n"); - GOTOERROR(FAIL); - } - - fcpl = H5Pcreate(H5P_FILE_CREATE); - if (param->page_size) { - H5Pset_file_space_strategy(fcpl, H5F_FSPACE_STRATEGY_PAGE, 0, (hsize_t)1); - H5Pset_file_space_page_size(fcpl, param->page_size); - if (param->page_buffer_size) - H5Pset_page_buffer_size(fapl, param->page_buffer_size, 0, 0); - } - - /* create the parallel file */ - if (flags & (SIO_CREATE | SIO_WRITE)) { - fd->h5fd = H5Fcreate(fname, H5F_ACC_TRUNC, fcpl, fapl); - } - else { - fd->h5fd = H5Fopen(fname, H5F_ACC_RDONLY, fapl); - } - - if (fd->h5fd < 0) { - HDfprintf(stderr, "HDF5 File Create failed(%s)\n", fname); - GOTOERROR(FAIL); - } - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)param->io_type); - GOTOERROR(FAIL); - break; - } - -done: - return ret_code; -} - -/* - * Function: set_vfd - * Purpose: Sets file driver. - * Return: SUCCESS or FAIL - * Programmer: Christian Chilan, April, 2008 - * Modifications: - */ - -hid_t -set_vfd(parameters *param) -{ - hid_t my_fapl = H5I_INVALID_HID; - vfdtype vfd; - - vfd = param->vfd; - - if ((my_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) - return -1; - - if (vfd == sec2) { - /* Unix read() and write() system calls */ - if (H5Pset_fapl_sec2(my_fapl) < 0) - return -1; - } - else if (vfd == stdio) { - /* Standard C fread() and fwrite() system calls */ - if (H5Pset_fapl_stdio(my_fapl) < 0) - return -1; - } - else if (vfd == core) { - /* In-core temporary file with 1MB increment */ - if (H5Pset_fapl_core(my_fapl, (size_t)1024 * 1024, TRUE) < 0) - return -1; - } - else if (vfd == split) { - /* Split meta data and raw data each using default driver */ - if (H5Pset_fapl_split(my_fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT) < 0) - return -1; - } - else if (vfd == multi) { - /* Multi-file driver, general case of the split driver */ - H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; - hid_t memb_fapl[H5FD_MEM_NTYPES]; - const char *memb_name[H5FD_MEM_NTYPES]; - char sv[H5FD_MEM_NTYPES][1024]; - haddr_t memb_addr[H5FD_MEM_NTYPES]; - H5FD_mem_t mt; - - HDmemset(memb_map, 0, sizeof memb_map); - HDmemset(memb_fapl, 0, sizeof memb_fapl); - HDmemset(memb_name, 0, sizeof memb_name); - HDmemset(memb_addr, 0, sizeof memb_addr); - - HDassert(HDstrlen(multi_letters) == H5FD_MEM_NTYPES); - for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { - memb_fapl[mt] = H5P_DEFAULT; - HDsprintf(sv[mt], "%%s-%c.h5", multi_letters[mt]); - memb_name[mt] = sv[mt]; - memb_addr[mt] = (haddr_t)MAX(mt - 1, 0) * (HADDR_MAX / 10); - } - - if (H5Pset_fapl_multi(my_fapl, memb_map, memb_fapl, memb_name, memb_addr, FALSE) < 0) { - return -1; - } - } - else if (vfd == family) { - hsize_t fam_size = 1 * 1024 * 1024; /*100 MB*/ - - /* Family of files, each 1MB and using the default driver */ - /* if ((val=HDstrtok(NULL, " \t\n\r"))) - fam_size = (hsize_t)(HDstrtod(val, NULL) * 1024*1024); */ - if (H5Pset_fapl_family(my_fapl, fam_size, H5P_DEFAULT) < 0) - return -1; - } - else if (vfd == direct) { -#ifdef H5_HAVE_DIRECT - /* Linux direct read() and write() system calls. Set memory boundary, file block size, - * and copy buffer size to the default values. */ - if (H5Pset_fapl_direct(my_fapl, 1024, 4096, 8 * 4096) < 0) - return -1; -#endif - } - else { - /* Unknown driver */ - return -1; - } - - return my_fapl; -} - -/* - * Function: do_fclose - * Purpose: Close the specified file descriptor. - * Return: SUCCESS or FAIL - * Programmer: Albert Cheng, Bill Wendling, 2001/12/13 - * Modifications: - */ -static herr_t -do_fclose(iotype iot, file_descr *fd /*out*/) -{ - herr_t ret_code = SUCCESS, hrc; - int rc = 0; - - switch (iot) { - case POSIXIO: - rc = POSIXCLOSE(fd->posixfd); - - if (rc != 0) { - HDfprintf(stderr, "POSIX File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->posixfd = -1; - break; - - case HDF5: - hrc = H5Fclose(fd->h5fd); - - if (hrc < 0) { - HDfprintf(stderr, "HDF5 File Close failed\n"); - GOTOERROR(FAIL); - } - - fd->h5fd = -1; - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - GOTOERROR(FAIL); - break; - } - -done: - return ret_code; -} - -/* - * Function: do_cleanupfile - * Purpose: Cleanup temporary file unless HDF5_NOCLEANUP is set. - * Return: void - * Programmer: Albert Cheng 2001/12/12 - * Modifications: Support for file drivers. Christian Chilan, April, 2008 - */ -static void -do_cleanupfile(iotype iot, char *filename) -{ - char temp[2048]; - int j; - hid_t driver; - - if (clean_file_g == -1) - clean_file_g = (HDgetenv("HDF5_NOCLEANUP") == NULL) ? 1 : 0; - - if (clean_file_g) { - - switch (iot) { - case POSIXIO: - HDremove(filename); - break; - - case HDF5: - driver = H5Pget_driver(fapl); - - if (driver == H5FD_FAMILY) { - for (j = 0; /*void*/; j++) { - HDsnprintf(temp, sizeof temp, filename, j); - - if (HDaccess(temp, F_OK) < 0) - break; - - HDremove(temp); - } - } - else if (driver == H5FD_CORE) { - hbool_t backing; /* Whether the core file has backing store */ - - H5Pget_fapl_core(fapl, NULL, &backing); - - /* If the file was stored to disk with bacing store, remove it */ - if (backing) - HDremove(filename); - } - else if (driver == H5FD_MULTI) { - H5FD_mem_t mt; - assert(HDstrlen(multi_letters) == H5FD_MEM_NTYPES); - - for (mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; mt++) { - HDsnprintf(temp, sizeof temp, "%s-%c.h5", filename, multi_letters[mt]); - HDremove(temp); /*don't care if it fails*/ - } - } - else { - HDremove(filename); - } - H5Pclose(fapl); - break; - - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - HDassert(0 && "Unknown IO type"); - break; - } - } -} diff --git a/tools/test/perform/sio_perf.c b/tools/test/perform/sio_perf.c deleted file mode 100644 index 51a7825..0000000 --- a/tools/test/perform/sio_perf.c +++ /dev/null @@ -1,1437 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Serial HDF5 Performance Testing Code - * -------------------------------------- - * - * Portable code to test performance on the different platforms we support. - * This is what the report should look like: - * - * nprocs = Max#Procs - * IO API = POSIXIO - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * - * IO API = HDF5 - * # Files = 1, # of dsets = 1000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * # Files = 1, # of dsets = 3000, Elements per dset = 37000 - * Write Results = x MB/s - * Read Results = x MB/s - * - * . . . - * - * - * . . . - * - */ - -/* system header files */ -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> - -#include "hdf5.h" - -/* our header files */ -#include "sio_perf.h" - -/* useful macros */ -#define TAB_SPACE 4 - -#define ONE_KB 1024 -#define ONE_MB (ONE_KB * ONE_KB) -#define ONE_GB (ONE_MB * ONE_KB) - -#define SIO_POSIX 0x1 -#define SIO_HDF5 0x4 - -/* report 0.0 in case t is zero too */ -#define MB_PER_SEC(bytes, t) (H5_DBL_ABS_EQUAL(t, 0.0) ? 0.0 : ((((double)bytes) / (double)ONE_MB) / (t))) - -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE (!TRUE) -#endif /* FALSE */ - -/* global variables */ -FILE *output; /* output file */ -int sio_debug_level = 0; /* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Maximal & then some - */ - -/* local variables */ -static const char *progname = "h5perf_serial"; - -/* - * Command-line options: The user can specify short or long-named - * parameters. The long-named ones can be partially spelled. When - * adding more, make sure that they don't clash with each other. - */ - -/* - * It seems that only the options that accept additional information - * such as dataset size (-e) require the colon next to it. - */ -static const char * s_opts = "a:A:B:c:Cd:D:e:F:ghi:Imno:p:P:r:stT:v:wx:X:"; -static struct h5_long_options l_opts[] = {{"align", require_arg, 'a'}, - {"alig", require_arg, 'a'}, - {"ali", require_arg, 'a'}, - {"al", require_arg, 'a'}, - {"api", require_arg, 'A'}, - {"ap", require_arg, 'A'}, -#if 0 - /* a sighting of the elusive binary option */ - { "binary", no_arg, 'b' }, - { "binar", no_arg, 'b' }, - { "bina", no_arg, 'b' }, - { "bin", no_arg, 'b' }, - { "bi", no_arg, 'b' }, -#endif /* 0 */ - {"block-size", require_arg, 'B'}, - {"block-siz", require_arg, 'B'}, - {"block-si", require_arg, 'B'}, - {"block-s", require_arg, 'B'}, - {"block-", require_arg, 'B'}, - {"block", require_arg, 'B'}, - {"bloc", require_arg, 'B'}, - {"blo", require_arg, 'B'}, - {"bl", require_arg, 'B'}, - {"chunk", no_arg, 'c'}, - {"chun", no_arg, 'c'}, - {"chu", no_arg, 'c'}, - {"ch", no_arg, 'c'}, - {"collective", no_arg, 'C'}, - {"collectiv", no_arg, 'C'}, - {"collecti", no_arg, 'C'}, - {"collect", no_arg, 'C'}, - {"collec", no_arg, 'C'}, - {"colle", no_arg, 'C'}, - {"coll", no_arg, 'C'}, - {"col", no_arg, 'C'}, - {"co", no_arg, 'C'}, - {"debug", require_arg, 'D'}, - {"debu", require_arg, 'D'}, - {"deb", require_arg, 'D'}, - {"de", require_arg, 'D'}, - {"file-driver", require_arg, 'v'}, - {"file-drive", require_arg, 'v'}, - {"file-driv", require_arg, 'v'}, - {"file-dri", require_arg, 'v'}, - {"file-dr", require_arg, 'v'}, - {"file-d", require_arg, 'v'}, - {"file-", require_arg, 'v'}, - {"file", require_arg, 'v'}, - {"fil", require_arg, 'v'}, - {"fi", require_arg, 'v'}, - {"geometry", no_arg, 'g'}, - {"geometr", no_arg, 'g'}, - {"geomet", no_arg, 'g'}, - {"geome", no_arg, 'g'}, - {"geom", no_arg, 'g'}, - {"geo", no_arg, 'g'}, - {"ge", no_arg, 'g'}, - {"help", no_arg, 'h'}, - {"hel", no_arg, 'h'}, - {"he", no_arg, 'h'}, - {"interleaved", require_arg, 'I'}, - {"interleave", require_arg, 'I'}, - {"interleav", require_arg, 'I'}, - {"interlea", require_arg, 'I'}, - {"interle", require_arg, 'I'}, - {"interl", require_arg, 'I'}, - {"inter", require_arg, 'I'}, - {"inte", require_arg, 'I'}, - {"int", require_arg, 'I'}, - {"in", require_arg, 'I'}, - {"max-num-processes", require_arg, 'P'}, - {"max-num-processe", require_arg, 'P'}, - {"max-num-process", require_arg, 'P'}, - {"max-num-proces", require_arg, 'P'}, - {"max-num-proce", require_arg, 'P'}, - {"max-num-proc", require_arg, 'P'}, - {"max-num-pro", require_arg, 'P'}, - {"max-num-pr", require_arg, 'P'}, - {"max-num-p", require_arg, 'P'}, - {"min-num-processes", require_arg, 'p'}, - {"min-num-processe", require_arg, 'p'}, - {"min-num-process", require_arg, 'p'}, - {"min-num-proces", require_arg, 'p'}, - {"min-num-proce", require_arg, 'p'}, - {"min-num-proc", require_arg, 'p'}, - {"min-num-pro", require_arg, 'p'}, - {"min-num-pr", require_arg, 'p'}, - {"min-num-p", require_arg, 'p'}, - {"max-xfer-size", require_arg, 'X'}, - {"max-xfer-siz", require_arg, 'X'}, - {"max-xfer-si", require_arg, 'X'}, - {"max-xfer-s", require_arg, 'X'}, - {"max-xfer", require_arg, 'X'}, - {"max-xfe", require_arg, 'X'}, - {"max-xf", require_arg, 'X'}, - {"max-x", require_arg, 'X'}, - {"min-xfer-size", require_arg, 'x'}, - {"min-xfer-siz", require_arg, 'x'}, - {"min-xfer-si", require_arg, 'x'}, - {"min-xfer-s", require_arg, 'x'}, - {"min-xfer", require_arg, 'x'}, - {"min-xfe", require_arg, 'x'}, - {"min-xf", require_arg, 'x'}, - {"min-x", require_arg, 'x'}, - {"num-bytes", require_arg, 'e'}, - {"num-byte", require_arg, 'e'}, - {"num-byt", require_arg, 'e'}, - {"num-by", require_arg, 'e'}, - {"num-b", require_arg, 'e'}, - {"num-dsets", require_arg, 'd'}, - {"num-dset", require_arg, 'd'}, - {"num-dse", require_arg, 'd'}, - {"num-ds", require_arg, 'd'}, - {"num-d", require_arg, 'd'}, - {"num-files", require_arg, 'F'}, - {"num-file", require_arg, 'F'}, - {"num-fil", require_arg, 'F'}, - {"num-fi", require_arg, 'F'}, - {"num-f", require_arg, 'F'}, - {"num-iterations", require_arg, 'i'}, - {"num-iteration", require_arg, 'i'}, - {"num-iteratio", require_arg, 'i'}, - {"num-iterati", require_arg, 'i'}, - {"num-iterat", require_arg, 'i'}, - {"num-itera", require_arg, 'i'}, - {"num-iter", require_arg, 'i'}, - {"num-ite", require_arg, 'i'}, - {"num-it", require_arg, 'i'}, - {"num-i", require_arg, 'i'}, - {"order", require_arg, 'r'}, - {"orde", require_arg, 'r'}, - {"ord", require_arg, 'r'}, - {"or", require_arg, 'r'}, - {"output", require_arg, 'o'}, - {"outpu", require_arg, 'o'}, - {"outp", require_arg, 'o'}, - {"out", require_arg, 'o'}, - {"ou", require_arg, 'o'}, - {"extendable", no_arg, 't'}, - {"extendabl", no_arg, 't'}, - {"extendab", no_arg, 't'}, - {"extenda", no_arg, 't'}, - {"extend", no_arg, 't'}, - {"exten", no_arg, 't'}, - {"exte", no_arg, 't'}, - {"ext", no_arg, 't'}, - {"ex", no_arg, 't'}, - {"threshold", require_arg, 'T'}, - {"threshol", require_arg, 'T'}, - {"thresho", require_arg, 'T'}, - {"thresh", require_arg, 'T'}, - {"thres", require_arg, 'T'}, - {"thre", require_arg, 'T'}, - {"thr", require_arg, 'T'}, - {"th", require_arg, 'T'}, - {"write-only", require_arg, 'w'}, - {"write-onl", require_arg, 'w'}, - {"write-on", require_arg, 'w'}, - {"write-o", require_arg, 'w'}, - {"write", require_arg, 'w'}, - {"writ", require_arg, 'w'}, - {"wri", require_arg, 'w'}, - {"wr", require_arg, 'w'}, - {NULL, 0, '\0'}}; - -struct options { - long io_types; /* bitmask of which I/O types to test */ - const char *output_file; /* file to print report to */ - long num_dsets; /* number of datasets */ - long num_files; /* number of files */ - off_t num_bpp; /* number of bytes per proc per dset */ - int num_iters; /* number of iterations */ - hsize_t dset_size[MAX_DIMS]; /* Dataset size */ - size_t buf_size[MAX_DIMS]; /* Buffer size */ - size_t chk_size[MAX_DIMS]; /* Chunk size */ - int order[MAX_DIMS]; /* Dimension access order */ - int dset_rank; /* Rank */ - int buf_rank; /* Rank */ - int order_rank; /* Rank */ - int chk_rank; /* Rank */ - int print_times; /* print times as well as throughputs */ - int print_raw; /* print raw data throughput info */ - hsize_t h5_alignment; /* alignment in HDF5 file */ - hsize_t h5_threshold; /* threshold for alignment in HDF5 file */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int h5_extendable; /* Perform the write tests only */ - int verify; /* Verify data correctness */ - vfdtype vfd; /* File driver */ - size_t page_buffer_size; - size_t page_size; -}; - -typedef struct { - double min; - double max; - double sum; - int num; -} minmax; - -/* local functions */ -static hsize_t parse_size_directive(const char *size); -static struct options *parse_command_line(int argc, const char *argv[]); -static void run_test_loop(struct options *options); -static int run_test(iotype iot, parameters parms, struct options *opts); -static void output_all_info(minmax *mm, int count, int indent_level); -static void get_minmax(minmax *mm, double val); -static void accumulate_minmax_stuff(const minmax *mm, int count, minmax *total_mm); -static void output_results(const struct options *options, const char *name, minmax *table, int table_size, - off_t data_size); -static void output_report(const char *fmt, ...); -static void print_indent(register int indent); -static void usage(const char *prog); -static void report_parameters(struct options *opts); - -/* - * Function: main - * Purpose: Start things up. - * Return: EXIT_SUCCESS or EXIT_FAILURE - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - */ -int -main(int argc, const char *argv[]) -{ - int exit_value = EXIT_SUCCESS; - struct options *opts = NULL; - -#ifndef STANDALONE - /* Initialize h5tools lib */ - h5tools_init(); -#endif - - output = stdout; - - opts = parse_command_line(argc, argv); - - if (!opts) { - exit_value = EXIT_FAILURE; - goto finish; - } - - if (opts->output_file) { - if ((output = HDfopen(opts->output_file, "w")) == NULL) { - HDfprintf(stderr, "%s: cannot open output file\n", progname); - HDperror(opts->output_file); - goto finish; - } - } - - report_parameters(opts); - - run_test_loop(opts); - -finish: - HDfree(opts); - return exit_value; -} - -/* - * Function: run_test_loop - * Purpose: Run the I/O tests. Write the results to OUTPUT. - * - * - The slowest changing part of the test is the number of - * processors to use. For each loop iteration, we divide that - * number by 2 and rerun the test. - * - * - The second slowest is what type of IO API to perform. We have - * three choices: POSIXIO, and HDF5. - * - * - Then we change the size of the buffer. This information is - * inferred from the number of datasets to create and the number - * of integers to put into each dataset. The backend code figures - * this out. - * - * Return: Nothing - * Programmer: Bill Wendling, 30. October 2001 - * Modifications: - * Added multidimensional testing (Christian Chilan, April, 2008) - */ -static void -run_test_loop(struct options *opts) -{ - parameters parms; - int i; - size_t buf_bytes; - - /* load options into parameter structure */ - parms.num_files = opts->num_files; - parms.num_dsets = opts->num_dsets; - parms.num_iters = opts->num_iters; - parms.rank = opts->dset_rank; - parms.h5_align = opts->h5_alignment; - parms.h5_thresh = opts->h5_threshold; - parms.h5_use_chunks = opts->h5_use_chunks; - parms.h5_extendable = opts->h5_extendable; - parms.h5_write_only = opts->h5_write_only; - parms.verify = opts->verify; - parms.vfd = opts->vfd; - parms.page_buffer_size = opts->page_buffer_size; - parms.page_size = opts->page_size; - - /* load multidimensional options */ - parms.num_bytes = 1; - buf_bytes = 1; - for (i = 0; i < parms.rank; i++) { - parms.buf_size[i] = opts->buf_size[i]; - parms.dset_size[i] = opts->dset_size[i]; - parms.chk_size[i] = opts->chk_size[i]; - parms.order[i] = opts->order[i]; - parms.num_bytes *= opts->dset_size[i]; - buf_bytes *= opts->buf_size[i]; - } - - /* print size information */ - output_report("Transfer Buffer Size (bytes): %d\n", buf_bytes); - output_report("File Size(MB): %.2f\n", ((double)parms.num_bytes) / ONE_MB); - - print_indent(0); - if (opts->io_types & SIO_POSIX) - run_test(POSIXIO, parms, opts); - - print_indent(0); - if (opts->io_types & SIO_HDF5) - run_test(HDF5, parms, opts); -} - -/* - * Function: run_test - * Purpose: Inner loop call to actually run the I/O test. - * Return: Nothing - * Programmer: Bill Wendling, 18. December 2001 - * Modifications: - */ -static int -run_test(iotype iot, parameters parms, struct options *opts) -{ - results res; - register int i, ret_value = SUCCESS; - off_t raw_size; - minmax * write_sys_mm_table = NULL; - minmax * write_mm_table = NULL; - minmax * write_gross_mm_table = NULL; - minmax * write_raw_mm_table = NULL; - minmax * read_sys_mm_table = NULL; - minmax * read_mm_table = NULL; - minmax * read_gross_mm_table = NULL; - minmax * read_raw_mm_table = NULL; - minmax write_sys_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax write_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax write_gross_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax write_raw_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_sys_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_gross_mm = {0.0F, 0.0F, 0.0F, 0}; - minmax read_raw_mm = {0.0F, 0.0F, 0.0F, 0}; - - raw_size = (off_t)parms.num_bytes; - parms.io_type = iot; - print_indent(2); - output_report("IO API = "); - - switch (iot) { - case POSIXIO: - output_report("POSIX\n"); - break; - case HDF5: - output_report("HDF5\n"); - break; - default: - /* unknown request */ - HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); - HDassert(0 && "Unknown IO tpe"); - break; - } - - /* allocate space for tables minmax and that it is sufficient */ - /* to initialize all elements to zeros by calloc. */ - write_sys_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - write_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - write_gross_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - write_raw_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - - if (!parms.h5_write_only) { - read_sys_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - read_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - read_gross_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - read_raw_mm_table = (minmax *)calloc((size_t)parms.num_iters, sizeof(minmax)); - } - - /* Do IO iteration times, collecting statistics each time */ - for (i = 0; i < parms.num_iters; ++i) { - double t; - - do_sio(parms, &res); - - /* gather all of the "sys write" times */ - t = io_time_get(res.timers, HDF5_MPI_WRITE); - get_minmax(&write_sys_mm, t); - - write_sys_mm_table[i] = write_sys_mm; - - /* gather all of the "write" times */ - t = io_time_get(res.timers, HDF5_FINE_WRITE_FIXED_DIMS); - get_minmax(&write_mm, t); - - write_mm_table[i] = write_mm; - - /* gather all of the "write" times from open to close */ - t = io_time_get(res.timers, HDF5_GROSS_WRITE_FIXED_DIMS); - get_minmax(&write_gross_mm, t); - - write_gross_mm_table[i] = write_gross_mm; - - /* gather all of the raw "write" times */ - t = io_time_get(res.timers, HDF5_RAW_WRITE_FIXED_DIMS); - get_minmax(&write_raw_mm, t); - - write_raw_mm_table[i] = write_raw_mm; - - if (!parms.h5_write_only) { - /* gather all of the "mpi read" times */ - t = io_time_get(res.timers, HDF5_MPI_READ); - get_minmax(&read_sys_mm, t); - - read_sys_mm_table[i] = read_sys_mm; - - /* gather all of the "read" times */ - t = io_time_get(res.timers, HDF5_FINE_READ_FIXED_DIMS); - get_minmax(&read_mm, t); - - read_mm_table[i] = read_mm; - - /* gather all of the "read" times from open to close */ - t = io_time_get(res.timers, HDF5_GROSS_READ_FIXED_DIMS); - get_minmax(&read_gross_mm, t); - - read_gross_mm_table[i] = read_gross_mm; - - /* gather all of the raw "read" times */ - t = io_time_get(res.timers, HDF5_RAW_READ_FIXED_DIMS); - get_minmax(&read_raw_mm, t); - - read_raw_mm_table[i] = read_gross_mm; - } - io_time_destroy(res.timers); - } - - /* - * Show various statistics - */ - /* Write statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw write" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Write details:\n"); - output_all_info(write_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Raw Data Write", write_raw_mm_table, parms.num_iters, raw_size); - } /* end if */ - - /* show sys write statics */ -#if 0 - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Write details:\n"); - output_all_info(write_sys_mm_table, parms.num_iters, 4); - } -#endif - /* We don't currently output the MPI write results */ - - /* accumulate and output the max, min, and average "write" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write details:\n"); - output_all_info(write_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Write", write_mm_table, parms.num_iters, raw_size); - - /* accumulate and output the max, min, and average "gross write" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Write Open-Close details:\n"); - output_all_info(write_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Write Open-Close", write_gross_mm_table, parms.num_iters, raw_size); - - if (!parms.h5_write_only) { - /* Read statistics */ - /* Print the raw data throughput if desired */ - if (opts->print_raw) { - /* accumulate and output the max, min, and average "raw read" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Raw Data Read details:\n"); - output_all_info(read_raw_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Raw Data Read", read_raw_mm_table, parms.num_iters, raw_size); - } /* end if */ - - /* show mpi read statics */ -#if 0 - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("MPI Read details:\n"); - output_all_info(read_sys_mm_table, parms.num_iters, 4); - } -#endif - /* We don't currently output the MPI read results */ - - /* accumulate and output the max, min, and average "read" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read details:\n"); - output_all_info(read_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read", read_mm_table, parms.num_iters, raw_size); - - /* accumulate and output the max, min, and average "gross read" times */ - if (sio_debug_level >= 3) { - /* output all of the times for all iterations */ - print_indent(3); - output_report("Read Open-Close details:\n"); - output_all_info(read_gross_mm_table, parms.num_iters, 4); - } - - output_results(opts, "Read Open-Close", read_gross_mm_table, parms.num_iters, raw_size); - } - - /* clean up our mess */ - HDfree(write_sys_mm_table); - HDfree(write_mm_table); - HDfree(write_gross_mm_table); - HDfree(write_raw_mm_table); - - if (!parms.h5_write_only) { - HDfree(read_sys_mm_table); - HDfree(read_mm_table); - HDfree(read_gross_mm_table); - HDfree(read_raw_mm_table); - } - - return ret_value; -} - -/* - * Function: output_all_info - * Purpose: - * Return: Nothing - * Programmer: Bill Wendling, 29. January 2002 - * Modifications: - */ -static void -output_all_info(minmax *mm, int count, int indent_level) -{ - int i; - - for (i = 0; i < count; ++i) { - print_indent(indent_level); - output_report("Iteration %d:\n", i + 1); - print_indent(indent_level + 1); - output_report("Minimum Time: %.2fs\n", mm[i].min); - print_indent(indent_level + 1); - output_report("Maximum Time: %.2fs\n", mm[i].max); - } -} - -/* - * Function: get_minmax - * Purpose: Gather all the min, max and total of val. - * Return: Nothing - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Use MPI_Allreduce to do it. -akc, 2002/01/11 - */ - -static void -get_minmax(minmax *mm, double val) -{ - mm->max = val; - mm->min = val; - mm->sum = val; -} - -/* - * Function: accumulate_minmax_stuff - * Purpose: Accumulate the minimum, maximum, and average of the times - * across all processes. - * Return: TOTAL_MM - the total of all of these. - * Programmer: Bill Wendling, 21. December 2001 - * Modifications: - * Changed to use seconds instead of MB/s - QAK, 5/9/02 - */ -static void -accumulate_minmax_stuff(const minmax *mm, int count, minmax *total_mm) -{ - int i; - - total_mm->sum = 0.0F; - total_mm->max = -DBL_MAX; - total_mm->min = DBL_MAX; - total_mm->num = count; - - for (i = 0; i < count; ++i) { - double m = mm[i].max; - - total_mm->sum += m; - - if (m < total_mm->min) - total_mm->min = m; - - if (m > total_mm->max) - total_mm->max = m; - } -} - -/* - * Function: output_results - * Purpose: Print information about the time & bandwidth for a given - * minmax & # of iterations. - * Return: Nothing - * Programmer: Quincey Koziol, 9. May 2002 - * Modifications: - */ -static void -output_results(const struct options *opts, const char *name, minmax *table, int table_size, off_t data_size) -{ - minmax total_mm; - - accumulate_minmax_stuff(table, table_size, &total_mm); - - print_indent(3); - output_report("%s (%d iteration(s)):\n", name, table_size); - - /* Note: The maximum throughput uses the minimum amount of time & vice versa */ - - print_indent(4); - output_report("Maximum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.min)); - if (opts->print_times) - output_report(" (%7.3f s)\n", total_mm.min); - else - output_report("\n"); - - print_indent(4); - output_report("Average Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.sum / total_mm.num)); - if (opts->print_times) - output_report(" (%7.3f s)\n", (total_mm.sum / total_mm.num)); - else - output_report("\n"); - - print_indent(4); - output_report("Minimum Throughput: %6.2f MB/s", MB_PER_SEC(data_size, total_mm.max)); - if (opts->print_times) - output_report(" (%7.3f s)\n", total_mm.max); - else - output_report("\n"); -} - -/* - * Function: output_report - * Purpose: Print a line of the report. Only do so if I'm the 0 process. - * Return: Nothing - * Programmer: Bill Wendling, 19. December 2001 - * Modifications: - */ -static void -output_report(const char *fmt, ...) -{ - va_list ap; - - HDva_start(ap, fmt); - HDvfprintf(output, fmt, ap); - HDva_end(ap); -} - -/* - * Function: print_indent - * Purpose: Print spaces to indent a new line of text for pretty printing - * things. - * Return: Nothing - * Programmer: Bill Wendling, 29. October 2001 - * Modifications: - */ -static void -print_indent(register int indent) -{ - indent *= TAB_SPACE; - - for (; indent > 0; --indent) - HDfputc(' ', output); -} - -static void -recover_size_and_print(long long val, const char *end) -{ - if (val >= ONE_KB && (val % ONE_KB) == 0) { - if (val >= ONE_MB && (val % ONE_MB) == 0) { - if (val >= ONE_GB && (val % ONE_GB) == 0) - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "GB%s", - val / ONE_GB, end); - else - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "MB%s", - val / ONE_MB, end); - } - else { - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "KB%s", - val / ONE_KB, end); - } - } - else { - HDfprintf(output, - "%" H5_PRINTF_LL_WIDTH "d" - "%s", - val, end); - } -} - -static void -print_io_api(long io_types) -{ - if (io_types & SIO_POSIX) - HDfprintf(output, "posix "); - if (io_types & SIO_HDF5) - HDfprintf(output, "hdf5 "); - HDfprintf(output, "\n"); -} - -static void -report_parameters(struct options *opts) -{ - int i, rank; - rank = opts->dset_rank; - - print_version("HDF5 Library"); /* print library version */ - HDfprintf(output, "==== Parameters ====\n"); - - HDfprintf(output, "IO API="); - print_io_api(opts->io_types); - - HDfprintf(output, "Number of iterations=%d\n", opts->num_iters); - - HDfprintf(output, "Dataset size="); - - for (i = 0; i < rank; i++) - recover_size_and_print((long long)opts->dset_size[i], " "); - HDfprintf(output, "\n"); - - HDfprintf(output, "Transfer buffer size="); - for (i = 0; i < rank; i++) - recover_size_and_print((long long)opts->buf_size[i], " "); - HDfprintf(output, "\n"); - - if (opts->page_size) { - HDfprintf(output, "Page Aggregation Enabled. Page size = %zu\n", opts->page_size); - if (opts->page_buffer_size) - HDfprintf(output, "Page Buffering Enabled. Page Buffer size = %zu\n", opts->page_buffer_size); - else - HDfprintf(output, "Page Buffering Disabled\n"); - } - else - HDfprintf(output, "Page Aggregation Disabled\n"); - - HDfprintf(output, "Dimension access order="); - for (i = 0; i < rank; i++) - recover_size_and_print((long long)opts->order[i], " "); - HDfprintf(output, "\n"); - - if (opts->io_types & SIO_HDF5) { - - HDfprintf(output, "HDF5 data storage method="); - - if (opts->h5_use_chunks) { - - HDfprintf(output, "Chunked\n"); - HDfprintf(output, "HDF5 chunk size="); - for (i = 0; i < rank; i++) - recover_size_and_print((long long)opts->chk_size[i], " "); - HDfprintf(output, "\n"); - - HDfprintf(output, "HDF5 dataset dimensions="); - if (opts->h5_extendable) { - HDfprintf(output, "Extendable\n"); - } - else { - HDfprintf(output, "Fixed\n"); - } - } - else { - HDfprintf(output, "Contiguous\n"); - } - - HDfprintf(output, "HDF5 file driver="); - if (opts->vfd == sec2) { - HDfprintf(output, "sec2\n"); - } - else if (opts->vfd == stdio) { - HDfprintf(output, "stdio\n"); - } - else if (opts->vfd == core) { - HDfprintf(output, "core\n"); - } - else if (opts->vfd == split) { - HDfprintf(output, "split\n"); - } - else if (opts->vfd == multi) { - HDfprintf(output, "multi\n"); - } - else if (opts->vfd == family) { - HDfprintf(output, "family\n"); - } - else if (opts->vfd == direct) { - HDfprintf(output, "direct\n"); - } - } - - { - char *prefix = HDgetenv("HDF5_PREFIX"); - - HDfprintf(output, "Env HDF5_PREFIX=%s\n", (prefix ? prefix : "not set")); - } - - HDfprintf(output, "==== End of Parameters ====\n"); - HDfprintf(output, "\n"); -} - -/* - * Function: parse_command_line - * Purpose: Parse the command line options and return a STRUCT OPTIONS - * structure which will need to be freed by the calling function. - * Return: Pointer to an OPTIONS structure - * Programmer: Bill Wendling, 31. October 2001 - * Modifications: - * Added multidimensional testing (Christian Chilan, April, 2008) - */ -static struct options * -parse_command_line(int argc, const char *argv[]) -{ - int opt; - struct options *cl_opts; - int i, default_rank, actual_rank, ranks[4]; - - cl_opts = (struct options *)HDmalloc(sizeof(struct options)); - - cl_opts->page_buffer_size = 0; - cl_opts->page_size = 0; - - cl_opts->output_file = NULL; - cl_opts->io_types = 0; /* will set default after parsing options */ - cl_opts->num_iters = 1; - - default_rank = 2; - - cl_opts->dset_rank = 0; - cl_opts->buf_rank = 0; - cl_opts->chk_rank = 0; - cl_opts->order_rank = 0; - - for (i = 0; i < MAX_DIMS; i++) { - cl_opts->buf_size[i] = (size_t)((i + 1) * 10); - cl_opts->dset_size[i] = (hsize_t)((i + 1) * 100); - cl_opts->chk_size[i] = (size_t)((i + 1) * 10); - cl_opts->order[i] = i + 1; - } - - cl_opts->vfd = sec2; - - cl_opts->print_times = FALSE; /* Printing times is off by default */ - cl_opts->print_raw = FALSE; /* Printing raw data throughput is off by default */ - cl_opts->h5_alignment = 1; /* No alignment for HDF5 objects by default */ - cl_opts->h5_threshold = 1; /* No threshold for aligning HDF5 objects by default */ - cl_opts->h5_use_chunks = FALSE; /* Don't chunk the HDF5 dataset by default */ - cl_opts->h5_write_only = FALSE; /* Do both read and write by default */ - cl_opts->h5_extendable = FALSE; /* Use extendable dataset */ - cl_opts->verify = FALSE; /* No Verify data correctness by default */ - - while ((opt = H5_get_option(argc, argv, s_opts, l_opts)) != EOF) { - switch ((char)opt) { - case 'a': - cl_opts->h5_alignment = parse_size_directive(H5_optarg); - break; - case 'G': - cl_opts->page_size = parse_size_directive(H5_optarg); - break; - case 'b': - cl_opts->page_buffer_size = parse_size_directive(H5_optarg); - break; - case 'A': { - const char *end = H5_optarg; - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - if (!HDstrcasecmp(buf, "hdf5")) { - cl_opts->io_types |= SIO_HDF5; - } - else if (!HDstrcasecmp(buf, "posix")) { - cl_opts->io_types |= SIO_POSIX; - } - else { - HDfprintf(stderr, "sio_perf: invalid --api option %s\n", buf); - HDexit(EXIT_FAILURE); - } - - if (*end == '\0') - break; - - end++; - } - } - - break; -#if 0 - case 'b': - /* the future "binary" option */ - break; -#endif /* 0 */ - case 'c': - /* Turn on chunked HDF5 dataset creation */ - cl_opts->h5_use_chunks = 1; - { - const char *end = H5_optarg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->chk_size[j] = parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - cl_opts->chk_rank = j; - } - - break; - - case 'D': { - const char *end = H5_optarg; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - if (HDstrlen(buf) > 1 || HDisdigit(buf[0])) { - size_t j; - - for (j = 0; j < 10 && buf[j] != '\0'; ++j) - if (!HDisdigit(buf[j])) { - HDfprintf(stderr, "sio_perf: invalid --debug option %s\n", buf); - HDexit(EXIT_FAILURE); - } - - sio_debug_level = atoi(buf); - - if (sio_debug_level > 4) - sio_debug_level = 4; - else if (sio_debug_level < 0) - sio_debug_level = 0; - } - else { - switch (*buf) { - case 'r': - /* Turn on raw data throughput info */ - cl_opts->print_raw = TRUE; - break; - case 't': - /* Turn on time printing */ - cl_opts->print_times = TRUE; - break; - case 'v': - /* Turn on verify data correctness*/ - cl_opts->verify = TRUE; - break; - default: - HDfprintf(stderr, "sio_perf: invalid --debug option %s\n", buf); - HDexit(EXIT_FAILURE); - } - } - - if (*end == '\0') - break; - - end++; - } - } - - break; - case 'e': { - const char *end = H5_optarg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->dset_size[j] = parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - cl_opts->dset_rank = j; - } - - break; - - case 'i': - cl_opts->num_iters = HDatoi(H5_optarg); - break; - case 'o': - cl_opts->output_file = H5_optarg; - break; - case 'T': - cl_opts->h5_threshold = parse_size_directive(H5_optarg); - break; - case 'v': - if (!HDstrcasecmp(H5_optarg, "sec2")) { - cl_opts->vfd = sec2; - } - else if (!HDstrcasecmp(H5_optarg, "stdio")) { - cl_opts->vfd = stdio; - } - else if (!HDstrcasecmp(H5_optarg, "core")) { - cl_opts->vfd = core; - } - else if (!HDstrcasecmp(H5_optarg, "split")) { - cl_opts->vfd = split; - } - else if (!HDstrcasecmp(H5_optarg, "multi")) { - cl_opts->vfd = multi; - } - else if (!HDstrcasecmp(H5_optarg, "family")) { - cl_opts->vfd = family; - } - else if (!HDstrcasecmp(H5_optarg, "direct")) { - cl_opts->vfd = direct; - } - else { - HDfprintf(stderr, "sio_perf: invalid --api option %s\n", H5_optarg); - HDexit(EXIT_FAILURE); - } - break; - case 'w': - cl_opts->h5_write_only = TRUE; - break; - case 't': - cl_opts->h5_extendable = TRUE; - break; - case 'x': { - const char *end = H5_optarg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->buf_size[j] = parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - cl_opts->buf_rank = j; - } - - break; - - case 'r': { - const char *end = H5_optarg; - int j = 0; - - while (end && *end != '\0') { - char buf[10]; - - HDmemset(buf, '\0', sizeof(buf)); - - for (i = 0; *end != '\0' && *end != ','; ++end) - if (HDisalnum(*end) && i < 10) - buf[i++] = *end; - - cl_opts->order[j] = (int)parse_size_directive(buf); - - j++; - - if (*end == '\0') - break; - - end++; - } - - cl_opts->order_rank = j; - } - - break; - - case 'h': - case '?': - default: - usage(progname); - HDfree(cl_opts); - return NULL; - } - } - - /* perform rank consistency analysis */ - actual_rank = 0; - - ranks[0] = cl_opts->dset_rank; - ranks[1] = cl_opts->buf_rank; - ranks[2] = cl_opts->order_rank; - ranks[3] = cl_opts->chk_rank; - - for (i = 0; i < 4; i++) { - if (ranks[i] > 0) { - if (!actual_rank) { - actual_rank = ranks[i]; - } - else { - if (actual_rank != ranks[i]) - exit(EXIT_FAILURE); - } - } - } - - if (!actual_rank) - actual_rank = default_rank; - - cl_opts->dset_rank = actual_rank; - cl_opts->buf_rank = actual_rank; - cl_opts->order_rank = actual_rank; - cl_opts->chk_rank = actual_rank; - - for (i = 0; i < actual_rank; i++) { - if (cl_opts->order[i] > actual_rank) { - exit(EXIT_FAILURE); - } - } - - /* set default if none specified yet */ - if (!cl_opts->io_types) - cl_opts->io_types = SIO_HDF5 | SIO_POSIX; /* run all API */ - - /* verify parameters sanity. Adjust if needed. */ - /* cap xfer_size with bytes per process */ - if (cl_opts->num_iters <= 0) - cl_opts->num_iters = 1; - - return cl_opts; -} - -/* - * Function: parse_size_directive - * Purpose: Parse the size directive passed on the commandline. The size - * directive is an integer followed by a size indicator: - * - * K, k - Kilobyte - * M, m - Megabyte - * G, g - Gigabyte - * - * Return: The size as a off_t because this is related to file size. - * If an unknown size indicator is used, then the program will - * exit with EXIT_FAILURE as the return value. - * Programmer: Bill Wendling, 18. December 2001 - * Modifications: - */ - -static hsize_t -parse_size_directive(const char *size) -{ - hsize_t s; - char * endptr; - - s = HDstrtoull(size, &endptr, 10); - - if (endptr && *endptr) { - while (*endptr != '\0' && (*endptr == ' ' || *endptr == '\t')) - ++endptr; - - switch (*endptr) { - case 'K': - case 'k': - s *= ONE_KB; - break; - - case 'M': - case 'm': - s *= ONE_MB; - break; - - case 'G': - case 'g': - s *= ONE_GB; - break; - - default: - HDfprintf(stderr, "Illegal size specifier '%c'\n", *endptr); - HDexit(EXIT_FAILURE); - } - } - - return s; -} - -/* - * Function: usage - * Purpose: Print a usage message and then exit. - * Return: Nothing - * Programmer: Bill Wendling, 31. October 2001 - * Modifications: - */ -static void -usage(const char *prog) -{ - print_version(prog); - HDprintf("usage: %s [OPTIONS]\n", prog); - HDprintf(" OPTIONS\n"); - HDprintf(" -h Print an usage message and exit\n"); - HDprintf(" -A AL Which APIs to test\n"); - HDprintf(" [default: all of them]\n"); - HDprintf(" -c SL Selects chunked storage and defines chunks dimensions\n"); - HDprintf(" and sizes\n"); - HDprintf(" [default: Off]\n"); - HDprintf(" -e SL Dimensions and sizes of dataset\n"); - HDprintf(" [default: 100,200]\n"); - HDprintf(" -i N Number of iterations to perform\n"); - HDprintf(" [default: 1]\n"); - HDprintf(" -r NL Dimension access order (see below for description)\n"); - HDprintf(" [default: 1,2]\n"); - HDprintf(" -t Selects extendable dimensions for HDF5 dataset\n"); - HDprintf(" [default: Off]\n"); - HDprintf(" -v VFD Selects file driver for HDF5 access\n"); - HDprintf(" [default: sec2]\n"); - HDprintf(" -w Perform write tests, not the read tests\n"); - HDprintf(" [default: Off]\n"); - HDprintf(" -x SL Dimensions and sizes of the transfer buffer\n"); - HDprintf(" [default: 10,20]\n"); - HDprintf("\n"); - HDprintf(" N - is an integer > 0.\n"); - HDprintf("\n"); - HDprintf(" S - is a size specifier, an integer > 0 followed by a size indicator:\n"); - HDprintf(" K - Kilobyte (%d)\n", ONE_KB); - HDprintf(" M - Megabyte (%d)\n", ONE_MB); - HDprintf(" G - Gigabyte (%d)\n", ONE_GB); - HDprintf("\n"); - HDprintf(" Example: '37M' is 37 megabytes or %d bytes\n", 37 * ONE_MB); - HDprintf("\n"); - HDprintf(" AL - is an API list. Valid values are:\n"); - HDprintf(" hdf5 - HDF5\n"); - HDprintf(" posix - POSIX\n"); - HDprintf("\n"); - HDprintf(" Example: -A posix,hdf5\n"); - HDprintf("\n"); - HDprintf(" NL - is list of integers (N) separated by commas.\n"); - HDprintf("\n"); - HDprintf(" Example: 1,2,3\n"); - HDprintf("\n"); - HDprintf(" SL - is list of size specifiers (S) separated by commas.\n"); - HDprintf("\n"); - HDprintf(" Example: 2K,2K,3K\n"); - HDprintf("\n"); - HDprintf(" The example defines an object (dataset, tranfer buffer) with three\n"); - HDprintf(" dimensions. Be aware that as the number of dimensions increases, the\n"); - HDprintf(" the total size of the object increases exponentially.\n"); - HDprintf("\n"); - HDprintf(" VFD - is an HDF5 file driver specifier. Valid values are:\n"); - HDprintf(" sec2, stdio, core, split, multi, family, direct\n"); - HDprintf("\n"); - HDprintf(" Dimension access order:\n"); - HDprintf(" Data access starts at the cardinal origin of the dataset using the\n"); - HDprintf(" transfer buffer. The next access occurs on a dataset region next to\n"); - HDprintf(" the previous one. For a multidimensional dataset, there are several\n"); - HDprintf(" directions as to where to proceed. This can be specified in the dimension\n"); - HDprintf(" access order. For example, -r 1,2 states that the tool should traverse\n"); - HDprintf(" dimension 1 first, and then dimension 2.\n"); - HDprintf("\n"); - HDprintf(" Environment variables:\n"); - HDprintf(" HDF5_NOCLEANUP Do not remove data files if set [default remove]\n"); - HDprintf(" HDF5_PREFIX Data file prefix\n"); - HDprintf("\n"); - HDfflush(stdout); -} /* end usage() */ diff --git a/tools/test/perform/sio_perf.h b/tools/test/perform/sio_perf.h deleted file mode 100644 index 6242782..0000000 --- a/tools/test/perform/sio_perf.h +++ /dev/null @@ -1,104 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef SIO_PERF_H -#define SIO_PERF_H - -#ifndef STANDALONE -#include "io_timer.h" -#include "h5test.h" -#include "h5tools.h" -#include "h5tools_utils.h" -#else -#include "io_timer.h" -#include "sio_standalone.h" -#endif - -/* setup the dataset no fill option if this is v1.5 or more */ -#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR > 4 -#define H5_HAVE_NOFILL 1 -#endif - -#define MAX_DIMS 32 - -typedef enum iotype_ { - POSIXIO, - HDF5 - /*NUM_TYPES*/ -} iotype; - -typedef enum vfdtype_ { - sec2, - stdio, - core, - split, - multi, - family, - direct - /*NUM_TYPES*/ -} vfdtype; - -typedef struct parameters_ { - iotype io_type; /* The type of IO test to perform */ - vfdtype vfd; - long num_files; /* Number of files to create */ - long num_dsets; /* Number of datasets to create */ - hsize_t num_bytes; /* Number of bytes in each dset */ - int num_iters; /* Number of times to loop doing the IO */ - int rank; /* Rank of dataset */ - hsize_t dset_size[MAX_DIMS]; /* Dataset size */ - size_t buf_size[MAX_DIMS]; /* Buffer size */ - size_t chk_size[MAX_DIMS]; /* Chunk size */ - int order[MAX_DIMS]; /* Buffer size */ - hsize_t h5_align; /* HDF5 object alignment */ - hsize_t h5_thresh; /* HDF5 object alignment threshold */ - int h5_use_chunks; /* Make HDF5 dataset chunked */ - int h5_extendable; /* Make HDF5 dataset chunked */ - int h5_write_only; /* Perform the write tests only */ - int verify; /* Verify data correctness */ - size_t page_size; - size_t page_buffer_size; -} parameters; - -typedef struct results_ { - herr_t ret_code; - io_time_t *timers; -} results; - -#ifndef SUCCESS -#define SUCCESS 0 -#endif /* !SUCCESS */ - -#ifndef FAIL -#define FAIL -1 -#endif /* !FAIL */ - -extern FILE * output; /* output file */ -extern io_time_t *timer_g; /* timer: global for stub functions */ -extern int sio_debug_level; /* The debug level: - * 0 - Off - * 1 - Minimal - * 2 - Some more - * 3 - Maximal - * 4 - Even More Debugging (timer stuff) - */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -extern void do_sio(parameters param, results *res); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* SIO_PERF_H */ diff --git a/tools/test/perform/sio_standalone.c b/tools/test/perform/sio_standalone.c index 2e793fb..7c22b53 100644 --- a/tools/test/perform/sio_standalone.c +++ b/tools/test/perform/sio_standalone.c @@ -22,11 +22,6 @@ /* global variables */ int nCols = 80; -/* ``get_option'' variables */ -int H5_opterr = 1; /*get_option prints errors if this is on */ -int H5_optind = 1; /*token pointer */ -const char *H5_optarg; /*flag argument (or value) */ - int get_option(int argc, const char **argv, const char *opts, const struct h5_long_options *l_opts) { diff --git a/tools/test/perform/sio_standalone.h b/tools/test/perform/sio_standalone.h index 098b98a..99cca75 100644 --- a/tools/test/perform/sio_standalone.h +++ b/tools/test/perform/sio_standalone.h @@ -456,22 +456,11 @@ extern char * strdup(const char *s); #define TRUE true #endif -/** From h5test.h **/ - -#ifdef H5_HAVE_PARALLEL -extern MPI_Info h5_io_info_g; /* MPI INFO object for IO */ -#endif - -#ifdef H5_HAVE_PARALLEL -int h5_set_info_object(void); -void h5_dump_info_object(MPI_Info info); -#endif - /** From h5tools_utils.h **/ -extern int H5_opterr; /* getoption prints errors if this is on */ -extern int H5_optind; /* token pointer */ -extern const char *H5_optarg; /* flag argument (or value) */ +H5_DLLVAR int H5_opterr; /* getoption prints errors if this is on */ +H5_DLLVAR int H5_optind; /* token pointer */ +H5_DLLVAR const char *H5_optarg; /* flag argument (or value) */ enum h5_arg_level { no_arg = 0, /* doesn't take an argument */ diff --git a/tools/test/perform/zip_perf.c b/tools/test/perform/zip_perf.c index 6231587..d8cd3a1 100644 --- a/tools/test/perform/zip_perf.c +++ b/tools/test/perform/zip_perf.c @@ -35,7 +35,7 @@ #define MICROSECOND 1000000.0 /* report 0.0 in case t is zero too */ -#define MB_PER_SEC(bytes, t) ((fabs(t) < 0.0000000001) ? 0.0 : ((((double)bytes) / (double)ONE_MB) / (t))) +#define MB_PER_SEC(bytes, t) ((fabs(t) < 0.0000000001) ? 0.0 : ((((double)(bytes)) / (double)ONE_MB) / (t))) #ifndef TRUE #define TRUE 1 @@ -67,62 +67,11 @@ static void compress_buffer(Bytef *dest, uLongf *destLen, const Bytef *source, u static const char * s_opts = "hB:b:c:p:rs:0123456789"; static struct h5_long_options l_opts[] = {{"help", no_arg, 'h'}, {"compressability", require_arg, 'c'}, - {"compressabilit", require_arg, 'c'}, - {"compressabili", require_arg, 'c'}, - {"compressabil", require_arg, 'c'}, - {"compressabi", require_arg, 'c'}, - {"compressab", require_arg, 'c'}, - {"compressa", require_arg, 'c'}, - {"compress", require_arg, 'c'}, - {"compres", require_arg, 'c'}, - {"compre", require_arg, 'c'}, - {"compr", require_arg, 'c'}, - {"comp", require_arg, 'c'}, - {"com", require_arg, 'c'}, - {"co", require_arg, 'c'}, {"file-size", require_arg, 's'}, - {"file-siz", require_arg, 's'}, - {"file-si", require_arg, 's'}, - {"file-s", require_arg, 's'}, - {"file", require_arg, 's'}, - {"fil", require_arg, 's'}, - {"fi", require_arg, 's'}, {"max-buffer-size", require_arg, 'B'}, - {"max-buffer-siz", require_arg, 'B'}, - {"max-buffer-si", require_arg, 'B'}, - {"max-buffer-s", require_arg, 'B'}, - {"max-buffer", require_arg, 'B'}, - {"max-buffe", require_arg, 'B'}, - {"max-buff", require_arg, 'B'}, - {"max-buf", require_arg, 'B'}, - {"max-bu", require_arg, 'B'}, - {"max-b", require_arg, 'B'}, - {"max", require_arg, 'B'}, {"min-buffer-size", require_arg, 'b'}, - {"min-buffer-siz", require_arg, 'b'}, - {"min-buffer-si", require_arg, 'b'}, - {"min-buffer-s", require_arg, 'b'}, - {"min-buffer", require_arg, 'b'}, - {"min-buffe", require_arg, 'b'}, - {"min-buff", require_arg, 'b'}, - {"min-buf", require_arg, 'b'}, - {"min-bu", require_arg, 'b'}, - {"min-b", require_arg, 'b'}, - {"min", require_arg, 'b'}, {"prefix", require_arg, 'p'}, - {"prefi", require_arg, 'p'}, - {"pref", require_arg, 'p'}, - {"pre", require_arg, 'p'}, - {"pr", require_arg, 'p'}, {"random-test", no_arg, 'r'}, - {"random-tes", no_arg, 'r'}, - {"random-te", no_arg, 'r'}, - {"random-t", no_arg, 'r'}, - {"random", no_arg, 'r'}, - {"rando", no_arg, 'r'}, - {"rand", no_arg, 'r'}, - {"ran", no_arg, 'r'}, - {"ra", no_arg, 'r'}, {NULL, 0, '\0'}}; /* -- cgit v0.12