From b5e17f746c741efb0cf1ef6e428ebf96c088aa75 Mon Sep 17 00:00:00 2001 From: John Omotani <john.omotani@ukaea.uk> Date: Tue, 12 Jan 2021 23:39:50 +0100 Subject: [PATCH 1/6] Remove HDF5 support --- .github/workflows/clang-tidy-review.yml | 5 +- .github/workflows/tests.yml | 8 - .travis_fedora.sh | 2 +- CMakeLists.txt | 12 - README.md | 4 +- autoconf_build_defines.hxx.in | 3 - bin/bout-config.in | 7 - bout++Config.cmake.in | 6 - cmake_build_defines.hxx.in | 1 - configure | 1498 ----------------- configure.ac | 33 - include/bout/build_config.hxx | 1 - include/dataformat.hxx | 2 +- m4/ax_lib_hdf5.m4 | 303 ---- m4/ax_lib_parallelhdf5.m4 | 273 --- manual/doxygen/Doxyfile | 2 - manual/doxygen/Doxyfile_readthedocs | 2 - manual/sphinx/developer_docs/code_layout.rst | 7 - manual/sphinx/developer_docs/file_io.rst | 12 +- manual/sphinx/user_docs/advanced_install.rst | 33 +- manual/sphinx/user_docs/bout_options.rst | 20 +- manual/sphinx/user_docs/input_grids.rst | 6 +- manual/sphinx/user_docs/installing.rst | 12 +- manual/sphinx/user_docs/output_and_post.rst | 20 +- manual/sphinx/user_docs/physics_models.rst | 4 +- manual/sphinx/user_docs/python.rst | 5 +- manual/sphinx/user_docs/running_bout.rst | 2 +- manual/sphinx/user_docs/testing.rst | 10 +- src/bout++.cxx | 2 - src/fileio/formatfactory.cxx | 18 - src/fileio/impls/hdf5/h5_format.cxx | 1475 ---------------- src/fileio/impls/hdf5/h5_format.hxx | 183 -- src/fileio/impls/hdf5/makefile | 8 - src/fileio/impls/makefile | 2 +- tests/integrated/.gitignore | 2 - tests/integrated/CMakeLists.txt | 2 - .../doc/drift_instability.bib | 8 - tests/integrated/test-io_hdf5/CMakeLists.txt | 7 - tests/integrated/test-io_hdf5/README.md | 23 - tests/integrated/test-io_hdf5/data/BOUT.inp | 13 - .../test-io_hdf5/data/benchmark.out.0.hdf5 | Bin 727950 -> 0 bytes tests/integrated/test-io_hdf5/generate.py | 31 - tests/integrated/test-io_hdf5/makefile | 6 - tests/integrated/test-io_hdf5/run.sh | 20 - tests/integrated/test-io_hdf5/runtest | 228 --- .../integrated/test-io_hdf5/test_io.grd.hdf5 | Bin 14536 -> 0 bytes .../integrated/test-io_hdf5/test_io_hdf5.cxx | 169 -- .../test-restart-io_hdf5/.gitignore | 1 - .../test-restart-io_hdf5/CMakeLists.txt | 6 - .../test-restart-io_hdf5/data/BOUT.inp | 19 - .../integrated/test-restart-io_hdf5/makefile | 5 - tests/integrated/test-restart-io_hdf5/runtest | 127 -- .../test-restart-io_hdf5/test-restart-io.cxx | 34 - tests/requirements/requirements.py | 2 +- tools/pylib/boutconfig/__init__.py.cin | 1 - 55 files changed, 47 insertions(+), 4638 deletions(-) delete mode 100644 m4/ax_lib_hdf5.m4 delete mode 100644 m4/ax_lib_parallelhdf5.m4 delete mode 100644 src/fileio/impls/hdf5/h5_format.cxx delete mode 100644 src/fileio/impls/hdf5/h5_format.hxx delete mode 100644 src/fileio/impls/hdf5/makefile delete mode 100644 tests/integrated/test-io_hdf5/CMakeLists.txt delete mode 100644 tests/integrated/test-io_hdf5/README.md delete mode 100644 tests/integrated/test-io_hdf5/data/BOUT.inp delete mode 100644 tests/integrated/test-io_hdf5/data/benchmark.out.0.hdf5 delete mode 100644 tests/integrated/test-io_hdf5/generate.py delete mode 100644 tests/integrated/test-io_hdf5/makefile delete mode 100755 tests/integrated/test-io_hdf5/run.sh delete mode 100755 tests/integrated/test-io_hdf5/runtest delete mode 100644 tests/integrated/test-io_hdf5/test_io.grd.hdf5 delete mode 100644 tests/integrated/test-io_hdf5/test_io_hdf5.cxx delete mode 100644 tests/integrated/test-restart-io_hdf5/.gitignore delete mode 100644 tests/integrated/test-restart-io_hdf5/CMakeLists.txt delete mode 100644 tests/integrated/test-restart-io_hdf5/data/BOUT.inp delete mode 100644 tests/integrated/test-restart-io_hdf5/makefile delete mode 100755 tests/integrated/test-restart-io_hdf5/runtest delete mode 100644 tests/integrated/test-restart-io_hdf5/test-restart-io.cxx diff --git a/.github/workflows/clang-tidy-review.yml b/.github/workflows/clang-tidy-review.yml index 7fdcd203fb..b27df6b708 100644 --- a/.github/workflows/clang-tidy-review.yml +++ b/.github/workflows/clang-tidy-review.yml @@ -18,8 +18,6 @@ jobs: libnetcdf-dev libnetcdf-c++4-dev netcdf-bin - hdf5-tools - libhdf5-mpi-dev openmpi-bin libopenmpi-dev petsc-dev @@ -39,7 +37,6 @@ jobs: -DBOUT_ENABLE_OPENMP=ON \ -DBOUT_USE_PETSC=ON \ -DBOUT_USE_SLEPC=ON \ - -DBOUT_USE_HDF5=ON \ -DBOUT_USE_SUNDIALS=ON \ -DBOUT_BUILD_EXAMPLES=ON \ -DCMAKE_EXPORT_COMPILE_COMMANDS=On @@ -49,6 +46,6 @@ jobs: id: review with: build_dir: build - apt_packages: "libfftw3-dev,libnetcdf-c++4-dev,libhdf5-mpi-dev,libopenmpi-dev,petsc-dev,slepc-dev,liblapack-dev,libparpack2-dev,libsundials-dev" + apt_packages: "libfftw3-dev,libnetcdf-c++4-dev,libopenmpi-dev,petsc-dev,slepc-dev,liblapack-dev,libparpack2-dev,libsundials-dev" clang_tidy_checks: '-*,performance-*,readability-*,bugprone-*,clang-analyzer-*,cppcoreguidelines-*,mpi-*,misc-*,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e3cd8195d3..bb38b721a1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,7 +30,6 @@ jobs: os: ubuntu-18.04 configure_options: "--with-petsc --with-slepc - --with-hdf5 --with-sundials=/home/runner/local" script_flags: "-uim" @@ -44,7 +43,6 @@ jobs: --disable-backtrace --with-petsc --with-slepc - --with-hdf5 --with-sundials=/home/runner/local" script_flags: "-uim -t shared -t python" @@ -54,7 +52,6 @@ jobs: --enable-sigfpe --enable-debug --enable-track - --with-hdf5 --with-petsc --with-slepc --with-sundials=/home/runner/local" @@ -66,7 +63,6 @@ jobs: --enable-openmp --with-petsc --with-slepc - --with-hdf5 --with-sundials=/home/runner/local" script_flags: "-uim" omp_num_threads: 2 @@ -77,7 +73,6 @@ jobs: -DBOUT_ENABLE_OPENMP=ON -DBOUT_USE_PETSC=ON -DBOUT_USE_SLEPC=ON - -DBOUT_USE_HDF5=ON -DBOUT_USE_SUNDIALS=ON -DSUNDIALS_ROOT=/home/runner/local" omp_num_threads: 2 @@ -89,7 +84,6 @@ jobs: --enable-debug --enable-track --with-lapack - --with-hdf5 --with-petsc --with-slepc --with-sundials=/home/runner/local" @@ -114,14 +108,12 @@ jobs: libnetcdf-dev libnetcdf-c++4-dev netcdf-bin - hdf5-tools python3 python3-pip python3-pytest python3-numpy python3-scipy lcov - libhdf5-mpi-dev openmpi-bin libopenmpi-dev petsc-dev diff --git a/.travis_fedora.sh b/.travis_fedora.sh index 9ffda6082a..9afd5d6a9c 100755 --- a/.travis_fedora.sh +++ b/.travis_fedora.sh @@ -37,7 +37,7 @@ then cat /etc/os-release # Ignore weak depencies echo "install_weak_deps=False" >> /etc/dnf/dnf.conf - time dnf -y install dnf-plugins-core {petsc,hdf5}-${mpi}-devel /usr/lib/rpm/redhat/redhat-hardened-cc1 python3-h5py + time dnf -y install dnf-plugins-core petsc-${mpi}-devel /usr/lib/rpm/redhat/redhat-hardened-cc1 python3-h5py # Allow to override packages - see #2073 time dnf copr enable -y davidsch/fixes4bout || : time dnf -y upgrade diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bd73f0edd..01149b4a9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -166,8 +166,6 @@ set(BOUT_SOURCES ./src/fileio/formatfactory.cxx ./src/fileio/formatfactory.hxx ./src/fileio/impls/emptyformat.hxx - ./src/fileio/impls/hdf5/h5_format.cxx - ./src/fileio/impls/hdf5/h5_format.hxx ./src/fileio/impls/netcdf/nc_format.cxx ./src/fileio/impls/netcdf/nc_format.hxx ./src/fileio/impls/netcdf4/ncxx4.cxx @@ -518,15 +516,6 @@ endif() message(STATUS "NetCDF support: ${BOUT_USE_NETCDF}") set(BOUT_HAS_NETCDF ${BOUT_USE_NETCDF}) -option(BOUT_USE_HDF5 "Enable support for HDF5 output" OFF) -if (BOUT_USE_HDF5) - find_package(HDF5 REQUIRED COMPONENTS CXX) - target_link_libraries(bout++ PUBLIC "${HDF5_CXX_LIBRARIES}") - target_include_directories(bout++ PUBLIC "${HDF5_CXX_INCLUDE_DIRS}") -endif() -message(STATUS "HDF5 support: ${BOUT_USE_HDF5}") -set(BOUT_HAS_HDF5 ${BOUT_USE_HDF5}) - option(BOUT_USE_FFTW "Enable support for FFTW" ON) if (BOUT_USE_FFTW) find_package(FFTW REQUIRED) @@ -873,7 +862,6 @@ message(" SLEPc support : ${BOUT_HAS_SLEPC} SUNDIALS support : ${BOUT_HAS_SUNDIALS} NetCDF support : ${BOUT_HAS_NETCDF} - HDF5 support : ${BOUT_HAS_HDF5} FFTW support : ${BOUT_HAS_FFTW} LAPACK support : ${BOUT_HAS_LAPACK} OpenMP support : ${BOUT_USE_OPENMP} diff --git a/README.md b/README.md index b136fa8f79..9d0367717a 100644 --- a/README.md +++ b/README.md @@ -62,9 +62,7 @@ BOUT++ needs the following: * A C++14 compiler * MPI -* Either NetCDF or HDF5 - -Note that some of the tests require NetCDF rather than HDF5 +* NetCDF BOUT++ has the following optional dependencies: diff --git a/autoconf_build_defines.hxx.in b/autoconf_build_defines.hxx.in index 925fe967ec..fa2d95d3e8 100644 --- a/autoconf_build_defines.hxx.in +++ b/autoconf_build_defines.hxx.in @@ -15,9 +15,6 @@ /* NLS support */ #undef BOUT_HAS_GETTEXT -/* HDF5 support */ -#undef BOUT_HAS_HDF5 - /* IDA support */ #undef BOUT_HAS_IDA diff --git a/bin/bout-config.in b/bin/bout-config.in index bfcea24c04..a354f6a1d6 100755 --- a/bin/bout-config.in +++ b/bin/bout-config.in @@ -31,7 +31,6 @@ pythonpath="@PYTHONCONFIGPATH@" has_netcdf="@BOUT_HAS_NETCDF@" has_legacy_netcdf="@BOUT_HAS_LEGACY_NETCDF@" has_pnetcdf="@BOUT_HAS_PNETCDF@" -has_hdf5="@BOUT_HAS_HDF5@" has_pvode="@BOUT_HAS_PVODE@" has_cvode="@BOUT_HAS_CVODE@" has_ida="@BOUT_HAS_IDA@" @@ -71,7 +70,6 @@ Available values for OPTION include: --has-netcdf NetCDF file support --has-legacy-netcdf Legacy NetCDF file support --has-pnetcdf Parallel NetCDF file support - --has-hdf5 HDF5 file support --has-pvode PVODE solver support --has-cvode SUNDIALS CVODE solver support --has-ida SUNDIALS IDA solver support @@ -107,7 +105,6 @@ all() echo " --has-netcdf -> $has_netcdf" echo " --has-legacy-netcdf -> $has_legacy_netcdf" echo " --has-pnetcdf -> $has_pnetcdf" - echo " --has-hdf5 -> $has_hdf5" echo " --has-pvode -> $has_pvode" echo " --has-cvode -> $has_cvode" echo " --has-ida -> $has_ida" @@ -200,10 +197,6 @@ while test $# -gt 0; do echo $has_pnetcdf ;; - --has-hdf5) - echo $has_hdf5 - ;; - --has-pvode) echo $has_pvode ;; diff --git a/bout++Config.cmake.in b/bout++Config.cmake.in index f216af16aa..5d46b3edf0 100644 --- a/bout++Config.cmake.in +++ b/bout++Config.cmake.in @@ -58,9 +58,6 @@ endif() if(EXISTS "@netCDFCxx_ROOT@") set(netCDFCxx_ROOT "@netCDFCxx_ROOT@") endif() -if(EXISTS "@HDF5F_ROOT@") - set(HDF5F_ROOT "@HDF5F_ROOT@") -endif() if(EXISTS "@PVODE_ROOT@") set(PVODE_ROOT "@PVODE_ROOT@") endif() @@ -85,9 +82,6 @@ endif() if (BOUT_HAS_NETCDF) find_dependency(netCDFCxx @netCDFCxx_VERSION@) endif() -if (BOUT_HAS_HDF5) - find_dependency(HDF5 @HDF5_VERSION@) -endif() if (BOUT_HAS_PVODE) find_dependency(PVODE @PVODE_VERSION@) endif() diff --git a/cmake_build_defines.hxx.in b/cmake_build_defines.hxx.in index d3edbb752a..f7bee53892 100644 --- a/cmake_build_defines.hxx.in +++ b/cmake_build_defines.hxx.in @@ -9,7 +9,6 @@ #cmakedefine01 BOUT_HAS_CVODE #cmakedefine01 BOUT_HAS_FFTW #cmakedefine01 BOUT_HAS_GETTEXT -#cmakedefine01 BOUT_HAS_HDF5 #cmakedefine01 BOUT_HAS_IDA #cmakedefine01 BOUT_HAS_LAPACK #cmakedefine01 BOUT_HAS_NETCDF diff --git a/configure b/configure index cb5593809b..0c4e13bee2 100755 --- a/configure +++ b/configure @@ -647,7 +647,6 @@ BOUT_HAS_LEGACY_NETCDF BOUT_HAS_NETCDF BOUT_HAS_LAPACK BOUT_HAS_IDA -BOUT_HAS_HDF5 BOUT_HAS_GETTEXT BOUT_HAS_FFTW BOUT_HAS_CVODE @@ -707,26 +706,10 @@ PETSC_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG -PARALLELHDF5_TYPE -PARALLELHDF5_LIBS -PARALLELHDF5_LDFLAGS -PARALLELHDF5_CPPFLAGS -PARALLELHDF5_CFLAGS -PARALLELHDF5_CC -PARALLELHDF5_VERSION -PARALLELH5CC -HDF5_TYPE -HDF5_LIBS -HDF5_LDFLAGS -HDF5_CPPFLAGS -HDF5_CFLAGS -HDF5_CC -HDF5_VERSION CPP ac_ct_CC CFLAGS CC -H5CC AWK NCMPIDUMP_PATH NCCONF @@ -844,8 +827,6 @@ with_openmp_schedule enable_pvode_openmp with_gcov enable_code_coverage -with_hdf5 -with_parallelhdf5 enable_nls with_gnu_ld enable_rpath @@ -1527,9 +1508,6 @@ Optional Packages: --with-openmp-schedule=static/dynamic/guided/auto Set OpenMP schedule (default: static) --with-gcov=GCOV use given GCOV for coverage (GCOV=gcov). - --with-hdf5=yes/no/PATH location of h5cc for serial HDF5 configuration - --with-parallelhdf5=yes/no/PATH - location of h5pcc for parallel HDF5 configuration --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib --without-libiconv-prefix don't search for libiconv in includedir and libdir @@ -7474,1468 +7452,6 @@ $as_echo "$as_me: Parallel-NetCDF support enabled" >&6;} fi -############################################################# -# HDF5 library -############################################################# - -BOUT_HAS_HDF5="no" -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdarg.h> -#include <stdio.h> -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - - -if test "serial" = "" ; then - : # Recognized value -elif test "serial" = "serial" ; then - : # Recognized value -elif test "serial" = "parallel"; then - : # Recognized value -else - as_fn_error $? " -Unrecognized value for AX_LIB_HDF5 within configure.ac. -If supplied, argument 1 must be either 'serial' or 'parallel'. -" "$LINENO" 5 -fi - - -# Check whether --with-hdf5 was given. -if test "${with_hdf5+set}" = set; then : - withval=$with_hdf5; if test "$withval" = "no"; then - with_hdf5="no" - elif test "$withval" = "yes"; then - with_hdf5="yes" - else - with_hdf5="yes" - H5CC="$withval" - fi -else - with_hdf5="guess" - -fi - - -HDF5_CC="" -HDF5_VERSION="" -HDF5_CFLAGS="" -HDF5_CPPFLAGS="" -HDF5_LDFLAGS="" -HDF5_LIBS="" -HDF5_FC="" -HDF5_FFLAGS="" -HDF5_FLIBS="" -HDF5_TYPE="" - -if test "$with_hdf5" = "yes" || test "$with_hdf5" = "guess"; then - if test -z "$H5CC"; then - for ac_prog in h5cc -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_H5CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $H5CC in - [\\/]* | ?:[\\/]*) - ac_cv_path_H5CC="$H5CC" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_H5CC="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -H5CC=$ac_cv_path_H5CC -if test -n "$H5CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $H5CC" >&5 -$as_echo "$H5CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$H5CC" && break -done - - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking Using provided HDF5 C wrapper" >&5 -$as_echo_n "checking Using provided HDF5 C wrapper... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $H5CC" >&5 -$as_echo "$H5CC" >&6; } - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HDF5 type" >&5 -$as_echo_n "checking for HDF5 type... " >&6; } - case $H5CC in #( - *h5pcc) : - HDF5_TYPE=parallel ;; #( - *h5cc) : - HDF5_TYPE=serial ;; #( - *) : - HDF5_TYPE=neither ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HDF5_TYPE" >&5 -$as_echo "$HDF5_TYPE" >&6; } - if test ! -f "$H5CC" || test ! -x "$H5CC"; then - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can compile HDF5 program without helper script" >&5 -$as_echo_n "checking if we can compile HDF5 program without helper script... " >&6; } - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include <hdf5.h> - -int -main () -{ -H5Fcreate(0, 0, 0, 0); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_hdf5_h=yes - ac_cv_libhdf5=yes -else - ac_cv_hdf5_h=no - ac_cv_libhdf5=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libhdf5" >&5 -$as_echo "$ac_cv_libhdf5" >&6; } - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - if test "$ac_cv_libhdf5" = "no" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to compile HDF5 test program" >&5 -$as_echo "$as_me: WARNING: Unable to compile HDF5 test program" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: -Unable to locate serial HDF5 compilation helper script 'h5cc'. -Please specify --with-hdf5=<LOCATION> as the full path to h5cc. -HDF5 support is being disabled (equivalent to --with-hdf5=no). -" >&5 -$as_echo "$as_me: WARNING: -Unable to locate serial HDF5 compilation helper script 'h5cc'. -Please specify --with-hdf5=<LOCATION> as the full path to h5cc. -HDF5 support is being disabled (equivalent to --with-hdf5=no). -" >&2;} - if test "$with_hdf5" = "yes"; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "HDF5 was requested, but could not be compiled -See \`config.log' for more details" "$LINENO" 5; } - fi - with_hdf5="no" - else - with_hdf5="yes" - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HDF5 libraries" >&5 -$as_echo_n "checking for HDF5 libraries... " >&6; } - HDF5_SHOW=$(eval $H5CC -show) - - HDF5_CC=$(eval $H5CC -show | $AWK '{print $1}') - if test "$HDF5_CC" = "ccache"; then - HDF5_CC=$(eval $H5CC -show | $AWK '{print $2}') - fi - - - HDF5_VERSION=$(eval $H5CC -showconfig | $GREP 'HDF5 Version:' \ - | $AWK '{print $3}') - - HDF5_tmp_flags=$(eval $H5CC -showconfig \ - | $GREP 'FLAGS\|Extra libraries:' \ - | $AWK -F: '{printf("%s "), $2}' ) - - HDF5_tmp_inst=$(eval $H5CC -showconfig \ - | $GREP 'Installation point:' \ - | $AWK '{print $NF}' ) - - HDF5_CPPFLAGS="-I${HDF5_tmp_inst}/include" - - for arg in $HDF5_SHOW $HDF5_tmp_flags ; do - case "$arg" in - -I*) echo $HDF5_CPPFLAGS | $GREP -e "$arg" 2>&1 >/dev/null \ - || HDF5_CPPFLAGS="$HDF5_CPPFLAGS $arg" - ;; - -L*) echo $HDF5_LDFLAGS | $GREP -e "$arg" 2>&1 >/dev/null \ - || HDF5_LDFLAGS="$HDF5_LDFLAGS $arg" - ;; - -l*) echo $HDF5_LIBS | $GREP -e "$arg" 2>&1 >/dev/null \ - || HDF5_LIBS="$HDF5_LIBS $arg" - ;; - esac - done - - HDF5_LIBS="-lhdf5 $HDF5_LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (version $HDF5_VERSION)" >&5 -$as_echo "yes (version $HDF5_VERSION)" >&6; } - - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - ax_lib_hdf5_save_CC=$CC - ax_lib_hdf5_save_CPPFLAGS=$CPPFLAGS - ax_lib_hdf5_save_LIBS=$LIBS - ax_lib_hdf5_save_LDFLAGS=$LDFLAGS - CC=$HDF5_CC - CPPFLAGS=$HDF5_CPPFLAGS - LIBS=$HDF5_LIBS - LDFLAGS=$HDF5_LDFLAGS - ac_fn_c_check_header_mongrel "$LINENO" "hdf5.h" "ac_cv_header_hdf5_h" "$ac_includes_default" -if test "x$ac_cv_header_hdf5_h" = xyes; then : - ac_cv_hdf5_h=yes -else - ac_cv_hdf5_h=no -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for H5Fcreate in -lhdf5" >&5 -$as_echo_n "checking for H5Fcreate in -lhdf5... " >&6; } -if ${ac_cv_lib_hdf5_H5Fcreate+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lhdf5 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char H5Fcreate (); -int -main () -{ -return H5Fcreate (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_hdf5_H5Fcreate=yes -else - ac_cv_lib_hdf5_H5Fcreate=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_hdf5_H5Fcreate" >&5 -$as_echo "$ac_cv_lib_hdf5_H5Fcreate" >&6; } -if test "x$ac_cv_lib_hdf5_H5Fcreate" = xyes; then : - ac_cv_libhdf5=yes -else - ac_cv_libhdf5=no -fi - - if test "$ac_cv_hdf5_h" = "no" && test "$ac_cv_libhdf5" = "no" ; then - if test "$with_hdf5" = "yes"; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Unable to compile HDF5 test program -See \`config.log' for more details" "$LINENO" 5; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to compile HDF5 test program" >&5 -$as_echo "$as_me: WARNING: Unable to compile HDF5 test program" >&2;} - fi - fi - with_hdf5=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lhdf5_hl" >&5 -$as_echo_n "checking for main in -lhdf5_hl... " >&6; } -if ${ac_cv_lib_hdf5_hl_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lhdf5_hl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_hdf5_hl_main=yes -else - ac_cv_lib_hdf5_hl_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_hdf5_hl_main" >&5 -$as_echo "$ac_cv_lib_hdf5_hl_main" >&6; } -if test "x$ac_cv_lib_hdf5_hl_main" = xyes; then : - HDF5_LIBS="-lhdf5_hl $HDF5_LIBS" -fi -ac_cv_lib_hdf5_hl=ac_cv_lib_hdf5_hl_main - - - CC=$ax_lib_hdf5_save_CC - CPPFLAGS=$ax_lib_hdf5_save_CPPFLAGS - LIBS=$ax_lib_hdf5_save_LIBS - LDFLAGS=$ax_lib_hdf5_save_LDFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - - - - - - - - -$as_echo "#define HAVE_HDF5 1" >>confdefs.h - - fi -fi - -if test "$with_hdf5" = "yes"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Found HDF5" >&5 -$as_echo "$as_me: Found HDF5" >&6;} - EXTRA_INCS="$EXTRA_INCS $HDF5_CPPFLAGS" - EXTRA_LIBS="$EXTRA_LIBS $HDF5_LDFLAGS $HDF5_LIBS" - BOUT_HAS_HDF5="yes" - file_formats="$file_formats HDF5" - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Serial HDF5 support disabled" >&5 -$as_echo "$as_me: Serial HDF5 support disabled" >&6;} - -fi - -BOUT_HAS_PHDF5="no" - - - - - - - -# Check whether --with-parallelhdf5 was given. -if test "${with_parallelhdf5+set}" = set; then : - withval=$with_parallelhdf5; if test "$withval" = "no"; then - with_parallelhdf5="no" - elif test "$withval" = "yes"; then - with_parallelhdf5="yes" - else - with_parallelhdf5="yes" - PARALLELH5CC="$withval" - fi -else - with_parallelhdf5="no" - -fi - - -PARALLELHDF5_CC="" -PARALLELHDF5_VERSION="" -PARALLELHDF5_CFLAGS="" -PARALLELHDF5_CPPFLAGS="" -PARALLELHDF5_LDFLAGS="" -PARALLELHDF5_LIBS="" -PARALLELHDF5_FC="" -PARALLELHDF5_FFLAGS="" -PARALLELHDF5_FLIBS="" -PARALLELHDF5_TYPE="" - -if test "$with_parallelhdf5" = "yes"; then - if test -z "$PARALLELH5CC"; then - for ac_prog in h5pcc - -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PARALLELH5CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PARALLELH5CC in - [\\/]* | ?:[\\/]*) - ac_cv_path_PARALLELH5CC="$PARALLELH5CC" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PARALLELH5CC="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PARALLELH5CC=$ac_cv_path_PARALLELH5CC -if test -n "$PARALLELH5CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PARALLELH5CC" >&5 -$as_echo "$PARALLELH5CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$PARALLELH5CC" && break -done - - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking Using provided HDF5 C wrapper" >&5 -$as_echo_n "checking Using provided HDF5 C wrapper... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PARALLELH5CC" >&5 -$as_echo "$PARALLELH5CC" >&6; } - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HDF5 type" >&5 -$as_echo_n "checking for HDF5 type... " >&6; } - case $PARALLELH5CC in #( - *h5pcc) : - PARALLELHDF5_TYPE=parallel ;; #( - *h5cc) : - PARALLELHDF5_TYPE=serial ;; #( - *) : - PARALLELHDF5_TYPE=neither ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PARALLELHDF5_TYPE" >&5 -$as_echo "$PARALLELHDF5_TYPE" >&6; } - - if test ! -f "$PARALLELH5CC" || test ! -x "$PARALLELH5CC"; then - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can compile parallel HDF5 program without helper script" >&5 -$as_echo_n "checking if we can compile parallel HDF5 program without helper script... " >&6; } - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include <hdf5.h> - -int -main () -{ -H5Fcreate(0, 0, 0, 0); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_parallelhdf5_h=yes - ac_cv_libparallelhdf5=yes -else - ac_cv_parallelhdf5_h=no - ac_cv_libparallelhdf5=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_parallelhdf5_h" >&5 -$as_echo "$ac_cv_parallelhdf5_h" >&6; } - - if test "$ac_cv_parallelhdf5_h" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if found HDF5 is parallel" >&5 -$as_echo_n "checking if found HDF5 is parallel... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include <H5pubconf.h> - #ifdef H5_HAVE_PARALLEL - yes - #endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : - ac_cv_parallelhdf5_h=yes -else - ac_cv_parallelhdf5_h=no -fi -rm -f conftest* - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_parallelhdf5_h" >&5 -$as_echo "$ac_cv_parallelhdf5_h" >&6; } - fi - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - if test "$ac_cv_parallelhdf5_h" = "no" ; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? " -Unable to locate parallel HDF5 compilation helper script 'h5pcc'. -Please specify --with-parallelhdf5=<LOCATION> as the full path to h5pcc. -HDF5 support is being disabled (equivalent to --with-parallelhdf5=no). - -See \`config.log' for more details" "$LINENO" 5; } - with_parallelhdf5="no" - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HDF5 libraries" >&5 -$as_echo_n "checking for HDF5 libraries... " >&6; } - PARALLELHDF5_SHOW=$(eval $PARALLELH5CC -show) - - PARALLELHDF5_CC=$(eval $PARALLELH5CC -show | $AWK '{print $1}') - if test "$PARALLELHDF5_CC" = "ccache"; then - PARALLELHDF5_CC=$(eval $PARALLELH5CC -show | $AWK '{print $2}') - fi - - - PARALLELHDF5_VERSION=$(eval $PARALLELH5CC -showconfig | $GREP 'HDF5 Version:' \ - | $AWK '{print $3}') - - PARALLELHDF5_tmp_flags=$(eval $PARALLELH5CC -showconfig \ - | $GREP 'FLAGS\|Extra libraries:' \ - | $AWK -F: '{printf("%s "), $2}' ) - - PARALLELHDF5_tmp_inst=$(eval $PARALLELH5CC -showconfig \ - | $GREP 'Installation point:' \ - | $AWK '{print $NF}' ) - - PARALLELHDF5_CPPFLAGS="-I${PARALLELHDF5_tmp_inst}/include" - - for arg in $PARALLELHDF5_SHOW $PARALLELHDF5_tmp_flags ; do - case "$arg" in - -I*) echo $PARALLELHDF5_CPPFLAGS | $GREP -e "$arg" 2>&1 >/dev/null \ - || PARALLELHDF5_CPPFLAGS="$PARALLELHDF5_CPPFLAGS $arg" - ;; - -L*) echo $PARALLELHDF5_LDFLAGS | $GREP -e "$arg" 2>&1 >/dev/null \ - || PARALLELHDF5_LDFLAGS="$PARALLELHDF5_LDFLAGS $arg" - ;; - -l*) echo $PARALLELHDF5_LIBS | $GREP -e "$arg" 2>&1 >/dev/null \ - || PARALLELHDF5_LIBS="$PARALLELHDF5_LIBS $arg" - ;; - esac - done - - PARALLELHDF5_LIBS="-lhdf5 $PARALLELHDF5_LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (version $PARALLELHDF5_VERSION)" >&5 -$as_echo "yes (version $PARALLELHDF5_VERSION)" >&6; } - - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - ax_lib_parallelhdf5_save_CC=$CC - ax_lib_parallelhdf5_save_CPPFLAGS=$CPPFLAGS - ax_lib_parallelhdf5_save_LIBS=$LIBS - ax_lib_parallelhdf5_save_LDFLAGS=$LDFLAGS - CC=$PARALLELHDF5_CC - CPPFLAGS=$PARALLELHDF5_CPPFLAGS - LIBS=$PARALLELHDF5_LIBS - LDFLAGS=$PARALLELHDF5_LDFLAGS - ac_fn_c_check_header_mongrel "$LINENO" "hdf5.h" "ac_cv_header_hdf5_h" "$ac_includes_default" -if test "x$ac_cv_header_hdf5_h" = xyes; then : - ac_cv_parallelhdf5_h=yes -else - ac_cv_parallelhdf5_h=no -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for H5Fcreate in -lhdf5" >&5 -$as_echo_n "checking for H5Fcreate in -lhdf5... " >&6; } -if ${ac_cv_lib_hdf5_H5Fcreate+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lhdf5 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char H5Fcreate (); -int -main () -{ -return H5Fcreate (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_hdf5_H5Fcreate=yes -else - ac_cv_lib_hdf5_H5Fcreate=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_hdf5_H5Fcreate" >&5 -$as_echo "$ac_cv_lib_hdf5_H5Fcreate" >&6; } -if test "x$ac_cv_lib_hdf5_H5Fcreate" = xyes; then : - ac_cv_libparallelhdf5=yes -else - ac_cv_libparallelhdf5=no -fi - - if test "$ac_cv_parallelhdf5_h" = "no" && test "$ac_cv_libparallelhdf5" = "no" ; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Unable to compile HDF5 test program -See \`config.log' for more details" "$LINENO" 5; } - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lhdf5_hl" >&5 -$as_echo_n "checking for main in -lhdf5_hl... " >&6; } -if ${ac_cv_lib_hdf5_hl_main+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lhdf5_hl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_hdf5_hl_main=yes -else - ac_cv_lib_hdf5_hl_main=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_hdf5_hl_main" >&5 -$as_echo "$ac_cv_lib_hdf5_hl_main" >&6; } -if test "x$ac_cv_lib_hdf5_hl_main" = xyes; then : - PARALLELHDF5_LIBS="-lhdf5_hl $PARALLELHDF5_LIBS" -fi -ac_cv_lib_hdf5_hl=ac_cv_lib_hdf5_hl_main - - - CC=$ax_lib_parallelhdf5_save_CC - CPPFLAGS=$ax_lib_parallelhdf5_save_CPPFLAGS - LIBS=$ax_lib_parallelhdf5_save_LIBS - LDFLAGS=$ax_lib_parallelhdf5_save_LDFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - - - - - - - - -$as_echo "#define HAVE_PARALLELHDF5 1" >>confdefs.h - - fi -fi - -if test "$with_parallelhdf5" = "yes"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Found parallel HDF5" >&5 -$as_echo "$as_me: Found parallel HDF5" >&6;} - CXXFLAGS="$CXXFLAGS -DPHDF5" - EXTRA_INCS="$EXTRA_INCS $PARALLELHDF5_CPPFLAGS" - EXTRA_LIBS="$EXTRA_LIBS $PARALLELHDF5_LDFLAGS $PARALLELHDF5_LIBS" - BOUT_HAS_PHDF5="yes" - file_formats="$file_formats Parallel HDF5" - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Parallel HDF5 support disabled" >&5 -$as_echo "$as_me: Parallel HDF5 support disabled" >&6;} - -fi - ############################################################# # Check file formats ############################################################# @@ -16326,18 +14842,6 @@ fi -if test "x$BOUT_HAS_HDF5" = "xyes"; then : - -$as_echo "#define BOUT_HAS_HDF5 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_HDF5 0" >>confdefs.h - -fi - - - if test "x$BOUT_HAS_IDA" = "xyes"; then : $as_echo "#define BOUT_HAS_IDA 1" >>confdefs.h @@ -18069,8 +16573,6 @@ $as_echo "$as_me: FFTW support : $BOUT_HAS_FFTW" >&6;} $as_echo "$as_me: NetCDF support : $BOUT_HAS_NETCDF (legacy: $BOUT_HAS_LEGACY_NETCDF)" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Parallel-NetCDF support : $BOUT_HAS_PNETCDF" >&5 $as_echo "$as_me: Parallel-NetCDF support : $BOUT_HAS_PNETCDF" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: HDF5 support : $BOUT_HAS_HDF5 (parallel: $BOUT_HAS_PHDF5)" >&5 -$as_echo "$as_me: HDF5 support : $BOUT_HAS_HDF5 (parallel: $BOUT_HAS_PHDF5)" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Lapack support : $BOUT_HAS_LAPACK" >&5 $as_echo "$as_me: Lapack support : $BOUT_HAS_LAPACK" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Scorep support : $BOUT_HAS_SCOREP" >&5 diff --git a/configure.ac b/configure.ac index 1f6614f9c3..263bbc074a 100644 --- a/configure.ac +++ b/configure.ac @@ -63,8 +63,6 @@ AC_ARG_WITH(scorep, [AS_HELP_STRING([--with-scorep], AC_ARG_WITH(system_mpark, [AS_HELP_STRING([--with-system-mpark], [Use mpark.variant already installed rather then the bundled one])],,[with_system_mpark=auto]) -dnl --with-hdf5 flags are set in AX_LIB_{PARALLEL}HDF5 - AC_ARG_ENABLE(warnings, [AS_HELP_STRING([--disable-warnings], [Disable compiler warnings])],,[]) AC_ARG_ENABLE(checks, [AS_HELP_STRING([--enable-checks=no/1/2/3], @@ -636,35 +634,6 @@ AS_IF([test "x$PNCPATH" = "x"], [ AC_MSG_NOTICE([Parallel-NetCDF support enabled]) ]) -############################################################# -# HDF5 library -############################################################# - -BOUT_HAS_HDF5="no" -AX_LIB_HDF5([serial]) -AS_IF([test "$with_hdf5" = "yes"], [ - AC_MSG_NOTICE([Found HDF5]) - EXTRA_INCS="$EXTRA_INCS $HDF5_CPPFLAGS" - EXTRA_LIBS="$EXTRA_LIBS $HDF5_LDFLAGS $HDF5_LIBS" - BOUT_HAS_HDF5="yes" - file_formats="$file_formats HDF5" - ], [ - AC_MSG_NOTICE([Serial HDF5 support disabled]) -]) - -BOUT_HAS_PHDF5="no" -AX_LIB_PARALLELHDF5() -AS_IF([test "$with_parallelhdf5" = "yes"], [ - AC_MSG_NOTICE([Found parallel HDF5]) - CXXFLAGS="$CXXFLAGS -DPHDF5" - EXTRA_INCS="$EXTRA_INCS $PARALLELHDF5_CPPFLAGS" - EXTRA_LIBS="$EXTRA_LIBS $PARALLELHDF5_LDFLAGS $PARALLELHDF5_LIBS" - BOUT_HAS_PHDF5="yes" - file_formats="$file_formats Parallel HDF5" - ], [ - AC_MSG_NOTICE([Parallel HDF5 support disabled]) -]) - ############################################################# # Check file formats ############################################################# @@ -1343,7 +1312,6 @@ BOUT_DEFINE_SUBST(BOUT_HAS_ARKODE, [ARKODE support]) BOUT_DEFINE_SUBST(BOUT_HAS_CVODE, [CVODE support]) BOUT_DEFINE_SUBST(BOUT_HAS_FFTW, [FFTW support]) BOUT_DEFINE_SUBST(BOUT_HAS_GETTEXT, [NLS support]) -BOUT_DEFINE_SUBST(BOUT_HAS_HDF5, [HDF5 support]) BOUT_DEFINE_SUBST(BOUT_HAS_IDA, [IDA support]) BOUT_DEFINE_SUBST(BOUT_HAS_LAPACK, [LAPACK support]) BOUT_DEFINE_SUBST(BOUT_HAS_NETCDF, [NETCDF support]) @@ -1397,7 +1365,6 @@ AC_MSG_NOTICE([ ARKODE support : $BOUT_HAS_ARKODE]) AC_MSG_NOTICE([ FFTW support : $BOUT_HAS_FFTW]) AC_MSG_NOTICE([ NetCDF support : $BOUT_HAS_NETCDF (legacy: $BOUT_HAS_LEGACY_NETCDF)]) AC_MSG_NOTICE([ Parallel-NetCDF support : $BOUT_HAS_PNETCDF]) -AC_MSG_NOTICE([ HDF5 support : $BOUT_HAS_HDF5 (parallel: $BOUT_HAS_PHDF5)]) AC_MSG_NOTICE([ Lapack support : $BOUT_HAS_LAPACK]) AC_MSG_NOTICE([ Scorep support : $BOUT_HAS_SCOREP]) AC_MSG_NOTICE([ OpenMP support : $BOUT_USE_OPENMP (schedule: $OPENMP_SCHEDULE)]) diff --git a/include/bout/build_config.hxx b/include/bout/build_config.hxx index acd8a6b33b..07bd38dd95 100644 --- a/include/bout/build_config.hxx +++ b/include/bout/build_config.hxx @@ -14,7 +14,6 @@ constexpr auto openmp_schedule = STRINGIFY(BOUT_OPENMP_SCHEDULE); constexpr auto has_fftw = static_cast<bool>(BOUT_HAS_FFTW); constexpr auto has_gettext = static_cast<bool>(BOUT_HAS_GETTEXT); -constexpr auto has_hdf5 = static_cast<bool>(BOUT_HAS_HDF5); constexpr auto has_lapack = static_cast<bool>(BOUT_HAS_LAPACK); constexpr auto has_legacy_netcdf = static_cast<bool>(BOUT_HAS_LEGACY_NETCDF); constexpr auto has_netcdf = static_cast<bool>(BOUT_HAS_NETCDF); diff --git a/include/dataformat.hxx b/include/dataformat.hxx index 204d103483..b8d1321464 100644 --- a/include/dataformat.hxx +++ b/include/dataformat.hxx @@ -1,7 +1,7 @@ /*! * \file dataformat.hxx * - * \brief Generic interface for file formats e.g. netCDF, HDF5 + * \brief Generic interface for file formats e.g. netCDF * * \author B.Dudson * \date April 2009 diff --git a/m4/ax_lib_hdf5.m4 b/m4/ax_lib_hdf5.m4 deleted file mode 100644 index edd10839ab..0000000000 --- a/m4/ax_lib_hdf5.m4 +++ /dev/null @@ -1,303 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_lib_hdf5.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_LIB_HDF5([serial/parallel]) -# -# DESCRIPTION -# -# This macro provides tests of the availability of HDF5 library. -# -# The optional macro argument should be either 'serial' or 'parallel'. The -# former only looks for serial HDF5 installations via h5cc. The latter -# only looks for parallel HDF5 installations via h5pcc. If the optional -# argument is omitted, serial installations will be preferred over -# parallel ones. -# -# The macro adds a --with-hdf5 option accepting one of three values: -# -# no - do not check for the HDF5 library. -# yes - do check for HDF5 library in standard locations. -# path - complete path to the HDF5 helper script h5cc or h5pcc. -# -# If HDF5 is successfully found, this macro calls -# -# AC_SUBST(HDF5_VERSION) -# AC_SUBST(HDF5_CC) -# AC_SUBST(HDF5_CFLAGS) -# AC_SUBST(HDF5_CPPFLAGS) -# AC_SUBST(HDF5_LDFLAGS) -# AC_SUBST(HDF5_LIBS) -# AC_SUBST(HDF5_FC) -# AC_SUBST(HDF5_FFLAGS) -# AC_SUBST(HDF5_FLIBS) -# AC_SUBST(HDF5_TYPE) -# AC_DEFINE(HAVE_HDF5) -# -# and sets with_hdf5="yes". Additionally, the macro sets -# with_hdf5_fortran="yes" if a matching Fortran wrapper script is found. -# Note that Autconf's Fortran support is not used to perform this check. -# H5CC and H5FC will contain the appropriate serial or parallel HDF5 -# wrapper script locations. -# -# If HDF5 is disabled or not found, this macros sets with_hdf5="no" and -# with_hdf5_fortran="no". -# -# Your configuration script can test $with_hdf to take any further -# actions. HDF5_{C,CPP,LD}FLAGS may be used when building with C or C++. -# HDF5_F{FLAGS,LIBS} should be used when building Fortran applications. -# -# To use the macro, one would code one of the following in "configure.ac" -# before AC_OUTPUT: -# -# 1) dnl Check for HDF5 support -# AX_LIB_HDF5() -# -# 2) dnl Check for serial HDF5 support -# AX_LIB_HDF5([serial]) -# -# 3) dnl Check for parallel HDF5 support -# AX_LIB_HDF5([parallel]) -# -# One could test $with_hdf5 for the outcome or display it as follows -# -# echo "HDF5 support: $with_hdf5" -# -# You could also for example, override the default CC in "configure.ac" to -# enforce compilation with the compiler that HDF5 uses: -# -# AX_LIB_HDF5([parallel]) -# if test "$with_hdf5" = "yes"; then -# CC="$HDF5_CC" -# else -# AC_MSG_ERROR([Unable to find HDF5, we need parallel HDF5.]) -# fi -# -# The HDF5_TYPE environment variable returns "parallel" or "serial", -# depending on which type of library is found. -# -# LICENSE -# -# Copyright (c) 2009 Timothy Brown <tbrown@freeshell.org> -# Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com> -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 15 - -AC_DEFUN([AX_LIB_HDF5], [ - -AC_REQUIRE([AC_PROG_SED]) -AC_REQUIRE([AC_PROG_AWK]) -AC_REQUIRE([AC_PROG_GREP]) - -dnl Check first argument is one of the recognized values. -dnl Fail eagerly if is incorrect as this simplifies case statements below. -if test "m4_normalize(m4_default([$1],[]))" = "" ; then - : # Recognized value -elif test "m4_normalize(m4_default([$1],[]))" = "serial" ; then - : # Recognized value -elif test "m4_normalize(m4_default([$1],[]))" = "parallel"; then - : # Recognized value -else - AC_MSG_ERROR([ -Unrecognized value for AX[]_LIB_HDF5 within configure.ac. -If supplied, argument 1 must be either 'serial' or 'parallel'. -]) -fi - -dnl Add a default --with-hdf5 configuration option. -AC_ARG_WITH([hdf5], - AS_HELP_STRING( - [--with-hdf5=[yes/no/PATH]], - m4_case(m4_normalize([$1]), - [serial], [location of h5cc for serial HDF5 configuration], - [parallel], [location of h5pcc for parallel HDF5 configuration], - [location of h5cc or h5pcc for HDF5 configuration]) - ), - [if test "$withval" = "no"; then - with_hdf5="no" - elif test "$withval" = "yes"; then - with_hdf5="yes" - else - with_hdf5="yes" - H5CC="$withval" - fi], - [with_hdf5="guess"] -) - -dnl Set defaults to blank -HDF5_CC="" -HDF5_VERSION="" -HDF5_CFLAGS="" -HDF5_CPPFLAGS="" -HDF5_LDFLAGS="" -HDF5_LIBS="" -HDF5_FC="" -HDF5_FFLAGS="" -HDF5_FLIBS="" -HDF5_TYPE="" - -dnl Try and find hdf5 compiler tools and options. -if test "$with_hdf5" = "yes" || test "$with_hdf5" = "guess"; then - if test -z "$H5CC"; then - dnl Check to see if H5CC is in the path. - AC_PATH_PROGS( - [H5CC], - m4_case(m4_normalize([$1]), - [serial], [h5cc], - [parallel], [h5pcc], - [h5cc h5pcc]), - []) - else - AC_MSG_CHECKING([Using provided HDF5 C wrapper]) - AC_MSG_RESULT([$H5CC]) - fi - AC_MSG_CHECKING([for HDF5 type]) - AS_CASE([$H5CC], - [*h5pcc], [HDF5_TYPE=parallel], - [*h5cc], [HDF5_TYPE=serial], - [HDF5_TYPE=neither]) - AC_MSG_RESULT([$HDF5_TYPE]) - if test ! -f "$H5CC" || test ! -x "$H5CC"; then - - AC_MSG_CHECKING([if we can compile HDF5 program without helper script]) - AC_LANG_PUSH([C++]) - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([ - #include <hdf5.h> - ], [H5Fcreate(0, 0, 0, 0);])], - [ac_cv_hdf5_h=yes - ac_cv_libhdf5=yes], - [ac_cv_hdf5_h=no - ac_cv_libhdf5=no]) - AC_MSG_RESULT([$ac_cv_libhdf5]) - AC_LANG_POP([C++]) - - if test "$ac_cv_libhdf5" = "no" ; then - AC_MSG_WARN([Unable to compile HDF5 test program]) - AC_MSG_WARN(m4_case(m4_normalize([$1]), - [serial], [ -Unable to locate serial HDF5 compilation helper script 'h5cc'. -Please specify --with-hdf5=<LOCATION> as the full path to h5cc. -HDF5 support is being disabled (equivalent to --with-hdf5=no). -], [parallel],[ -Unable to locate parallel HDF5 compilation helper script 'h5pcc'. -Please specify --with-hdf5=<LOCATION> as the full path to h5pcc. -HDF5 support is being disabled (equivalent to --with-hdf5=no). -], [ -Unable to locate HDF5 compilation helper scripts 'h5cc' or 'h5pcc'. -Please specify --with-hdf5=<LOCATION> as the full path to h5cc or h5pcc. -HDF5 support is being disabled (equivalent to --with-hdf5=no). -])) - if test "$with_hdf5" = "yes"; then - AC_MSG_FAILURE([HDF5 was requested, but could not be compiled]) - fi - with_hdf5="no" - else - with_hdf5="yes" - fi - else - AC_MSG_CHECKING([for HDF5 libraries]) - dnl Get the h5cc output - HDF5_SHOW=$(eval $H5CC -show) - - dnl Get the actual compiler used - HDF5_CC=$(eval $H5CC -show | $AWK '{print $[]1}') - if test "$HDF5_CC" = "ccache"; then - HDF5_CC=$(eval $H5CC -show | $AWK '{print $[]2}') - fi - - dnl h5cc provides both AM_ and non-AM_ options - dnl depending on how it was compiled either one of - dnl these are empty. Lets roll them both into one. - - dnl Look for "HDF5 Version: X.Y.Z" - HDF5_VERSION=$(eval $H5CC -showconfig | $GREP 'HDF5 Version:' \ - | $AWK '{print $[]3}') - - dnl A ideal situation would be where everything we needed was - dnl in the AM_* variables. However most systems are not like this - dnl and seem to have the values in the non-AM variables. - dnl - dnl We try the following to find the flags: - dnl (1) Look for "NAME:" tags - dnl (2) Look for "H5_NAME:" tags - dnl (3) Look for "AM_NAME:" tags - dnl - HDF5_tmp_flags=$(eval $H5CC -showconfig \ - | $GREP 'FLAGS\|Extra libraries:' \ - | $AWK -F: '{printf("%s "), $[]2}' ) - - dnl Find the installation directory and append include/ - HDF5_tmp_inst=$(eval $H5CC -showconfig \ - | $GREP 'Installation point:' \ - | $AWK '{print $[]NF}' ) - - dnl Add this to the CPPFLAGS - HDF5_CPPFLAGS="-I${HDF5_tmp_inst}/include" - - dnl Now sort the flags out based upon their prefixes - for arg in $HDF5_SHOW $HDF5_tmp_flags ; do - case "$arg" in - -I*) echo $HDF5_CPPFLAGS | $GREP -e "$arg" 2>&1 >/dev/null \ - || HDF5_CPPFLAGS="$HDF5_CPPFLAGS $arg" - ;; - -L*) echo $HDF5_LDFLAGS | $GREP -e "$arg" 2>&1 >/dev/null \ - || HDF5_LDFLAGS="$HDF5_LDFLAGS $arg" - ;; - -l*) echo $HDF5_LIBS | $GREP -e "$arg" 2>&1 >/dev/null \ - || HDF5_LIBS="$HDF5_LIBS $arg" - ;; - esac - done - - HDF5_LIBS="-lhdf5 $HDF5_LIBS" - AC_MSG_RESULT([yes (version $[HDF5_VERSION])]) - - dnl See if we can compile - AC_LANG_PUSH([C]) - ax_lib_hdf5_save_CC=$CC - ax_lib_hdf5_save_CPPFLAGS=$CPPFLAGS - ax_lib_hdf5_save_LIBS=$LIBS - ax_lib_hdf5_save_LDFLAGS=$LDFLAGS - CC=$HDF5_CC - CPPFLAGS=$HDF5_CPPFLAGS - LIBS=$HDF5_LIBS - LDFLAGS=$HDF5_LDFLAGS - AC_CHECK_HEADER([hdf5.h], [ac_cv_hdf5_h=yes], [ac_cv_hdf5_h=no]) - AC_CHECK_LIB([hdf5], [H5Fcreate], [ac_cv_libhdf5=yes], - [ac_cv_libhdf5=no]) - if test "$ac_cv_hdf5_h" = "no" && test "$ac_cv_libhdf5" = "no" ; then - if test "$with_hdf5" = "yes"; then - AC_MSG_FAILURE([Unable to compile HDF5 test program]) - else - AC_MSG_WARN([Unable to compile HDF5 test program]) - fi - fi - with_hdf5=yes - dnl Look for HDF5's high level library - AC_HAVE_LIBRARY([hdf5_hl], [HDF5_LIBS="-lhdf5_hl $HDF5_LIBS"], [], []) - - CC=$ax_lib_hdf5_save_CC - CPPFLAGS=$ax_lib_hdf5_save_CPPFLAGS - LIBS=$ax_lib_hdf5_save_LIBS - LDFLAGS=$ax_lib_hdf5_save_LDFLAGS - AC_LANG_POP([C]) - - AC_SUBST([HDF5_VERSION]) - AC_SUBST([HDF5_CC]) - AC_SUBST([HDF5_CFLAGS]) - AC_SUBST([HDF5_CPPFLAGS]) - AC_SUBST([HDF5_LDFLAGS]) - AC_SUBST([HDF5_LIBS]) - AC_SUBST([HDF5_TYPE]) - AC_DEFINE([HAVE_HDF5], [1], [Defined if you have HDF5 support]) - fi -fi -]) diff --git a/m4/ax_lib_parallelhdf5.m4 b/m4/ax_lib_parallelhdf5.m4 deleted file mode 100644 index 28d4c952a6..0000000000 --- a/m4/ax_lib_parallelhdf5.m4 +++ /dev/null @@ -1,273 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_lib_hdf5.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_LIB_HDF5([serial/parallel]) -# -# DESCRIPTION -# -# This macro provides tests of the availability of HDF5 library. -# -# The optional macro argument should be either 'serial' or 'parallel'. The -# former only looks for serial HDF5 installations via h5cc. The latter -# only looks for parallel HDF5 installations via h5pcc. If the optional -# argument is omitted, serial installations will be preferred over -# parallel ones. -# -# The macro adds a --with-hdf5 option accepting one of three values: -# -# no - do not check for the HDF5 library. -# yes - do check for HDF5 library in standard locations. -# path - complete path to the HDF5 helper script h5cc or h5pcc. -# -# If HDF5 is successfully found, this macro calls -# -# AC_SUBST(HDF5_VERSION) -# AC_SUBST(HDF5_CC) -# AC_SUBST(HDF5_CFLAGS) -# AC_SUBST(HDF5_CPPFLAGS) -# AC_SUBST(HDF5_LDFLAGS) -# AC_SUBST(HDF5_LIBS) -# AC_SUBST(HDF5_FC) -# AC_SUBST(HDF5_FFLAGS) -# AC_SUBST(HDF5_FLIBS) -# AC_SUBST(HDF5_TYPE) -# AC_DEFINE(HAVE_HDF5) -# -# and sets with_hdf5="yes". Additionally, the macro sets -# with_hdf5_fortran="yes" if a matching Fortran wrapper script is found. -# Note that Autconf's Fortran support is not used to perform this check. -# H5CC and H5FC will contain the appropriate serial or parallel HDF5 -# wrapper script locations. -# -# If HDF5 is disabled or not found, this macros sets with_hdf5="no" and -# with_hdf5_fortran="no". -# -# Your configuration script can test $with_hdf to take any further -# actions. HDF5_{C,CPP,LD}FLAGS may be used when building with C or C++. -# HDF5_F{FLAGS,LIBS} should be used when building Fortran applications. -# -# To use the macro, one would code one of the following in "configure.ac" -# before AC_OUTPUT: -# -# 1) dnl Check for HDF5 support -# AX_LIB_HDF5() -# -# 2) dnl Check for serial HDF5 support -# AX_LIB_HDF5([serial]) -# -# 3) dnl Check for parallel HDF5 support -# AX_LIB_HDF5([parallel]) -# -# One could test $with_hdf5 for the outcome or display it as follows -# -# echo "HDF5 support: $with_hdf5" -# -# You could also for example, override the default CC in "configure.ac" to -# enforce compilation with the compiler that HDF5 uses: -# -# AX_LIB_HDF5([parallel]) -# if test "$with_hdf5" = "yes"; then -# CC="$HDF5_CC" -# else -# AC_MSG_ERROR([Unable to find HDF5, we need parallel HDF5.]) -# fi -# -# The HDF5_TYPE environment variable returns "parallel" or "serial", -# depending on which type of library is found. -# -# LICENSE -# -# Copyright (c) 2009 Timothy Brown <tbrown@freeshell.org> -# Copyright (c) 2010 Rhys Ulerich <rhys.ulerich@gmail.com> -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 15 - -AC_DEFUN([AX_LIB_PARALLELHDF5], [ - -AC_REQUIRE([AC_PROG_SED]) -AC_REQUIRE([AC_PROG_AWK]) -AC_REQUIRE([AC_PROG_GREP]) - -dnl Add a default --with-parallelhdf5 configuration option. -AC_ARG_WITH([parallelhdf5], - AS_HELP_STRING( - [--with-parallelhdf5=[yes/no/PATH]], - [location of h5pcc for parallel HDF5 configuration] - ), - [if test "$withval" = "no"; then - with_parallelhdf5="no" - elif test "$withval" = "yes"; then - with_parallelhdf5="yes" - else - with_parallelhdf5="yes" - PARALLELH5CC="$withval" - fi], - [with_parallelhdf5="no"] -) - -dnl Set defaults to blank -PARALLELHDF5_CC="" -PARALLELHDF5_VERSION="" -PARALLELHDF5_CFLAGS="" -PARALLELHDF5_CPPFLAGS="" -PARALLELHDF5_LDFLAGS="" -PARALLELHDF5_LIBS="" -PARALLELHDF5_FC="" -PARALLELHDF5_FFLAGS="" -PARALLELHDF5_FLIBS="" -PARALLELHDF5_TYPE="" - -dnl Try and find hdf5 compiler tools and options. -if test "$with_parallelhdf5" = "yes"; then - if test -z "$PARALLELH5CC"; then - dnl Check to see if H5CC is in the path. - AC_PATH_PROGS( - [PARALLELH5CC], [h5pcc] - []) - else - AC_MSG_CHECKING([Using provided HDF5 C wrapper]) - AC_MSG_RESULT([$PARALLELH5CC]) - fi - AC_MSG_CHECKING([for HDF5 type]) - AS_CASE([$PARALLELH5CC], - [*h5pcc], [PARALLELHDF5_TYPE=parallel], - [*h5cc], [PARALLELHDF5_TYPE=serial], - [PARALLELHDF5_TYPE=neither]) - AC_MSG_RESULT([$PARALLELHDF5_TYPE]) - - if test ! -f "$PARALLELH5CC" || test ! -x "$PARALLELH5CC"; then - - AC_MSG_CHECKING([if we can compile parallel HDF5 program without helper script]) - AC_LANG_PUSH([C++]) - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([ - #include <hdf5.h> - ], [H5Fcreate(0, 0, 0, 0);])], - [ac_cv_parallelhdf5_h=yes - ac_cv_libparallelhdf5=yes], - [ac_cv_parallelhdf5_h=no - ac_cv_libparallelhdf5=no]) - AC_MSG_RESULT([$ac_cv_parallelhdf5_h]) - - if test "$ac_cv_parallelhdf5_h" = "yes"; then - AC_MSG_CHECKING([if found HDF5 is parallel]) - AC_EGREP_CPP([yes], [ - #include <H5pubconf.h> - #ifdef H5_HAVE_PARALLEL - yes - #endif - ], [ac_cv_parallelhdf5_h=yes], [ac_cv_parallelhdf5_h=no]) - AC_MSG_RESULT([$ac_cv_parallelhdf5_h]) - fi - AC_LANG_POP([C++]) - - if test "$ac_cv_parallelhdf5_h" = "no" ; then - AC_MSG_FAILURE([ -Unable to locate parallel HDF5 compilation helper script 'h5pcc'. -Please specify --with-parallelhdf5=<LOCATION> as the full path to h5pcc. -HDF5 support is being disabled (equivalent to --with-parallelhdf5=no). -]) - with_parallelhdf5="no" - fi - else - AC_MSG_CHECKING([for HDF5 libraries]) - dnl Get the h5cc output - PARALLELHDF5_SHOW=$(eval $PARALLELH5CC -show) - - dnl Get the actual compiler used - PARALLELHDF5_CC=$(eval $PARALLELH5CC -show | $AWK '{print $[]1}') - if test "$PARALLELHDF5_CC" = "ccache"; then - PARALLELHDF5_CC=$(eval $PARALLELH5CC -show | $AWK '{print $[]2}') - fi - - dnl h5cc provides both AM_ and non-AM_ options - dnl depending on how it was compiled either one of - dnl these are empty. Lets roll them both into one. - - dnl Look for "HDF5 Version: X.Y.Z" - PARALLELHDF5_VERSION=$(eval $PARALLELH5CC -showconfig | $GREP 'HDF5 Version:' \ - | $AWK '{print $[]3}') - - dnl A ideal situation would be where everything we needed was - dnl in the AM_* variables. However most systems are not like this - dnl and seem to have the values in the non-AM variables. - dnl - dnl We try the following to find the flags: - dnl (1) Look for "NAME:" tags - dnl (2) Look for "H5_NAME:" tags - dnl (3) Look for "AM_NAME:" tags - dnl - PARALLELHDF5_tmp_flags=$(eval $PARALLELH5CC -showconfig \ - | $GREP 'FLAGS\|Extra libraries:' \ - | $AWK -F: '{printf("%s "), $[]2}' ) - - dnl Find the installation directory and append include/ - PARALLELHDF5_tmp_inst=$(eval $PARALLELH5CC -showconfig \ - | $GREP 'Installation point:' \ - | $AWK '{print $[]NF}' ) - - dnl Add this to the CPPFLAGS - PARALLELHDF5_CPPFLAGS="-I${PARALLELHDF5_tmp_inst}/include" - - dnl Now sort the flags out based upon their prefixes - for arg in $PARALLELHDF5_SHOW $PARALLELHDF5_tmp_flags ; do - case "$arg" in - -I*) echo $PARALLELHDF5_CPPFLAGS | $GREP -e "$arg" 2>&1 >/dev/null \ - || PARALLELHDF5_CPPFLAGS="$PARALLELHDF5_CPPFLAGS $arg" - ;; - -L*) echo $PARALLELHDF5_LDFLAGS | $GREP -e "$arg" 2>&1 >/dev/null \ - || PARALLELHDF5_LDFLAGS="$PARALLELHDF5_LDFLAGS $arg" - ;; - -l*) echo $PARALLELHDF5_LIBS | $GREP -e "$arg" 2>&1 >/dev/null \ - || PARALLELHDF5_LIBS="$PARALLELHDF5_LIBS $arg" - ;; - esac - done - - PARALLELHDF5_LIBS="-lhdf5 $PARALLELHDF5_LIBS" - AC_MSG_RESULT([yes (version $[PARALLELHDF5_VERSION])]) - - dnl See if we can compile - AC_LANG_PUSH([C]) - ax_lib_parallelhdf5_save_CC=$CC - ax_lib_parallelhdf5_save_CPPFLAGS=$CPPFLAGS - ax_lib_parallelhdf5_save_LIBS=$LIBS - ax_lib_parallelhdf5_save_LDFLAGS=$LDFLAGS - CC=$PARALLELHDF5_CC - CPPFLAGS=$PARALLELHDF5_CPPFLAGS - LIBS=$PARALLELHDF5_LIBS - LDFLAGS=$PARALLELHDF5_LDFLAGS - AC_CHECK_HEADER([hdf5.h], [ac_cv_parallelhdf5_h=yes], [ac_cv_parallelhdf5_h=no]) - AC_CHECK_LIB([hdf5], [H5Fcreate], [ac_cv_libparallelhdf5=yes], - [ac_cv_libparallelhdf5=no]) - if test "$ac_cv_parallelhdf5_h" = "no" && test "$ac_cv_libparallelhdf5" = "no" ; then - AC_MSG_FAILURE([Unable to compile HDF5 test program]) - fi - dnl Look for HDF5's high level library - AC_HAVE_LIBRARY([hdf5_hl], [PARALLELHDF5_LIBS="-lhdf5_hl $PARALLELHDF5_LIBS"], [], []) - - CC=$ax_lib_parallelhdf5_save_CC - CPPFLAGS=$ax_lib_parallelhdf5_save_CPPFLAGS - LIBS=$ax_lib_parallelhdf5_save_LIBS - LDFLAGS=$ax_lib_parallelhdf5_save_LDFLAGS - AC_LANG_POP([C]) - - AC_SUBST([PARALLELHDF5_VERSION]) - AC_SUBST([PARALLELHDF5_CC]) - AC_SUBST([PARALLELHDF5_CFLAGS]) - AC_SUBST([PARALLELHDF5_CPPFLAGS]) - AC_SUBST([PARALLELHDF5_LDFLAGS]) - AC_SUBST([PARALLELHDF5_LIBS]) - AC_SUBST([PARALLELHDF5_TYPE]) - AC_DEFINE([HAVE_PARALLELHDF5], [1], [Defined if you have parallel HDF5 support]) - fi -fi -]) diff --git a/manual/doxygen/Doxyfile b/manual/doxygen/Doxyfile index 6442efc567..9a00766741 100644 --- a/manual/doxygen/Doxyfile +++ b/manual/doxygen/Doxyfile @@ -2061,7 +2061,6 @@ PREDEFINED = BACKTRACE \ CHECK=3 \ DEPRECATED(func)=func \ HAS_PRETTY_FUNCTION \ - HDF5 \ LAPACK \ LOGCOLOR \ NCDF \ @@ -2069,7 +2068,6 @@ PREDEFINED = BACKTRACE \ PETSC_HAS_SUNDIALS \ PETSC_RELEASE \ PETSC_VERSION=3.8 \ - PHDF5 \ PNCDF \ SIGHANDLE \ TRACK \ diff --git a/manual/doxygen/Doxyfile_readthedocs b/manual/doxygen/Doxyfile_readthedocs index d2d00e0997..a0f8a669af 100644 --- a/manual/doxygen/Doxyfile_readthedocs +++ b/manual/doxygen/Doxyfile_readthedocs @@ -1021,7 +1021,6 @@ PREDEFINED = BACKTRACE \ CHECK=3 \ DEPRECATED(func)=func \ HAS_PRETTY_FUNCTION \ - HDF5 \ LAPACK \ LOGCOLOR \ NCDF \ @@ -1029,7 +1028,6 @@ PREDEFINED = BACKTRACE \ PETSC_HAS_SUNDIALS \ PETSC_RELEASE \ PETSC_VERSION=3.8 \ - PHDF5 \ PNCDF \ SIGHANDLE \ TRACK \ diff --git a/manual/sphinx/developer_docs/code_layout.rst b/manual/sphinx/developer_docs/code_layout.rst index b796f8a069..741e71e44b 100644 --- a/manual/sphinx/developer_docs/code_layout.rst +++ b/manual/sphinx/developer_docs/code_layout.rst @@ -150,13 +150,6 @@ The current source code files are: - :doc:`emptyformat.hxx<../_breathe_autogen/file/emptyformat_8hxx>` - - hdf5 - - - :doc:`h5_format.cxx<../_breathe_autogen/file/h5__format_8cxx>` implements an - interface to the HDF5 library - - - :doc:`h5_format.hxx<../_breathe_autogen/file/h5__format_8hxx>` - - netcdf - :doc:`nc_format.cxx<../_breathe_autogen/file/nc__format_8cxx>` implements an diff --git a/manual/sphinx/developer_docs/file_io.rst b/manual/sphinx/developer_docs/file_io.rst index d5cc038a76..9910baed05 100644 --- a/manual/sphinx/developer_docs/file_io.rst +++ b/manual/sphinx/developer_docs/file_io.rst @@ -10,12 +10,12 @@ and the `Datafile` class :doc:`datafile.cxx<../_breathe_autogen/file/datafile_8cxx>`). All other parts which need to read or write data go through these methods. -Several different file formats are commonly used, such as HDF, HDF5, -and netCDF. For historical reasons (inherited from BOUT), BOUT++ -originally used the Portable Data Binary (PDB) format developed at -LLNL [1]_. To separate the basic file format functions from the higher -level grid and Datafile classes, these use an abstract class -`DataFormat`. Any class which implements the functions listed in +netCDF is used for binary I/O. For historical reasons (inherited from +BOUT), BOUT++ originally used the Portable Data Binary (PDB) format +developed at LLNL [1]_. HDF5 was also previously supported. To +separate the basic file format functions from the higher level grid +and Datafile classes, these use an abstract class `DataFormat`. Any +class which implements the functions listed in :doc:`dataformat.hxx<../_breathe_autogen/file/dataformat_8hxx>` can therefore be passed to grid or datafile. This makes implementing a new file format, and switching between formats at run-time, relatively diff --git a/manual/sphinx/user_docs/advanced_install.rst b/manual/sphinx/user_docs/advanced_install.rst index d39aa9658a..d4ec77cb33 100644 --- a/manual/sphinx/user_docs/advanced_install.rst +++ b/manual/sphinx/user_docs/advanced_install.rst @@ -254,11 +254,11 @@ Finally example configurations for BOUT++, where you should replace <...> by app * for an optimized build (some experimentation with optimisation flags would be welcome, please share the results if you do!):: - ./configure --enable-optimize=3 --enable-checks=no --without-hdf5 --enable-static --with-netcdf=<...> --with-sundials=<...> --with-fftw=<...> --with-petsc=<...> + ./configure --enable-optimize=3 --enable-checks=no --enable-static --with-netcdf=<...> --with-sundials=<...> --with-fftw=<...> --with-petsc=<...> * for a debugging build:: - ./configure --enable-debug --without-hdf5 --enable-static --with-netcdf=<...> --with-sundials=<...> --with-fftw=<...> --with-petsc=<...> + ./configure --enable-debug --enable-static --with-netcdf=<...> --with-sundials=<...> --with-fftw=<...> --with-petsc=<...> Ubgl ~~~~ @@ -271,21 +271,16 @@ Ubgl File formats ------------ -BOUT++ can currently use two different file formats: NetCDF-4_, and -HDF5_ and experimental support for parallel flavours of both. NetCDF -is a widely used format and so has many more tools for viewing and -manipulating files. HDF5 is another widely used format. If you have -multiple libraries installed then BOUT++ can use them simultaneously, -for example reading in grid files in NetCDF format, but writing output -data in HDF5 format. +BOUT++ can currently use the NetCDF-4_ file format, with experimental +support for the parallel flavour. NetCDF is a widely used format and +has many tools for viewing and manipulating files. .. _NetCDF-4: https://www.unidata.ucar.edu/software/netcdf/ -.. _HDF5: https://www.hdfgroup.org/HDF5/ -BOUT++ will try to use NetCDF by default. It will look for -``ncxx4-config`` or ``nc-config`` in your ``$PATH``. If it cannot find -the libraries, or finds a different version than the one you want, you -can point it at the correct version using:: +BOUT++ will look for ``ncxx4-config`` or ``nc-config`` in your +``$PATH``. If it cannot find the libraries, or finds a different +version than the one you want, you can point it at the correct version +using:: ./configure --with-netcdf=/path/to/ncxx4-config @@ -293,16 +288,6 @@ where ``/path/to/ncxx4-config`` is the location of the ``ncxx4-config`` tool (``nc-config`` will also work, but ``ncxx4-config`` is preferred). -To use HDF5, you will need to explicitly enable it:: - - ./configure --with-hdf5 - -BOUT++ will look for ``h5cc`` in your ``$PATH``. Similar to NetCDF, -you can pass the location of the particular version you wish to use -with:: - - ./configure --with-hdf5=/path/to/h5cc - .. _sec-netcdf-from-source: diff --git a/manual/sphinx/user_docs/bout_options.rst b/manual/sphinx/user_docs/bout_options.rst index 4758163ac1..201aa09798 100644 --- a/manual/sphinx/user_docs/bout_options.rst +++ b/manual/sphinx/user_docs/bout_options.rst @@ -4,7 +4,7 @@ BOUT++ options ============== The inputs to BOUT++ are a text file containing options, command-line options, -and for complex grids a binary grid file in NetCDF or HDF5 format. Generating input +and for complex grids a binary grid file in NetCDF format. Generating input grids for tokamaks is described in :ref:`sec-gridgen`. The grid file describes the size and topology of the X-Y domain, metric tensor components and usually some initial profiles. The option file specifies @@ -437,20 +437,10 @@ may be useful anyway. See :ref:`sec-output` for more details. Input and Output ---------------- -The format of the output (dump) files can be controlled, if support for -more than one output format has been configured, by setting the -top-level option **dump\_format** to one of the recognised file -extensions: ‘nc’ for NetCDF; ‘hdf5’, ‘hdf’ or ‘h5’ for HDF5. For example -to select HDF5 instead of the default NetCDF format put - -.. code-block:: cfg - - dump_format = hdf5 - -before any section headers. The output (dump) files with time-history -are controlled by settings in a section called “output”. Restart files -contain a single time-slice, and are controlled by a section called -“restart”. The options available are listed in table :numref:`tab-outputopts`. +The output (dump) files with time-history are controlled by settings +in a section called “output”. Restart files contain a single +time-slice, and are controlled by a section called “restart”. The +options available are listed in table :numref:`tab-outputopts`. .. _tab-outputopts: .. table:: Output file options diff --git a/manual/sphinx/user_docs/input_grids.rst b/manual/sphinx/user_docs/input_grids.rst index 7c19db8eec..c214887c7d 100644 --- a/manual/sphinx/user_docs/input_grids.rst +++ b/manual/sphinx/user_docs/input_grids.rst @@ -100,9 +100,9 @@ e.g. “``section:variable``”. More complex meshes can be created by supplying an input grid file to describe the grid points, geometry, and starting profiles. Currently -BOUT++ supports NetCDF and HDF5 format binary files. During startup, -BOUT++ looks in the grid file for the following variables. If any are -not found, a warning will be printed and the default values used. +BOUT++ supports NetCDF format binary files. During startup, BOUT++ +looks in the grid file for the following variables. If any are not +found, a warning will be printed and the default values used. - X and Y grid sizes (integers) ``nx`` and ``ny`` **REQUIRED** diff --git a/manual/sphinx/user_docs/installing.rst b/manual/sphinx/user_docs/installing.rst index 8f95d79831..5b8ea28d01 100644 --- a/manual/sphinx/user_docs/installing.rst +++ b/manual/sphinx/user_docs/installing.rst @@ -71,10 +71,10 @@ then run:: This should give a terminal in a "boutuser" home directory, in which there is "BOUT-next", containing BOUT++ configured and compiled with -NetCDF, HDF5, SUNDIALS, PETSc and SLEPc. Python 3 is also installed, -with ipython, NumPy, Scipy and Matplotlib libaries. To plot to screen -an X11 display is needed. Alternatively a shared directory can be -created to pass files between the docker image and host. The following +NetCDF, SUNDIALS, PETSc and SLEPc. Python 3 is also installed, with +ipython, NumPy, Scipy and Matplotlib libaries. To plot to screen an +X11 display is needed. Alternatively a shared directory can be created +to pass files between the docker image and host. The following commands both enable X11 and create a shared directory:: $ mkdir shared @@ -253,8 +253,7 @@ directory with the ``–with-fftw=`` option e.g:: Configure should now find FFTW, and search for the NetCDF library. If configure finishes successfully, then skip to the next section, but if you see a message ``NetCDF support disabled`` then configure couldn’t -find the NetCDF library. Unless you have another file format (like HDF5) installed, this -will be followed by a message +find the NetCDF library. This will be followed by a message ``ERROR: At least one file format must be supported``. Check that you have NetCDF installed (See the previous section on :ref:`installing dependencies <sec-dependencies>` ). @@ -274,7 +273,6 @@ configuration:: ARKODE support: yes NetCDF support: yes Parallel-NetCDF support: no - HDF5 support: yes (parallel: no) If not, see :ref:`sec-advancedinstall` for some things you can try to resolve common problems. diff --git a/manual/sphinx/user_docs/output_and_post.rst b/manual/sphinx/user_docs/output_and_post.rst index 8f1182b63d..bcc6b94240 100644 --- a/manual/sphinx/user_docs/output_and_post.rst +++ b/manual/sphinx/user_docs/output_and_post.rst @@ -183,9 +183,8 @@ There are several modules available for reading NetCDF files, so to provide a consistent interface, file access is wrapped into a class DataFile. This provides a simple interface for reading and writing files from any of the following modules: ``netCDF4``; -``Scientific.IO.NetCDF``; and ``scipy.io.netcdf``. The DataFile class -also provides allows access to HDF5 files through the same interface, -using the ``h5py`` module. To open a file using DataFile: +``Scientific.IO.NetCDF``; and ``scipy.io.netcdf``. To open a file +using DataFile: .. code-block:: python @@ -195,16 +194,6 @@ using the ``h5py`` module. To open a file using DataFile: var = f.read("variable") # Read a variable from the file f.close() # Close the file -or similarly for an HDF5 file - -.. code-block:: python - - from boututils.datafile import DataFile - - f = DataFile("file.hdf5") # Open the file - var = f.read("variable") # Read a variable from the file - f.close() # Close the file - A more robust way to read from DataFiles is to use the context manager syntax: @@ -212,7 +201,7 @@ syntax: from boututils.datafile import DataFile - with DataFile("file.hdf5") as f: # Open the file + with DataFile("file.nc") as f: # Open the file var = f.read("variable") # Read a variable from the file This way the DataFile is automatically closed at the end of the ``with`` @@ -403,8 +392,7 @@ several optional keywords with ``[min,max]`` ranges: Summary of IDL file routines ---------------------------- -Functions file\_ can currently only read/write NetCDF files. HDF5 is not -supported yet. +Functions file\_ can currently only read/write NetCDF files. Open a NetCDF file: diff --git a/manual/sphinx/user_docs/physics_models.rst b/manual/sphinx/user_docs/physics_models.rst index 93249a4350..19ba2724bf 100644 --- a/manual/sphinx/user_docs/physics_models.rst +++ b/manual/sphinx/user_docs/physics_models.rst @@ -869,9 +869,7 @@ in ``init``, you then: name; actual opening of the file happens later when the data is written. If you are not using parallel I/O, the processor number is also inserted into the file name before the last “.”, so mydata.nc” - becomes “mydata.0.nc”, “mydata.1.nc” etc. The file format used - depends on the extension, so “.nc” will open NetCDF, and “.hdf5” or - “.h5” an HDF5 file. + becomes “mydata.0.nc”, “mydata.1.nc” etc. (see e.g. src/fileio/datafile.cxx line 139, which calls src/fileio/dataformat.cxx line 23, which then calls the file format diff --git a/manual/sphinx/user_docs/python.rst b/manual/sphinx/user_docs/python.rst index 7141d76861..0a0eac3a7a 100644 --- a/manual/sphinx/user_docs/python.rst +++ b/manual/sphinx/user_docs/python.rst @@ -7,9 +7,8 @@ boututils --------- - ``class Datafile`` provides a convenient way to read and write NetCDF - or HDF5 files. There are many different NetCDF libraries available - for Python, so this class tries to provide a consistent interface to - many of them, as well as to h5py. + files. There are many different NetCDF libraries available for Python, so + this class tries to provide a consistent interface to many of them. - ``deriv()`` diff --git a/manual/sphinx/user_docs/running_bout.rst b/manual/sphinx/user_docs/running_bout.rst index 6493817c75..d681f70e01 100644 --- a/manual/sphinx/user_docs/running_bout.rst +++ b/manual/sphinx/user_docs/running_bout.rst @@ -144,7 +144,7 @@ some requirements such as SciPy; see section :ref:`sec-python-requirements` for details. To print a list of variables in the output files, one way is to use the ``DataFile`` -class. This is a wrapper around the various NetCDF and HDF5 libraries for python: +class. This is a wrapper around the various NetCDF libraries for python: .. code-block:: pycon diff --git a/manual/sphinx/user_docs/testing.rst b/manual/sphinx/user_docs/testing.rst index 954e59e4c4..9189223a10 100644 --- a/manual/sphinx/user_docs/testing.rst +++ b/manual/sphinx/user_docs/testing.rst @@ -109,11 +109,11 @@ specify #requires petsc Currently the requirements which can be combined are ``travis``, -``netcdf``, ``pnetcdf``, ``hdf5``, ``pvode``, ``cvode``, -``ida``, ``lapack``, ``petsc``, ``slepc``, ``arkode``, -``openmp`` and ``make``. The ``make`` requirement is set to True when -the tests are being compiled (but not run), and False when the scripts -are run. It's used for tests which do not have a compilation stage. +``netcdf``, ``pnetcdf``, ``pvode``, ``cvode``, ``ida``, ``lapack``, +``petsc``, ``slepc``, ``arkode``, ``openmp`` and ``make``. The +``make`` requirement is set to True when the tests are being compiled +(but not run), and False when the scripts are run. It's used for tests +which do not have a compilation stage. .. _sec-mms: diff --git a/src/bout++.cxx b/src/bout++.cxx index a35433c73a..27915938ae 100644 --- a/src/bout++.cxx +++ b/src/bout++.cxx @@ -486,7 +486,6 @@ void printCompileTimeOptions() { output_info.write(_("\tFFT support {}\n"), is_enabled(has_fftw)); output_info.write(_("\tNatural language support {}\n"), is_enabled(has_gettext)); - output_info.write(_("\tHDF5 support {}\n"), is_enabled(has_hdf5)); output_info.write(_("\tLAPACK support {}\n"), is_enabled(has_lapack)); // Horrible nested ternary to set this at compile time constexpr auto netcdf_flavour = @@ -642,7 +641,6 @@ Datafile setupDumpFile(Options& options, Mesh& mesh, const std::string& data_dir // Add compile-time options dump_file.addOnce(const_cast<bool&>(bout::build::has_fftw), "has_fftw"); dump_file.addOnce(const_cast<bool&>(bout::build::has_gettext), "has_gettext"); - dump_file.addOnce(const_cast<bool&>(bout::build::has_hdf5), "has_hdf5"); dump_file.addOnce(const_cast<bool&>(bout::build::has_lapack), "has_lapack"); dump_file.addOnce(const_cast<bool&>(bout::build::has_netcdf), "has_netcdf"); dump_file.addOnce(const_cast<bool&>(bout::build::has_legacy_netcdf), diff --git a/src/fileio/formatfactory.cxx b/src/fileio/formatfactory.cxx index 0586bfb1b1..03ecc2eadc 100644 --- a/src/fileio/formatfactory.cxx +++ b/src/fileio/formatfactory.cxx @@ -8,7 +8,6 @@ #include "impls/netcdf4/ncxx4.hxx" #include "impls/netcdf/nc_format.hxx" -#include "impls/hdf5/h5_format.hxx" #include "impls/pnetcdf/pnetcdf.hxx" #include <boutexception.hxx> @@ -48,13 +47,8 @@ std::unique_ptr<DataFormat> FormatFactory::createDataFormat(const char *filename return bout::utils::make_unique<NcFormat>(mesh_in); #else -#if BOUT_HAS_HDF5 - return bout::utils::make_unique<H5Format>(mesh_in); -#else - #error No file format available; aborting. -#endif // BOUT_HAS_HDF5 #endif // BOUT_HAS_LEGACY_NETCDF #endif // BOUT_HAS_NETCDF #endif // PNCDF @@ -96,18 +90,6 @@ std::unique_ptr<DataFormat> FormatFactory::createDataFormat(const char *filename } #endif -#if BOUT_HAS_HDF5 - const char *hdf5_match[] = {"h5","hdf","hdf5"}; - if(matchString(s, 3, hdf5_match) != -1) { - output.write("\tUsing HDF5 format for file '{:s}'\n", filename); -#ifdef PHDF5 - return bout::utils::make_unique<H5Format>(parallel); -#else - return bout::utils::make_unique<H5Format>(); -#endif - } -#endif - throw BoutException("\tFile extension not recognised for '{:s}'\n", filename); return nullptr; } diff --git a/src/fileio/impls/hdf5/h5_format.cxx b/src/fileio/impls/hdf5/h5_format.cxx deleted file mode 100644 index 002b83bf62..0000000000 --- a/src/fileio/impls/hdf5/h5_format.cxx +++ /dev/null @@ -1,1475 +0,0 @@ -/************************************************************************** - * Copyright 2015 J.T.Omotani, B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu - * - * Contact: Ben Dudson, bd512@york.ac.uk - * - * This file is part of BOUT++. - * - * BOUT++ is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * BOUT++ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with BOUT++. If not, see <http://www.gnu.org/licenses/>. - * - **************************************************************************/ - -#include "bout/build_config.hxx" - -#include <globals.hxx> -#include "h5_format.hxx" - -#if BOUT_HAS_HDF5 - -#include <utils.hxx> -#include <cmath> -#include <string> -#include <mpi.h> - -#include <bout/mesh.hxx> -#include <output.hxx> -#include <msg_stack.hxx> -#include <boutcomm.hxx> - -H5Format::H5Format(bool parallel_in, Mesh* mesh_in) : DataFormat(mesh_in) { - parallel = parallel_in; - x0 = y0 = z0 = t0 = 0; - lowPrecision = false; - fname = nullptr; - dataFile = -1; - chunk_length = 10; // could change this to try to optimize IO performance (i.e. allocate new chunks of disk space less often) - - dataFile_plist = H5Pcreate(H5P_FILE_ACCESS); - if (dataFile_plist < 0) - throw BoutException("Failed to create dataFile_plist"); - -#ifdef PHDF5 - if (parallel) - if (H5Pset_fapl_mpio(dataFile_plist, BoutComm::get(), MPI_INFO_NULL) < 0) - throw BoutException("Failed to set dataFile_plist"); -#endif - - dataSet_plist = H5Pcreate(H5P_DATASET_XFER); - if (dataSet_plist < 0) - throw BoutException("Failed to create dataSet_plist"); - -#ifdef PHDF5 - if (parallel) - if (H5Pset_dxpl_mpio(dataSet_plist, H5FD_MPIO_INDEPENDENT) < 0) // Default, independent writes -// if (H5Pset_dxpl_mpio(dataSet_plist, H5FD_MPIO_COLLECTIVE) < 0) // Alternative, collective writes - throw BoutException("Failed to set dataSet_plist"); -#endif - - // Disable automatic printing of error messages so that we can catch - // errors without printing error messages to stdout - if (H5Eset_auto(H5E_DEFAULT, nullptr, nullptr) < 0) - throw BoutException("Failed to set error stack to not print errors"); -} - -H5Format::H5Format(const char *name, bool parallel_in, Mesh* mesh_in) - : DataFormat(mesh_in) { - parallel = parallel_in; - x0 = y0 = z0 = t0 = 0; - lowPrecision = false; - fname = nullptr; - dataFile = -1; - chunk_length = 10; // could change this to try to optimize IO performance (i.e. allocate new chunks of disk space less often) - - dataFile_plist = H5Pcreate(H5P_FILE_ACCESS); - if (dataFile_plist < 0) - throw BoutException("Failed to create dataFile_plist"); - -#ifdef PHDF5 - if (parallel) - if (H5Pset_fapl_mpio(dataFile_plist, BoutComm::get(), MPI_INFO_NULL) < 0) - throw BoutException("Failed to set dataFile_plist"); -#endif - - dataSet_plist = H5Pcreate(H5P_DATASET_XFER); - if (dataSet_plist < 0) - throw BoutException("Failed to create dataSet_plist"); - -#ifdef PHDF5 - if (parallel) - if (H5Pset_dxpl_mpio(dataSet_plist, H5FD_MPIO_COLLECTIVE) < 0) - throw BoutException("Failed to set dataSet_plist"); -#endif - - // Disable automatic printing of error messages so that we can catch - // errors without printing error messages to stdout - if (H5Eset_auto(H5E_DEFAULT, nullptr, nullptr) < 0) - throw BoutException("Failed to set error stack to not print errors"); - - H5Format::openr(name); -} - -H5Format::~H5Format() { - H5Format::close(); - H5Pclose(dataFile_plist); -} - -bool H5Format::openr(const char *name) { - TRACE("H5Format::openr"); - - if(dataFile > 0) // Already open. Close then re-open - close(); - - dataFile = H5Fopen(name, H5F_ACC_RDONLY, dataFile_plist); - if( dataFile < 0 ) { - throw BoutException("Failed to open dataFile"); - } - - return true; -} - -bool H5Format::openw(const char *name, bool append) { - TRACE("H5Format::openw"); - - if(dataFile > 0) // Already open. Close then re-open - close(); - - if(append) { - dataFile = H5Fopen(name, H5F_ACC_RDWR, dataFile_plist); - } - else { - dataFile = H5Fcreate(name, H5F_ACC_TRUNC, H5P_DEFAULT, dataFile_plist); - } - if( dataFile < 0 ) { - throw BoutException("Failed to open dataFile"); - } - - fname = copy_string(name); - - return true; -} - -bool H5Format::is_valid() { return dataFile >= 0; } - -void H5Format::close() { - TRACE("H5Format::close"); - - if (H5Format::is_valid()) { - H5Fclose(dataFile); - dataFile = -1; - } -} - -void H5Format::flush() { - if(!is_valid()) - return; - - if (H5Fflush(dataFile,H5F_SCOPE_LOCAL) < 0) { - throw BoutException("Failed to flush dataFile"); - } -} - -const std::vector<int> H5Format::getSize(const char *name) { - TRACE("H5Format::getSize"); - - std::vector<int> size; - - if(!is_valid()) - return size; - - hid_t dataSet = H5Dopen(dataFile, name, H5P_DEFAULT); - if (dataSet < 0) { - // variable does not exist in file, so return empty size - return size; - } - - hid_t dataSpace = H5Dget_space(dataSet); - if (dataSpace < 0) - throw BoutException("Failed to create dataSpace"); - - int nd = H5Sget_simple_extent_ndims(dataSpace); - if (nd < 0) - throw BoutException("Failed to get dataSpace ndims"); - - if (nd==0) { - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - size.push_back(1); - return size; - } else { - std::vector<hsize_t> dims(nd); - int error = H5Sget_simple_extent_dims(dataSpace, dims.data(), nullptr); - if (error < 0) - throw BoutException("Failed to get dimensions of dataSpace"); - - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - std::copy(begin(dims), end(dims), std::back_inserter(size)); - } - - return size; -} - -const std::vector<int> H5Format::getSize(const std::string &var) { - return getSize(var.c_str()); -} - -bool H5Format::setGlobalOrigin(int x, int y, int z) { - x0 = x; - y0 = y; - z0 = z; - x0_local = 0; - y0_local = 0; - z0_local = 0; - - return true; -} - -bool H5Format::setLocalOrigin(int x, int y, int z, int offset_x, int offset_y, int offset_z) { - - if(!setGlobalOrigin(x + mesh->OffsetX, y + mesh->OffsetY, z + mesh->OffsetZ)) - return false; - - x0_local = offset_x; - y0_local = offset_y; - z0_local = offset_z; - - return true; -} - -bool H5Format::setRecord(int t) { - t0 = t; - - return true; -} - -// Add a variable to the file -bool H5Format::addVar(const std::string &name, bool repeat, hid_t write_hdf5_type, - std::string datatype, int lx, int ly, int lz) { - hid_t dataSet = H5Dopen(dataFile, name.c_str(), H5P_DEFAULT); - if (dataSet >= 0) { // >=0 means variable already exists, so return. - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - return true; - } - - int nd = 0; - if (datatype == "scalar") { - nd = 0; - } else if (datatype == "vector" or datatype == "string" or datatype == "FieldX") { - nd = 1; - } else if (datatype == "Field2D" or datatype == "FieldPerp") { - nd = 2; - } else if (datatype == "Field3D") { - nd = 3; - } else { - throw BoutException("Unrecognized datatype '"+datatype+"'"); - } - - if (repeat) { - // add time dimension - datatype += "_t"; - nd += 1; - - hsize_t init_size[4]; - if (parallel) { - init_size[0]=0; - init_size[1] = lx == 0 ? mesh->GlobalNx-2*mesh->xstart : lx; - if (datatype == "FieldPerp_t") { - init_size[2] = lz == 0 ? mesh->GlobalNz : lz; - } else { - init_size[2] = ly == 0 ? mesh->GlobalNy - mesh->numberOfYBoundaries()*2*mesh->ystart : ly; - } - init_size[3] = lz == 0 ? mesh->GlobalNz : lz; - } - else { - init_size[0]=0; - init_size[1] = lx == 0 ? mesh->LocalNx : lx; - if (datatype == "FieldPerp_t") { - init_size[2] = lz == 0 ? mesh->LocalNz : lz; - } else { - init_size[2] = ly == 0 ? mesh->LocalNy : ly; - } - init_size[3] = lz == 0 ? mesh->LocalNz : lz; - } - - // Modify dataset creation properties, i.e. enable chunking. - hid_t propertyList = H5Pcreate(H5P_DATASET_CREATE); - if (propertyList < 0) - throw BoutException("Failed to create propertyList"); - hsize_t chunk_dims[4],max_dims[4]; - max_dims[0] = H5S_UNLIMITED; max_dims[1]=init_size[1]; max_dims[2]=init_size[2]; max_dims[3]=init_size[3]; - chunk_dims[0] = chunk_length; chunk_dims[1]=init_size[1]; chunk_dims[2]=init_size[2]; chunk_dims[3]=init_size[3]; - if (H5Pset_chunk(propertyList, nd, chunk_dims) < 0) - throw BoutException("Failed to set chunk property"); - - hid_t init_space = H5Screate_simple(nd, init_size, max_dims); - if (init_space < 0) - throw BoutException("Failed to create init_space"); - dataSet = H5Dcreate(dataFile, name.c_str(), write_hdf5_type, init_space, H5P_DEFAULT, propertyList, H5P_DEFAULT); - if (dataSet < 0) - throw BoutException("Failed to create dataSet"); - - // Add attribute to say what kind of field this is - - // Create new dataspace for attribute - hid_t attribute_dataspace = H5Screate(H5S_SCALAR); - if (attribute_dataspace < 0) - throw BoutException("Failed to create attribute_dataspace"); - - // Create new string datatype for attribute - hid_t variable_length_string_type = H5Tcopy(H5T_C_S1); - if (variable_length_string_type < 0) - throw BoutException("Failed to create variable_length_string_type"); - if (H5Tset_size(variable_length_string_type, H5T_VARIABLE) < 0) - throw BoutException("Failed to create string type"); - - // Create attribute and write to it - hid_t myatt_in = H5Acreate(dataSet, "bout_type", variable_length_string_type, attribute_dataspace, H5P_DEFAULT, H5P_DEFAULT); - if (myatt_in < 0) - throw BoutException("Failed to create attribute"); - if (H5Awrite(myatt_in, variable_length_string_type, &datatype) < 0) - throw BoutException("Failed to write attribute"); - - if (H5Pclose(propertyList) < 0) - throw BoutException("Failed to close propertyList"); - if (H5Sclose(init_space) < 0) - throw BoutException("Failed to close init_space"); - if (H5Sclose(attribute_dataspace) < 0) - throw BoutException("Failed to close attribute_dataspace"); - if (H5Tclose(variable_length_string_type) < 0) - throw BoutException("Failed to close variable_length_string_type"); - if (H5Aclose(myatt_in) < 0) - throw BoutException("Failed to close myatt_in"); - } else { - dataSet = H5Dopen(dataFile, name.c_str(), H5P_DEFAULT); - if (dataSet < 0) { - // Negative value indicates error, i.e. file does not exist, so create: - hsize_t init_size[3]; - if (parallel) { - init_size[0] = lx == 0 ? mesh->GlobalNx - 2 * mesh->xstart : lx; - if (datatype == "FieldPerp") { - init_size[1] = lz == 0 ? mesh->GlobalNz : lz; - } else { - init_size[1] = ly == 0 ? mesh->GlobalNy - mesh->numberOfYBoundaries() * 2 * mesh->ystart : ly; - } - init_size[2] = lz == 0 ? mesh->GlobalNz : lz; - } else { - init_size[0] = lx == 0 ? mesh->LocalNx : lx; - if (datatype == "FieldPerp") { - init_size[1] = lz == 0 ? mesh->LocalNz : lz; - } else { - init_size[1] = ly == 0 ? mesh->LocalNy : ly; - } - init_size[2] = lz == 0 ? mesh->LocalNz : lz; - } - - // Create value for attribute to say what kind of field this is - - if (nd==0) { - // Need to write a scalar, not a 0-d array - nd = 1; - init_size[0] = 1; - } - - hid_t init_space = H5Screate_simple(nd, init_size, init_size); - if (init_space < 0) - throw BoutException("Failed to create init_space"); - dataSet = H5Dcreate(dataFile, name.c_str(), write_hdf5_type, init_space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - if (dataSet < 0) - throw BoutException("Failed to create dataSet"); - - // Add attribute to say what kind of field this is - setAttribute(dataSet, "bout_type", datatype); - } - } - - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - return true; -} - -bool H5Format::addVarInt(const std::string &name, bool repeat) { - return addVar(name, repeat, H5T_NATIVE_INT, "scalar"); -} - -bool H5Format::addVarIntVec(const std::string &name, bool repeat, size_t size) { - return addVar(name, repeat, H5T_NATIVE_INT, "vector", size); -} - -bool H5Format::addVarString(const std::string &name, bool repeat, size_t size) { - return addVar(name, repeat, H5T_C_S1, "string", size); -} - -bool H5Format::addVarBoutReal(const std::string &name, bool repeat) { - auto h5_float_type = lowPrecision ? H5T_NATIVE_FLOAT : H5T_NATIVE_DOUBLE; - return addVar(name, repeat, h5_float_type, "scalar"); -} - -bool H5Format::addVarField2D(const std::string &name, bool repeat) { - auto h5_float_type = lowPrecision ? H5T_NATIVE_FLOAT : H5T_NATIVE_DOUBLE; - return addVar(name, repeat, h5_float_type, "Field2D"); -} - -bool H5Format::addVarField3D(const std::string &name, bool repeat) { - auto h5_float_type = lowPrecision ? H5T_NATIVE_FLOAT : H5T_NATIVE_DOUBLE; - return addVar(name, repeat, h5_float_type, "Field3D"); -} - -bool H5Format::addVarFieldPerp(const std::string &name, bool repeat) { - auto h5_float_type = lowPrecision ? H5T_NATIVE_FLOAT : H5T_NATIVE_DOUBLE; - return addVar(name, repeat, h5_float_type, "FieldPerp"); -} - -bool H5Format::read(int *data, const char *name, int lx, int ly, int lz) { - return read(data, H5T_NATIVE_INT, name, lx, ly, lz); -} - -bool H5Format::read(int *var, const std::string &name, int lx, int ly, int lz) { - return read(var, name.c_str(), lx, ly, lz); -} - -bool H5Format::read(char *data, const char *name, int n) { - return read(data, H5T_C_S1, name, n); -} - -bool H5Format::read(char *var, const std::string &name, int n) { - return read(var, name.c_str(), n); -} - -bool H5Format::read(BoutReal *data, const char *name, int lx, int ly, int lz) { - return read(data, H5T_NATIVE_DOUBLE, name, lx, ly, lz); -} - -bool H5Format::read(BoutReal *var, const std::string &name, int lx, int ly, int lz) { - return read(var, name.c_str(), lx, ly, lz); -} - -bool H5Format::read(void *data, hid_t hdf5_type, const char *name, int lx, int ly, int lz) { - TRACE("H5Format::read(void)"); - - if(!is_valid()) - return false; - - if((lx < 0) || (ly < 0) || (lz < 0)) - return false; - - int nd = 0; // Number of dimensions - if(lx != 0) nd = 1; - if(ly != 0) nd = 2; - if(lz != 0) nd = 3; - hsize_t counts[3],offset[3],offset_local[3],init_size_local[3]; - counts[0]=lx; counts[1]=ly; counts[2]=lz; - offset[0]=x0; offset[1]=y0; offset[2]=z0; - offset_local[0]=x0_local; - offset_local[1]=y0_local; - offset_local[2]=z0_local; - - // Want to be able to use without needing mesh to be initialised; makes hyperslab selection redundant - init_size_local[0]=offset_local[0]+counts[0]; - init_size_local[1]=offset_local[1]+counts[1]; - init_size_local[2]=offset_local[2]+counts[2]; - - hid_t mem_space = H5Screate_simple(nd, init_size_local, init_size_local); - if (mem_space < 0) - throw BoutException("Failed to create mem_space"); - - hid_t dataSet = H5Dopen(dataFile, name, H5P_DEFAULT); - if (dataSet < 0) { - return false; - } - - hid_t dataSpace = H5Dget_space(dataSet); - if (dataSpace < 0) - throw BoutException("Failed to create dataSpace"); - if (nd > 0 && !(nd==1 && lx==1)) - if (H5Sselect_hyperslab(dataSpace, H5S_SELECT_SET, offset, /*stride=*/nullptr, counts, - /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - if (H5Dread(dataSet, hdf5_type, mem_space, dataSpace, H5P_DEFAULT, data) < 0) - throw BoutException("Failed to read data"); - - if (H5Sclose(mem_space) < 0) - throw BoutException("Failed to close mem_space"); - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - return true; -} - -bool H5Format::read_perp(BoutReal *data, const std::string& name, int lx, int lz) { - TRACE("H5Format::read(void)"); - - hid_t hdf5_type = H5T_NATIVE_DOUBLE; - - if(!is_valid()) - return false; - - if((lx < 0) || (lz < 0)) - return false; - - int nd = 0; // Number of dimensions - if(lx != 0) nd = 1; - if(lz != 0) nd = 2; - hsize_t counts[2],offset[2],offset_local[2],init_size_local[2]; - counts[0]=lx; counts[1]=lz; - offset[0]=x0; offset[1]=z0; - offset_local[0]=x0_local; - offset_local[1]=z0_local; - - // Want to be able to use without needing mesh to be initialised; makes hyperslab selection redundant - init_size_local[0]=offset_local[0]+counts[0]; - init_size_local[1]=offset_local[1]+counts[1]; - - hid_t mem_space = H5Screate_simple(nd, init_size_local, init_size_local); - if (mem_space < 0) - throw BoutException("Failed to create mem_space"); - - hid_t dataSet = H5Dopen(dataFile, name.c_str(), H5P_DEFAULT); - if (dataSet < 0) { - return false; - } - - hid_t dataSpace = H5Dget_space(dataSet); - if (dataSpace < 0) - throw BoutException("Failed to create dataSpace"); - if (nd > 0 && !(nd==1 && lx==1)) - if (H5Sselect_hyperslab(dataSpace, H5S_SELECT_SET, offset, /*stride=*/nullptr, counts, - /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - if (H5Dread(dataSet, hdf5_type, mem_space, dataSpace, H5P_DEFAULT, data) < 0) - throw BoutException("Failed to read data"); - - if (H5Sclose(mem_space) < 0) - throw BoutException("Failed to close mem_space"); - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - return true; -} - -bool H5Format::write(int *data, const char *name, int lx, int ly, int lz) { - return write(data, H5T_NATIVE_INT, name, lx, ly, lz); -} - -bool H5Format::write(int *var, const std::string &name, int lx, int ly, int lz) { - return write(var, name.c_str(), lx, ly, lz); -} - -bool H5Format::write(char *data, const char *name, int n) { - return write(data, H5T_C_S1, name, n); -} - -bool H5Format::write(char *var, const std::string &name, int n) { - return write(var, name.c_str(), n); -} - -bool H5Format::write(BoutReal *data, const char *name, int lx, int ly, int lz) { - - if(lowPrecision) { - // An out of range value can make the conversion - // corrupt the whole dataset. Make sure everything - // is in the range of a float - int i_max=1; - if (lx>0) i_max*=lx; - if (ly>0) i_max*=ly; - if (lz>0) i_max*=lz; - - for(int i=0;i<i_max;i++) { - if(data[i] > 1e20) - data[i] = 1e20; - if(data[i] < -1e20) - data[i] = -1e20; - } - - return write(data, H5T_NATIVE_DOUBLE, name, lx, ly, lz); - } - else { - return write(data, H5T_NATIVE_DOUBLE, name, lx, ly, lz); - } - -} - -bool H5Format::write(BoutReal *var, const std::string &name, int lx, int ly, int lz) { - return write(var, name.c_str(), lx, ly, lz); -} - -bool H5Format::write(void *data, hid_t mem_hdf5_type, const char *name, int lx, int ly, - int lz) { - TRACE("H5Format::write(void)"); - - if(!is_valid()) - return false; - - if((lx < 0) || (ly < 0) || (lz < 0)) - return false; - - int nd = 0; // Number of dimensions - if(lx != 0) nd = 1; - if(ly != 0) nd = 2; - if(lz != 0) nd = 3; - hsize_t counts[3], offset[3], offset_local[3], init_size_local[3]; - counts[0] = lx; - counts[1] = ly; - counts[2] = lz; - offset[0] = x0; - offset[1] = y0; - offset[2] = z0; - offset_local[0] = x0_local; - offset_local[1] = y0_local; - offset_local[2] = z0_local; - init_size_local[0] = mesh->LocalNx; - init_size_local[1] = mesh->LocalNy; - init_size_local[2] = mesh->LocalNz; - - if (nd==0) { - // Need to write a scalar, not a 0-d array - nd = 1; - counts[0] = 1; - offset[0] = 0; - offset_local[0] = 0; - init_size_local[0] = 1; - } - - hid_t mem_space = H5Screate_simple(nd, init_size_local, init_size_local); - if (mem_space < 0) - throw BoutException("Failed to create mem_space"); - if (H5Sselect_hyperslab(mem_space, H5S_SELECT_SET, offset_local, /*stride=*/nullptr, - counts, /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - hid_t dataSet = H5Dopen(dataFile, name, H5P_DEFAULT); - if (dataSet < 0) { - output_error.write("ERROR: HDF5 variable '{:s}' has not been added to file '{:s}'\n", name, fname); - return false; - } - - hid_t dataSpace = H5Dget_space(dataSet); - if (dataSpace < 0) - throw BoutException("Failed to create dataSpace"); - if (H5Sselect_hyperslab(dataSpace, H5S_SELECT_SET, offset, /*stride=*/nullptr, counts, - /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - if (H5Dwrite(dataSet, mem_hdf5_type, mem_space, dataSpace, dataSet_plist, data) < 0) - throw BoutException("Failed to write data"); - - if (H5Sclose(mem_space) < 0) - throw BoutException("Failed to close mem_space"); - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - return true; -} - -bool H5Format::write_perp(BoutReal *data, const std::string& name, int lx, int lz) { - TRACE("H5Format::write_perp(void)"); - - hid_t mem_hdf5_type = H5T_NATIVE_DOUBLE; - - if(!is_valid()) - return false; - - if((lx < 0) || (lz < 0)) - return false; - - int nd = 0; // Number of dimensions - if(lx != 0) nd = 1; - if(lz != 0) nd = 2; - hsize_t counts[2], offset[2], offset_local[2], init_size_local[2]; - counts[0] = lx; - counts[1] = lz; - offset[0] = x0; - offset[1] = z0; - offset_local[0] = x0_local; - offset_local[1] = z0_local; - init_size_local[0] = mesh->LocalNx; - init_size_local[1] = mesh->LocalNz; - - if (nd==0) { - // Need to write a scalar, not a 0-d array - nd = 1; - counts[0] = 1; - offset[0] = 0; - offset_local[0] = 0; - init_size_local[0] = 1; - } - - hid_t mem_space = H5Screate_simple(nd, init_size_local, init_size_local); - if (mem_space < 0) - throw BoutException("Failed to create mem_space"); - if (H5Sselect_hyperslab(mem_space, H5S_SELECT_SET, offset_local, /*stride=*/nullptr, - counts, /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - hid_t dataSet = H5Dopen(dataFile, name.c_str(), H5P_DEFAULT); - if (dataSet < 0) { - output_error.write("ERROR: HDF5 variable '{:s}' has not been added to file '{:s}'\n", name, fname); - return false; - } - - hid_t dataSpace = H5Dget_space(dataSet); - if (dataSpace < 0) - throw BoutException("Failed to create dataSpace"); - if (H5Sselect_hyperslab(dataSpace, H5S_SELECT_SET, offset, /*stride=*/nullptr, counts, - /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - if (H5Dwrite(dataSet, mem_hdf5_type, mem_space, dataSpace, dataSet_plist, data) < 0) - throw BoutException("Failed to write data"); - - if (H5Sclose(mem_space) < 0) - throw BoutException("Failed to close mem_space"); - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - return true; -} - -/*************************************************************************** - * Record-based (time-dependent) data - ***************************************************************************/ - -bool H5Format::read_rec(int *data, const char *name, int lx, int ly, int lz) { - return read_rec(data, H5T_NATIVE_INT, name, lx, ly, lz); -} - -bool H5Format::read_rec(int *var, const std::string &name, int lx, int ly, int lz) { - return read_rec(var, name.c_str(), lx, ly, lz); -} - -bool H5Format::read_rec(char *data, const char *name, int n) { - return read_rec(data, H5T_C_S1, name, n); -} - -bool H5Format::read_rec(char *var, const std::string &name, int n) { - return read_rec(var, name.c_str(), n); -} - -bool H5Format::read_rec(BoutReal *data, const char *name, int lx, int ly, int lz) { - - return read_rec(data, H5T_NATIVE_DOUBLE, name, lx, ly, lz); - -} - -bool H5Format::read_rec(BoutReal *var, const std::string &name, int lx, int ly, int lz) { - return read_rec(var, name.c_str(), lx, ly, lz); -} - -bool H5Format::read_rec(void *data, hid_t hdf5_type, const char *name, int lx, int ly, - int lz) { - if (!is_valid()) { - return false; - } - - if ((lx < 0) || (ly < 0) || (lz < 0)) { - return false; - } - - int nd = 1; // Number of dimensions - if (lx != 0) { - nd = 2; - } - if (ly != 0) { - nd = 3; - } - if (lz != 0) { - nd = 4; - } - hsize_t counts[4], offset[4]; - hsize_t offset_local[3], init_size_local[3]; - counts[0] = 1; - counts[1] = lx; - counts[2] = ly; - counts[3] = lz; - offset[0] = t0; - offset[1] = x0; - offset[2] = y0; - offset[3] = z0; - offset_local[0] = x0_local; - offset_local[1] = y0_local; - offset_local[2] = z0_local; - init_size_local[0] = mesh->LocalNx; - init_size_local[1] = mesh->LocalNy; - init_size_local[2] = mesh->LocalNz; - - if (nd == 1) { - // Need to write a time-series of scalars - nd = 1; - counts[1] = 1; - offset[1] = 0; - init_size_local[0] = 1; - } - - hid_t mem_space = H5Screate_simple(nd, init_size_local, init_size_local); - if (mem_space < 0) - throw BoutException("Failed to create mem_space"); - if (H5Sselect_hyperslab(mem_space, H5S_SELECT_SET, offset_local, /*stride=*/nullptr, - counts, /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - hid_t dataSet = H5Dopen(dataFile, name, H5P_DEFAULT); - if (dataSet < 0) - throw BoutException("Failed to open dataSet"); - - hid_t dataSpace = H5Dget_space(dataSet); - if (dataSpace < 0) - throw BoutException("Failed to create dataSpace"); - if (H5Sselect_hyperslab(dataSpace, H5S_SELECT_SET, offset, /*stride=*/nullptr, counts, - /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - if (H5Dread(dataSet, hdf5_type, mem_space, dataSpace, H5P_DEFAULT, data) < 0) - throw BoutException("Failed to read data"); - - if (H5Sclose(mem_space) < 0) - throw BoutException("Failed to close mem_space"); - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - return true; -} - -bool H5Format::read_rec_perp(BoutReal *data, const std::string& name, int lx, int lz) { - if (!is_valid()) { - return false; - } - - hid_t hdf5_type = H5T_NATIVE_DOUBLE; - - if ((lx < 0) || (lz < 0)) { - return false; - } - - int nd = 1; // Number of dimensions - if (lx != 0) { - nd = 2; - } - if (lz != 0) { - nd = 3; - } - hsize_t counts[3], offset[3]; - hsize_t offset_local[2], init_size_local[2]; - counts[0] = 1; - counts[1] = lx; - counts[2] = lz; - offset[0] = t0; - offset[1] = x0; - offset[2] = z0; - offset_local[0] = x0_local; - offset_local[1] = z0_local; - init_size_local[0] = mesh->LocalNx; - init_size_local[1] = mesh->LocalNz; - - if (nd == 1) { - // Need to write a time-series of scalars - nd = 1; - counts[1] = 1; - offset[1] = 0; - init_size_local[0] = 1; - } - - hid_t mem_space = H5Screate_simple(nd, init_size_local, init_size_local); - if (mem_space < 0) - throw BoutException("Failed to create mem_space"); - if (H5Sselect_hyperslab(mem_space, H5S_SELECT_SET, offset_local, /*stride=*/nullptr, - counts, /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - hid_t dataSet = H5Dopen(dataFile, name.c_str(), H5P_DEFAULT); - if (dataSet < 0) - throw BoutException("Failed to open dataSet"); - - hid_t dataSpace = H5Dget_space(dataSet); - if (dataSpace < 0) - throw BoutException("Failed to create dataSpace"); - if (H5Sselect_hyperslab(dataSpace, H5S_SELECT_SET, offset, /*stride=*/nullptr, counts, - /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - if (H5Dread(dataSet, hdf5_type, mem_space, dataSpace, H5P_DEFAULT, data) < 0) - throw BoutException("Failed to read data"); - - if (H5Sclose(mem_space) < 0) - throw BoutException("Failed to close mem_space"); - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - return true; -} - -bool H5Format::write_rec(int *data, const char *name, int lx, int ly, int lz) { - return write_rec(data, H5T_NATIVE_INT, name, lx, ly, lz); -} - -bool H5Format::write_rec(int *var, const std::string &name, int lx, int ly, int lz) { - return write_rec(var, name.c_str(), lx, ly, lz); -} - -bool H5Format::write_rec(char *data, const char *name, int n) { - return write_rec(data, H5T_C_S1, name, n); -} - -bool H5Format::write_rec(char *var, const std::string &name, int n) { - return write_rec(var, name.c_str(), n); -} - -bool H5Format::write_rec(BoutReal *data, const char *name, int lx, int ly, int lz) { - - if(lowPrecision) { - // An out of range value can make the conversion - // corrupt the whole dataset. Make sure everything - // is in the range of a float - int i_max=1; - if (lx>0) i_max*=lx; - if (ly>0) i_max*=ly; - if (lz>0) i_max*=lz; - - for(int i=0;i<i_max;i++) { - if(data[i] > 1e20) - data[i] = 1e20; - if(data[i] < -1e20) - data[i] = -1e20; - } - return write_rec(data, H5T_NATIVE_DOUBLE, name, lx, ly, lz); - } - - return write_rec(data, H5T_NATIVE_DOUBLE, name, lx, ly, lz); -} - -bool H5Format::write_rec(BoutReal *var, const std::string &name, int lx, int ly, int lz) { - return write_rec(var, name.c_str(), lx, ly, lz); -} - -bool H5Format::write_rec(void *data, hid_t mem_hdf5_type, const char *name, int lx, int ly, int lz) { - if(!is_valid()) - return false; - - if((lx < 0) || (ly < 0) || (lz < 0)) - return false; - - int nd = 1; // Number of dimensions - if(lx != 0) nd = 2; - if(ly != 0) nd = 3; - if(lz != 0) nd = 4; - int nd_local = nd-1; - hsize_t counts[4], offset[4]; - hsize_t counts_local[3], offset_local[3], init_size_local[3]; - counts[0] = 1; - counts[1] = lx; - counts[2] = ly; - counts[3] = lz; - counts_local[0] = lx; - counts_local[1] = ly; - counts_local[2] = lz; - // Do this later, after setting t0// offset[0]=t0; - offset[1] = x0; - offset[2] = y0; - offset[3] = z0; - offset_local[0] = x0_local; - offset_local[1] = y0_local; - offset_local[2] = z0_local; - init_size_local[0] = mesh->LocalNx; - init_size_local[1] = mesh->LocalNy; - init_size_local[2] = mesh->LocalNz; - - if (nd_local == 0) { - nd_local = 1; - // Need to write a time-series of scalars - counts_local[0] = 1; - offset_local[0] = 0; - init_size_local[0] = 1; - } - - hid_t mem_space = H5Screate_simple(nd_local, init_size_local, init_size_local); - if (mem_space < 0) - throw BoutException("Failed to create mem_space"); - if (H5Sselect_hyperslab(mem_space, H5S_SELECT_SET, offset_local, /*stride=*/nullptr, - counts_local, /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - hid_t dataSet = H5Dopen(dataFile, name, H5P_DEFAULT); - if (dataSet >= 0) { // >=0 means file exists, so open. Else error. - - hsize_t dims[4] = {}; - hid_t dataSpace = H5Dget_space(dataSet); - if (dataSpace < 0) - throw BoutException("Failed to create dataSpace"); - if (H5Sget_simple_extent_dims(dataSpace, dims, /*maxdims=*/nullptr) < 0) - throw BoutException("Failed to get dims"); - dims[0]+=1; - if (t0 == -1) { - // Want t0 to be last record - t0 = dims[0]-1; - } - - if (H5Dset_extent(dataSet, dims) < 0) - throw BoutException("Failed to extend dataSet"); - - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - - } - else { - output_error.write("ERROR: HDF5 variable '{:s}' has not been added to file '{:s}'\n", name, fname); - return false; - } - - offset[0]=t0; - - hid_t dataSpace = H5Dget_space(dataSet); - if (dataSpace < 0) - throw BoutException("Failed to create dataSpace"); - if (H5Sselect_hyperslab(dataSpace, H5S_SELECT_SET, offset, /*stride=*/nullptr, counts, - /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - if (H5Dwrite(dataSet, mem_hdf5_type, mem_space, dataSpace, dataSet_plist, data) < 0) - throw BoutException("Failed to write data"); - - if (H5Sclose(mem_space) < 0) - throw BoutException("Failed to close mem_space"); - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - return true; -} - -bool H5Format::write_rec_perp(BoutReal *data, const std::string& name, int lx, int lz) { - if(!is_valid()) - return false; - - hid_t mem_hdf5_type = H5T_NATIVE_DOUBLE; - - if((lx < 0) || (lz < 0)) - return false; - - int nd = 1; // Number of dimensions - if(lx != 0) nd = 2; - if(lz != 0) nd = 3; - int nd_local = nd-1; - hsize_t counts[3], offset[3]; - hsize_t counts_local[2], offset_local[2], init_size_local[2]; - counts[0] = 1; - counts[1] = lx; - counts[2] = lz; - counts_local[0] = lx; - counts_local[1] = lz; - // Do this later, after setting t0// offset[0]=t0; - offset[1] = x0; - offset[2] = z0; - offset_local[0] = x0_local; - offset_local[1] = z0_local; - init_size_local[0] = mesh->LocalNx; - init_size_local[1] = mesh->LocalNz; - - if (nd_local == 0) { - nd_local = 1; - // Need to write a time-series of scalars - counts_local[0] = 1; - offset_local[0] = 0; - init_size_local[0] = 1; - } - - hid_t mem_space = H5Screate_simple(nd_local, init_size_local, init_size_local); - if (mem_space < 0) - throw BoutException("Failed to create mem_space"); - if (H5Sselect_hyperslab(mem_space, H5S_SELECT_SET, offset_local, /*stride=*/nullptr, - counts_local, /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - hid_t dataSet = H5Dopen(dataFile, name.c_str(), H5P_DEFAULT); - if (dataSet >= 0) { // >=0 means file exists, so open. Else error. - - hsize_t dims[3] = {}; - hid_t dataSpace = H5Dget_space(dataSet); - if (dataSpace < 0) - throw BoutException("Failed to create dataSpace"); - if (H5Sget_simple_extent_dims(dataSpace, dims, /*maxdims=*/nullptr) < 0) - throw BoutException("Failed to get dims"); - dims[0]+=1; - if (t0 == -1) { - // Want t0 to be last record - t0 = dims[0]-1; - } - - if (H5Dset_extent(dataSet, dims) < 0) - throw BoutException("Failed to extend dataSet"); - - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - - } - else { - output_error.write("ERROR: HDF5 variable '{:s}' has not been added to file '{:s}'\n", name, fname); - return false; - } - - offset[0]=t0; - - hid_t dataSpace = H5Dget_space(dataSet); - if (dataSpace < 0) - throw BoutException("Failed to create dataSpace"); - if (H5Sselect_hyperslab(dataSpace, H5S_SELECT_SET, offset, /*stride=*/nullptr, counts, - /*block=*/nullptr) < 0) - throw BoutException("Failed to select hyperslab"); - - if (H5Dwrite(dataSet, mem_hdf5_type, mem_space, dataSpace, dataSet_plist, data) < 0) - throw BoutException("Failed to write data"); - - if (H5Sclose(mem_space) < 0) - throw BoutException("Failed to close mem_space"); - if (H5Sclose(dataSpace) < 0) - throw BoutException("Failed to close dataSpace"); - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - return true; -} - - -/*************************************************************************** - * Attributes - ***************************************************************************/ - -void H5Format::setAttribute(const std::string &varname, const std::string &attrname, - const std::string &text) { - TRACE("H5Format::setAttribute(varname, attrname, string)"); - - std::string existing_att; - if (getAttribute(varname, attrname, existing_att)) { - if (text != existing_att) { - output_warn.write("Overwriting attribute '{:s}' of variable '{:s}' with '{:s}', " - "was previously '{:s}'", - attrname, varname, text, existing_att); - } - } - // else: attribute does not exist, so just write it - - if (varname == "") { - // attribute of file - setAttribute(dataFile, attrname, text); - } else { - // attribute of variable - hid_t dataSet = H5Dopen(dataFile, varname.c_str(), H5P_DEFAULT); - if (dataSet < 0) { - // Negative value indicates error, i.e. variable does not exist - throw BoutException("Trying to create attribute for variable that does not exist"); - } - - setAttribute(dataSet, attrname, text); - - if (H5Dclose(dataSet) < 0) { - throw BoutException("Failed to close dataSet"); - } - } -} - -void H5Format::setAttribute(const std::string &varname, const std::string &attrname, - int value) { - TRACE("H5Format::setAttribute(varname, attrname, int)"); - - int existing_att; - if (getAttribute(varname, attrname, existing_att)) { - if (value != existing_att) { - output_warn.write("Overwriting attribute '{:s}' of variable '{:s}' with '{:d}', was previously '{:d}'", attrname, varname, value, existing_att); - } - } - // else: attribute does not exist, so just write it - - if (varname == "") { - // attribute of file - setAttribute(dataFile, attrname, value); - } else { - // attribute of variable - hid_t dataSet = H5Dopen(dataFile, varname.c_str(), H5P_DEFAULT); - if (dataSet < 0) { - // Negative value indicates error, i.e. variable does not exist - throw BoutException("Trying to create attribute for variable that does not exist"); - } - - setAttribute(dataSet, attrname, value); - - if (H5Dclose(dataSet) < 0) { - throw BoutException("Failed to close dataSet"); - } - } -} - -void H5Format::setAttribute(const std::string &varname, const std::string &attrname, - BoutReal value) { - TRACE("H5Format::setAttribute(varname, attrname, BoutReal)"); - - BoutReal existing_att; - if (getAttribute(varname, attrname, existing_att)) { - if (value != existing_att) { - output_warn.write("Overwriting attribute '{:s}' of variable '{:s}' with '{:f}', was previously '{:f}'", attrname, varname, value, existing_att); - } - } - // else: attribute does not exist, so just write it - - if (varname == "") { - // attribute of file - setAttribute(dataFile, attrname, value); - } else { - // attribute of variable - hid_t dataSet = H5Dopen(dataFile, varname.c_str(), H5P_DEFAULT); - if (dataSet < 0) { - // Negative value indicates error, i.e. variable does not exist - throw BoutException("Trying to create attribute for variable that does not exist"); - } - - setAttribute(dataSet, attrname, value); - - if (H5Dclose(dataSet) < 0) { - throw BoutException("Failed to close dataSet"); - } - } -} - -void H5Format::setAttribute(const hid_t &dataSet, const std::string &attrname, - const std::string &text) { - TRACE("H5Format::setAttribute(dataSet, attrname, string)"); - - // Create new dataspace for attribute - hid_t attribute_dataspace = H5Screate(H5S_SCALAR); - if (attribute_dataspace < 0) - throw BoutException("Failed to create attribute_dataspace"); - - // Create new string datatype for attribute - hid_t variable_length_string_type = H5Tcopy(H5T_C_S1); - if (variable_length_string_type < 0) - throw BoutException("Failed to create variable_length_string_type"); - if (H5Tset_size(variable_length_string_type, H5T_VARIABLE) < 0) - throw BoutException("Failed to create string type"); - - // Create attribute if it does not exist and write to it - hid_t myatt_in = H5Aopen(dataSet, attrname.c_str(), H5P_DEFAULT); - if (myatt_in < 0) { - // Need to create attribute - myatt_in = H5Acreate(dataSet, attrname.c_str(), variable_length_string_type, attribute_dataspace, H5P_DEFAULT, H5P_DEFAULT); - if (myatt_in < 0) - throw BoutException("Failed to create attribute"); - } - // Need to pass `const char**` to HDF5 for reasons, and - // `&text.c_str()` isn't valid (can't take address of an - // r-value/temporary), so we need an intermediate variable - const char* c_text = text.c_str(); - if (H5Awrite(myatt_in, variable_length_string_type, &c_text) < 0) - throw BoutException("Failed to write attribute"); - - if (H5Sclose(attribute_dataspace) < 0) - throw BoutException("Failed to close attribute_dataspace"); - if (H5Tclose(variable_length_string_type) < 0) - throw BoutException("Failed to close variable_length_string_type"); - if (H5Aclose(myatt_in) < 0) - throw BoutException("Failed to close myatt_in"); -} - -void H5Format::setAttribute(const hid_t &dataSet, const std::string &attrname, - int value) { - TRACE("H5Format::setAttribute(dataSet, attrname, int)"); - - // Create new dataspace for attribute - hid_t attribute_dataspace = H5Screate(H5S_SCALAR); - if (attribute_dataspace < 0) - throw BoutException("Failed to create attribute_dataspace"); - - // Create attribute and write to it - hid_t myatt_in = H5Acreate(dataSet, attrname.c_str(), H5T_NATIVE_INT, attribute_dataspace, H5P_DEFAULT, H5P_DEFAULT); - if (myatt_in < 0) - throw BoutException("Failed to create attribute"); - if (H5Awrite(myatt_in, H5T_NATIVE_INT, &value) < 0) - throw BoutException("Failed to write attribute"); - - if (H5Sclose(attribute_dataspace) < 0) - throw BoutException("Failed to close attribute_dataspace"); - if (H5Aclose(myatt_in) < 0) - throw BoutException("Failed to close myatt_in"); -} - -void H5Format::setAttribute(const hid_t &dataSet, const std::string &attrname, - BoutReal value) { - TRACE("H5Format::setAttribute(dataSet, attrname, BoutReal)"); - - // Create new dataspace for attribute - hid_t attribute_dataspace = H5Screate(H5S_SCALAR); - if (attribute_dataspace < 0) - throw BoutException("Failed to create attribute_dataspace"); - - // Create attribute and write to it - hid_t myatt_in = H5Acreate(dataSet, attrname.c_str(), H5T_NATIVE_DOUBLE, attribute_dataspace, H5P_DEFAULT, H5P_DEFAULT); - if (myatt_in < 0) - throw BoutException("Failed to create attribute"); - if (H5Awrite(myatt_in, H5T_NATIVE_DOUBLE, &value) < 0) - throw BoutException("Failed to write attribute"); - - if (H5Sclose(attribute_dataspace) < 0) - throw BoutException("Failed to close attribute_dataspace"); - if (H5Aclose(myatt_in) < 0) - throw BoutException("Failed to close myatt_in"); -} - -bool H5Format::getAttribute(const std::string &varname, const std::string &attrname, std::string &text) { - TRACE("H5Format::getAttribute(varname, attrname, string)"); - - if (varname == "") { - // attribute of file - return getAttribute(dataFile, attrname, text); - } else { - // attribute of variable - hid_t dataSet = H5Dopen(dataFile, varname.c_str(), H5P_DEFAULT); - if (dataSet < 0) { - // Negative value indicates error, i.e. variable does not exist - throw BoutException("Trying to read attribute for variable that does not exist"); - } - - bool result = getAttribute(dataSet, attrname, text); - - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - return result; - } -} - -bool H5Format::getAttribute(const std::string &varname, const std::string &attrname, int &value) { - TRACE("H5Format::getAttribute(varname, attrname, int)"); - - if (varname == "") { - // attribute of file - return getAttribute(dataFile, attrname, value); - } else { - // attribute of variable - hid_t dataSet = H5Dopen(dataFile, varname.c_str(), H5P_DEFAULT); - if (dataSet < 0) { - // Negative value indicates error, i.e. variable does not exist - throw BoutException("Trying to read attribute for variable that does not exist"); - } - - bool result = getAttribute(dataSet, attrname, value); - - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - return result; - } -} - -bool H5Format::getAttribute(const std::string &varname, const std::string &attrname, BoutReal &value) { - TRACE("H5Format::getAttribute(varname, attrname, BoutReal)"); - - if (varname == "") { - // attribute of file - return getAttribute(dataFile, attrname, value); - } else { - // attribute of variable - hid_t dataSet = H5Dopen(dataFile, varname.c_str(), H5P_DEFAULT); - if (dataSet < 0) { - // Negative value indicates error, i.e. variable does not exist - throw BoutException("Trying to read attribute for variable that does not exist"); - } - - bool result = getAttribute(dataSet, attrname, value); - - if (H5Dclose(dataSet) < 0) - throw BoutException("Failed to close dataSet"); - - return result; - } -} - -bool H5Format::getAttribute(const hid_t &dataSet, const std::string &attrname, std::string &text) { - TRACE("H5Format::getAttribute(hid_t, attrname, string)"); - - // Open attribute - hid_t myatt = H5Aopen(dataSet, attrname.c_str(), H5P_DEFAULT); - if (myatt < 0) { - return false; - } - - // Create new string datatype for attribute - hid_t variable_length_string_type = H5Tcopy(H5T_C_S1); - if (variable_length_string_type < 0) - throw BoutException("Failed to create variable_length_string_type"); - if (H5Tset_size(variable_length_string_type, H5T_VARIABLE) < 0) - throw BoutException("Failed to create string type"); - - // Read attribute: Need to pass `char**` to HDF5 for reasons, but - // luckliy it will allocate c_text for us - char* c_text; - if (H5Aread(myatt, variable_length_string_type, &c_text) < 0) - throw BoutException("Failed to read attribute"); - text = c_text; - // Release resources allocated by HDF5 - free(c_text); - - if (H5Tclose(variable_length_string_type) < 0) - throw BoutException("Failed to close variable_length_string_type"); - if (H5Aclose(myatt) < 0) - throw BoutException("Failed to close myatt_in"); - - return true; -} - -bool H5Format::getAttribute(const hid_t &dataSet, const std::string &attrname, int &value) { - TRACE("H5Format::getAttribute(hid_t, attrname, int)"); - - // Open attribute - hid_t myatt = H5Aopen(dataSet, attrname.c_str(), H5P_DEFAULT); - if (myatt < 0) { - return false; - } - - // Read attribute - if (H5Aread(myatt, H5T_NATIVE_INT, &value) < 0) - throw BoutException("Failed to read attribute"); - - if (H5Aclose(myatt) < 0) - throw BoutException("Failed to close myatt_in"); - - return true; -} - -bool H5Format::getAttribute(const hid_t &dataSet, const std::string &attrname, BoutReal &value) { - TRACE("H5Format::getAttribute(hid_t, attrname, BoutReal)"); - - // Open attribute - hid_t myatt = H5Aopen(dataSet, attrname.c_str(), H5P_DEFAULT); - if (myatt < 0) { - return false; - } - - // Read attribute - if (H5Aread(myatt, H5T_NATIVE_DOUBLE, &value) < 0) - throw BoutException("Failed to read attribute"); - - if (H5Aclose(myatt) < 0) - throw BoutException("Failed to close myatt_in"); - - return true; -} - -#endif // BOUT_HAS_HDF5 diff --git a/src/fileio/impls/hdf5/h5_format.hxx b/src/fileio/impls/hdf5/h5_format.hxx deleted file mode 100644 index 767d51ec1c..0000000000 --- a/src/fileio/impls/hdf5/h5_format.hxx +++ /dev/null @@ -1,183 +0,0 @@ -/*! - * \file h5_format.hxx - * - * \brief HDF5 data format interface - * - * \author John Omotani - * \date 2015 - * - * Records: In netCDF, the time dimension for each dimension must be - * the same. Hence when a record is appended to a variable, the size - * of all variables is increased. To work out which record to write to, - * a map of variable names to record number is kept. - * - ************************************************************************** - * Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu - * - * Contact: Ben Dudson, bd512@york.ac.uk - * - * This file is part of BOUT++. - * - * BOUT++ is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * BOUT++ is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with BOUT++. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#include "bout/build_config.hxx" - -#if !BOUT_HAS_HDF5 - -#include "../emptyformat.hxx" -using H5Format = EmptyFormat; - -#else - -class H5Format; - -#ifndef __H5FORMAT_H__ -#define __H5FORMAT_H__ - -#include "dataformat.hxx" - -#include <hdf5.h> - -#include <map> -#include <string> - -class H5Format : public DataFormat { - public: - H5Format(bool parallel_in = false, Mesh* mesh_in = nullptr); - H5Format(const char *name, bool parallel_in = false, Mesh* mesh_in = nullptr); - H5Format(const std::string &name, bool parallel_in = false, Mesh* mesh_in = nullptr) - : H5Format(name.c_str(), parallel_in, mesh_in) {} - ~H5Format(); - - using DataFormat::openr; - bool openr(const char *name) override; - using DataFormat::openw; - bool openw(const char *name, bool append=false) override; - - bool is_valid() override; - - void close() override; - - void flush() override; - - const char* filename() { return fname; }; - - const std::vector<int> getSize(const char *var) override; - const std::vector<int> getSize(const std::string &var) override; - - // Set the origin for all subsequent calls - bool setGlobalOrigin(int x = 0, int y = 0, int z = 0) override; - bool setLocalOrigin(int x = 0, int y = 0, int z = 0, int offset_x = 0, int offset_y = 0, int offset_z = 0) override; - bool setRecord(int t) override; // negative -> latest - - // Add a variable to the file - bool addVarInt(const std::string &name, bool repeat) override; - bool addVarIntVec(const std::string &name, bool repeat, size_t size) override; - bool addVarString(const std::string &name, bool repeat, size_t size) override; - bool addVarBoutReal(const std::string &name, bool repeat) override; - bool addVarField2D(const std::string &name, bool repeat) override; - bool addVarField3D(const std::string &name, bool repeat) override; - bool addVarFieldPerp(const std::string &name, bool repeat) override; - - // Read / Write simple variables up to 3D - - bool read(int *var, const char *name, int lx = 1, int ly = 0, int lz = 0) override; - bool read(int *var, const std::string &name, int lx = 1, int ly = 0, int lz = 0) override; - bool read(char *var, const char *name, int n = 1) override; - bool read(char *var, const std::string &name, int n = 1) override; - bool read(BoutReal *var, const char *name, int lx = 1, int ly = 0, int lz = 0) override; - bool read(BoutReal *var, const std::string &name, int lx = 1, int ly = 0, int lz = 0) override; - bool read_perp(BoutReal *var, const std::string &name, int lx = 1, int lz = 0) override; - - bool write(int *var, const char *name, int lx = 0, int ly = 0, int lz = 0) override; - bool write(int *var, const std::string &name, int lx = 0, int ly = 0, int lz = 0) override; - bool write(char *var, const char *name, int n = 1) override; - bool write(char *var, const std::string &name, int n = 1) override; - bool write(BoutReal *var, const char *name, int lx = 0, int ly = 0, int lz = 0) override; - bool write(BoutReal *var, const std::string &name, int lx = 0, int ly = 0, int lz = 0) override; - bool write_perp(BoutReal *var, const std::string &name, int lx = 0, int lz = 0) override; - - // Read / Write record-based variables - - bool read_rec(int *var, const char *name, int lx = 1, int ly = 0, int lz = 0) override; - bool read_rec(int *var, const std::string &name, int lx = 1, int ly = 0, int lz = 0) override; - bool read_rec(char *var, const char *name, int n = 1) override; - bool read_rec(char *var, const std::string &name, int n = 1) override; - bool read_rec(BoutReal *var, const char *name, int lx = 1, int ly = 0, int lz = 0) override; - bool read_rec(BoutReal *var, const std::string &name, int lx = 1, int ly = 0, int lz = 0) override; - bool read_rec_perp(BoutReal *var, const std::string &name, int lx = 1, int lz = 0) override; - - bool write_rec(int *var, const char *name, int lx = 0, int ly = 0, int lz = 0) override; - bool write_rec(int *var, const std::string &name, int lx = 0, int ly = 0, int lz = 0) override; - bool write_rec(char *var, const char *name, int n = 1) override; - bool write_rec(char *var, const std::string &name, int n = 1) override; - bool write_rec(BoutReal *var, const char *name, int lx = 0, int ly = 0, int lz = 0) override; - bool write_rec(BoutReal *var, const std::string &name, int lx = 0, int ly = 0, int lz = 0) override; - bool write_rec_perp(BoutReal *var, const std::string &name, int lx = 0, int lz = 0) override; - - void setLowPrecision() override { lowPrecision = true; } - - // Attributes - - void setAttribute(const std::string &varname, const std::string &attrname, - const std::string &text) override; - void setAttribute(const std::string &varname, const std::string &attrname, - int value) override; - void setAttribute(const std::string &varname, const std::string &attrname, - BoutReal value) override; - bool getAttribute(const std::string &varname, const std::string &attrname, std::string &text) override; - bool getAttribute(const std::string &varname, const std::string &attrname, int &value) override; - bool getAttribute(const std::string &varname, const std::string &attrname, BoutReal &value) override; - - private: - - char *fname; ///< Current file name - - hid_t dataFile; - hid_t dataFile_plist; - hid_t dataSet_plist; - - bool lowPrecision; ///< When writing, down-convert to floats - bool parallel; - - int x0, y0, z0, t0; ///< Data origins for file access - int x0_local, y0_local, z0_local; ///< Data origins for memory access - - hsize_t chunk_length; - - bool addVar(const std::string &name, bool repeat, hid_t write_hdf5_type, std::string datatype, - int lx = 0, int ly = 0, int lz = 0); - bool read(void *var, hid_t hdf5_type, const char *name, int lx = 1, int ly = 0, int lz = 0); - bool write(void *var, hid_t mem_hdf5_type, const char *name, int lx = 0, int ly = 0, int lz = 0); - bool read_rec(void *var, hid_t hdf5_type, const char *name, int lx = 1, int ly = 0, int lz = 0); - bool write_rec(void *var, hid_t mem_hdf5_type, const char *name, int lx = 0, int ly = 0, int lz = 0); - - // Attributes - - void setAttribute(const hid_t &dataSet, const std::string &attrname, - const std::string &text); - void setAttribute(const hid_t &dataSet, const std::string &attrname, - int value); - void setAttribute(const hid_t &dataSet, const std::string &attrname, - BoutReal value); - bool getAttribute(const hid_t &dataSet, const std::string &attrname, std::string &text); - bool getAttribute(const hid_t &dataSet, const std::string &attrname, int &value); - bool getAttribute(const hid_t &dataSet, const std::string &attrname, BoutReal &value); -}; - -#endif // __H5FORMAT_H__ - -#endif // BOUT_HAS_HDF5 diff --git a/src/fileio/impls/hdf5/makefile b/src/fileio/impls/hdf5/makefile deleted file mode 100644 index 3497f0de9f..0000000000 --- a/src/fileio/impls/hdf5/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = h5_format.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/fileio/impls/makefile b/src/fileio/impls/makefile index 04dd6285bc..fee18c202d 100644 --- a/src/fileio/impls/makefile +++ b/src/fileio/impls/makefile @@ -1,7 +1,7 @@ BOUT_TOP = ../../.. -DIRS = netcdf netcdf4 pnetcdf hdf5 +DIRS = netcdf netcdf4 pnetcdf TARGET = lib include $(BOUT_TOP)/make.config diff --git a/tests/integrated/.gitignore b/tests/integrated/.gitignore index 0d4bfd1528..3eaa8b2d7e 100644 --- a/tests/integrated/.gitignore +++ b/tests/integrated/.gitignore @@ -13,7 +13,6 @@ BOUT.settings /test-interchange-instability/2fluid /test-invpar/test_invpar /test-io/test_io -/test-io_hdf5/test_io_hdf5 /test-laplace/test_laplace /test-restarting/test_restarting /test-smooth/test_smooth @@ -30,7 +29,6 @@ BOUT.settings /test-fci-slab/fci_slab /test-fieldgroupComm/test /test-interpolate/test_interpolate -/test-io_hdf5/test_io /test-multigrid_laplace/test_multigrid_laplace /test-petsc_laplace/test_petsc_laplace /test-petsc_laplace_MAST-grid/test_petsc_laplace_MAST_grid diff --git a/tests/integrated/CMakeLists.txt b/tests/integrated/CMakeLists.txt index 05d58e1956..1026829560 100644 --- a/tests/integrated/CMakeLists.txt +++ b/tests/integrated/CMakeLists.txt @@ -18,7 +18,6 @@ add_subdirectory(test-interpolate-z) add_subdirectory(test-invertable-operator) add_subdirectory(test-invpar) add_subdirectory(test-io) -add_subdirectory(test-io_hdf5) add_subdirectory(test-laplace) add_subdirectory(test-laplace-petsc3d) add_subdirectory(test-laplacexy-fv) @@ -29,7 +28,6 @@ add_subdirectory(test-options-netcdf) add_subdirectory(test-petsc_laplace) add_subdirectory(test-petsc_laplace_MAST-grid) add_subdirectory(test-restart-io) -add_subdirectory(test-restart-io_hdf5) add_subdirectory(test-restarting) add_subdirectory(test-slepc-solver) add_subdirectory(test-smooth) diff --git a/tests/integrated/test-drift-instability/doc/drift_instability.bib b/tests/integrated/test-drift-instability/doc/drift_instability.bib index dc74fdcd87..a84ff5c1e0 100644 --- a/tests/integrated/test-drift-instability/doc/drift_instability.bib +++ b/tests/integrated/test-drift-instability/doc/drift_instability.bib @@ -25,14 +25,6 @@ @string{CiCP @string{JPCS = {Journal of Physics: Conference Series}} @string{CPC = {Comp. Phys. Comm.}} -%% HDF5 - -@Misc{hdf5-www, - author = {{The HDF Group}}, - title = {{HDF5}}, - note = {{http://www.hdfgroup.org/HDF5/index.html}} -} - %% netCDF @Article{brown-1993, diff --git a/tests/integrated/test-io_hdf5/CMakeLists.txt b/tests/integrated/test-io_hdf5/CMakeLists.txt deleted file mode 100644 index 25eb3a4e6f..0000000000 --- a/tests/integrated/test-io_hdf5/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -bout_add_integrated_test(test-io-hdf5 - SOURCES test_io_hdf5.cxx - USE_RUNTEST - USE_DATA_BOUT_INP - EXTRA_FILES test_io.grd.hdf5 data/benchmark.out.0.hdf5 - REQUIRES BOUT_HAS_HDF5 -) diff --git a/tests/integrated/test-io_hdf5/README.md b/tests/integrated/test-io_hdf5/README.md deleted file mode 100644 index 6748d9a3bc..0000000000 --- a/tests/integrated/test-io_hdf5/README.md +++ /dev/null @@ -1,23 +0,0 @@ -test-io_hdf5 -============ - -Test if variables can be read and written correctly for different number of -processes, using the HDF5 file format. - -The test reads variables from gridfile, then writes them to the output file. The -output file is compared to existing benchmark files with a tolerance of 1e-10. -The test is run using 1, 2 and 4 MPI processes. - -The following types are read in then immediately written to the output file: - -- int -- BoutReal -- Field2D -- Field3D - -Additionally, the following types are evolved: - -- int -- BoutReal -- Vector2D -- Vector3D diff --git a/tests/integrated/test-io_hdf5/data/BOUT.inp b/tests/integrated/test-io_hdf5/data/BOUT.inp deleted file mode 100644 index 0985e6bde4..0000000000 --- a/tests/integrated/test-io_hdf5/data/BOUT.inp +++ /dev/null @@ -1,13 +0,0 @@ -# Simple I/O test -# -# Load variables from a grid file, then write them out -# to a data file. -# - -NOUT = 0 # No timesteps - -MZ = 4 # Z size - -grid = "test_io.grd.hdf5" - -dump_format = "hdf5" # HDF5 format. Alternative is "pdb" or "nc" diff --git a/tests/integrated/test-io_hdf5/data/benchmark.out.0.hdf5 b/tests/integrated/test-io_hdf5/data/benchmark.out.0.hdf5 deleted file mode 100644 index 2bbc88cbd6ad46ef4c92a828ee7a16d8f5a4bf16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 727950 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 diff --git a/tests/integrated/test-io_hdf5/generate.py b/tests/integrated/test-io_hdf5/generate.py deleted file mode 100644 index ea8e6478a8..0000000000 --- a/tests/integrated/test-io_hdf5/generate.py +++ /dev/null @@ -1,31 +0,0 @@ -# Create an input file for testing - -from h5py import File -import numpy -from sys import exit - -# number of components -nx = 12 -ny = 12 -nz = 5 - -ivar = 1 -rvar = numpy.pi -f2d = numpy.random.rand(nx, ny) -fperp = numpy.random.rand(nx, nz) -fperp2 = numpy.random.rand(nx, nz) -f3d = numpy.random.rand(nx, ny, nz) - -with File('test_io.grd.hdf5', 'w') as f: - f['nx'] = nx - f['ny'] = nx - f['ivar'] = ivar - f['rvar'] = rvar - - f['f2d'] = f2d - f['fperp'] = fperp - f['fperp2'] = fperp2 - f['fperp2'].attrs['yindex_global'] = 11 - f['f3d'] = f3d - -exit(0) diff --git a/tests/integrated/test-io_hdf5/makefile b/tests/integrated/test-io_hdf5/makefile deleted file mode 100644 index 0e55654a3a..0000000000 --- a/tests/integrated/test-io_hdf5/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_io_hdf5.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-io_hdf5/run.sh b/tests/integrated/test-io_hdf5/run.sh deleted file mode 100755 index 9158bdd67e..0000000000 --- a/tests/integrated/test-io_hdf5/run.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -make - -./test_io - -benchmark=`md5sum data/benchmark.out.0.nc | head -c 32` -output=`md5sum data/test_io.out.0.nc | head -c 32` - -echo "== Checksums ==" -echo $benchmark -echo $output -echo "" - -if test "$benchmark" = "$output"; then - echo "=> TEST PASSED" -else - echo "=> TEST FAILED" -fi - diff --git a/tests/integrated/test-io_hdf5/runtest b/tests/integrated/test-io_hdf5/runtest deleted file mode 100755 index 0efc929a27..0000000000 --- a/tests/integrated/test-io_hdf5/runtest +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/env python3 - -# -# Run the test, compare results against the benchmark -# - -# Requires: hdf5 -# Cores: 4 - -from boututils.run_wrapper import build_and_log, shell, launch_safe -from boutdata.collect import collect -from boututils.datafile import DataFile -import numpy as np -from sys import exit - - -build_and_log("I/O test") - -# Read benchmark values - -vars = [ - "ivar", - "ivar_vec", - "svar", - "rvar", - "bvar", - "f2d", - "f3d", - "fperp", - "fperp2", - "ivar_evol", - "ivar_vec_evol", - "svar_evol", - "rvar_evol", - "bvar_evol", - "v2d_evol_x", - "v2d_evol_y", - "v2d_evol_z", - "fperp2_evol", -] - -field_vars = [ - "f2d", - "f3d", - "fperp", - "fperp2", - "v2d_evol_x", - "v2d_evol_y", - "v2d_evol_z", - "fperp2_evol", -] # Field quantities, not scalars - -tol = 1e-10 - -print("Reading benchmark data") -bmk = {} -for v in vars: - if "ivar_vec" in v or "svar" in v: - f = DataFile("data/benchmark.out.0.hdf5") - bmk[v] = f[v][...] - else: - bmk[v] = collect(v, path="data", prefix="benchmark.out", info=False) - - -# Executable name -test_exe = "./test_io_hdf5" - - -def check_output(): - success = True - for v in vars: - print(" Checking variable " + v + " ... ", end="") - if "ivar_vec" in v or "svar" in v: - f = DataFile("data/BOUT.dmp.0.hdf5") - result = f[v][...] - else: - result = collect(v, path="data", info=False) - - # Compare benchmark and output - if np.shape(bmk[v]) != np.shape(result): - print("Fail, wrong shape") - success = False - continue - - if result.dtype.kind not in np.typecodes["AllFloat"]: - # Non-float types should be identical - if not np.all(bmk[v] == result): - print("Fail") - success = False - continue - else: - diff = np.max(np.abs(bmk[v] - result)) - if diff > tol: - print("Fail, maximum difference = " + str(diff)) - success = False - continue - - for attrname in bmk[v].attributes: - bmkattr = bmk[v].attributes[attrname] - resattr = result.attributes[attrname] - if not bmkattr == resattr: - print( - "Fail: Attribute {} not the same for {}. Expected {}, got {}".format( - attrname, v, bmkattr, resattr - ) - ) - success = False - - if v in field_vars: - # Check cell location - if "cell_location" not in result.attributes: - print("Fail: {0} has no cell_location attribute".format(v)) - success = False - continue - - if result.attributes["cell_location"] != "CELL_CENTRE": - print( - "Fail: Expecting cell_location == CELL_CENTRE, but got {0}".format( - result.attributes["cell_location"] - ) - ) - success = False - continue - - print("Pass") - - return success - - -print("Running I/O test") -success = True -for nproc in [1, 2, 4]: - for split in [None, "NXPE", "NYPE"]: - if split is not None: - npe_max = nproc - else: - npe_max = 1 - for np_split in [i for i in [1, 2, 4] if i <= npe_max]: - - if split is not None: - extra_args = " {}={}".format(split, np_split) - else: - extra_args = "" - - cmd = test_exe + extra_args - - # On some machines need to delete dmp files first - # or data isn't written correctly - shell("rm -f data/BOUT.dmp.*") - - # Run test case - print(" %d processor...." % (nproc) + extra_args) - s, out = launch_safe(cmd, nproc=nproc, pipe=True) - with open("run.log." + str(nproc), "w") as f: - f.write(out) - - # Check processor splitting - if split is not None: - print(" Checking " + split + " ... ", end="") - v = collect(split, path="data", info=False) - if v != np_split: - print( - "Fail, wrong {} expecting {}, got {}".format(split, np_split, v) - ) - success = False - else: - print("Pass") - - # Check output - if not check_output(): - success = False - -# Test double-adding variables -print("Checking with identical variable added twice") -s, out = launch_safe(test_exe + " check_double_add=true", nproc=nproc, pipe=True) -if not check_output(): - success = False - -print("Checking with different variables added with same name (expected throw)") -# Test incorrectly double-adding variables - should throw exception -for check_incorrect_add in [ - "ivar", - "ivar_vec", - "rvar", - "bvar", - "f2d", - "f3d", - "fperp", - "ivar_evol", - "ivar_vec_evol", - "rvar_evol", - "bvar_evol", - "v2d_evol", - "v3d_evol", -]: - print(" Checking variable {} ... ".format(check_incorrect_add), end="") - try: - s, out = launch_safe( - test_exe + " check_incorrect_add=" + check_incorrect_add, - nproc=nproc, - pipe=True, - ) - except RuntimeError as e: - if ( - "Variable with name '" + check_incorrect_add + "' already added to Datafile" - in str(e) - ): - print("Pass") - else: - print( - "Fail: Incorrect error message for check_incorrect_add=" - + check_incorrect_add - ) - success = False - else: - # was supposed to fail and raise an exception - print( - "Fail: Did not raise an exception for incorrect double-add of " - + check_incorrect_add - ) - success = False - -if success: - print(" => All I/O tests passed") - exit(0) -else: - print(" => Some failed tests") - exit(1) diff --git a/tests/integrated/test-io_hdf5/test_io.grd.hdf5 b/tests/integrated/test-io_hdf5/test_io.grd.hdf5 deleted file mode 100644 index cf9ef5057dc409bf16f1b43c56a758cd68d86fa7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14536 zcmeHt2|QJQyYDt6WeBN|M59!SCaHW?NGcg3l_F&b8B)?LNt7f-QlSu)Q05^KLgsm9 zZ|uq5_ST?*(p`mn&wbzf{?B>O{h!Y{=idL?pU--J!?S+tx4!#X&w3_5T`e7v$ug5k zzYak`5<f}ocXRyobL=Ql8yy+%kI!3<HF(CT?--5a9c}QCe*H)!sj+eKvGxC!Z<mp_ zHi^Vb8ee~$j$KAt&Oh23+Xl%~b+j)(&hQuge;NT@?TrS%9x!R_DSvl}cD2gbz!-7z z7;QM68l^|v4<7r~IyOdaR1g22uyL_I=0dc7Q$m((R*a61%dyyRE)pTT0>9;V^z^GQ z_<LrYkB^Y&Uu`jBcyvbd_xuE+_iLP&m-jcT;Mg0$$74ClHpcy%nK(&|^?xyYOfNAf zkpjo3{!39~{heAoqzNS5v0ddY|Ksf`j!nCW|1qED*mR`iAM=gh&Qs!#`Ns7`;M70n z`_G#F^X1C!zqMTb`FObex5nc?OD_NH`wEXOI8J{nLt;#7sn)Jxg-M#)j*I=-XK3(m z(quP=ap0}o${2F%$HtfUAD>cZVVA<if`%nzNUO~k;Yia!K0C4`dsRQ4%=nyjWi1&b z$(p3grhCv}yxsc1)*d9Z@qf6WNdxDZ%pLc@Cg>*kAM)JZjo$NG)WNrnD8Fy`&C0V2 zltRD$7xKL@DwN;(+Nv4d=O2)G?7JZ&^mg|4W4$0NnAvqY2O@7?twZ#u3@{f)+3(!T zhWix$N-YmM-gWsflkd`@COs@XV|z0K`6Z2*bxjCWOtlVl%fqT>%PCJLbD%qiN9SB^ zJv=fdq#qP*!PaEKramP)*cB6`Y!lgtR6L~hvb6wVv-xBlZZtsWW4R}@y%Upf&i47% zSc8L%U3i<ohNfSf1w;B0T3RL<nC+urWV70g>UT73YVB7(vw#la%MmISjg^SVi7iyV z(TnM1&qUk#T@cv)^-#G=Ej}6R6c6^cBUD&+bHJ_)T#T-1iQP$oyjE-M^!cr*-LPCd zg3<?4d*F<#7LTFZOFplh-Gs?6PHfH2p`!5G?FaLWiV%P2;hf0{?P&JlUs+?HinOL3 zeoxA(p&T~pYv4IHny)Q+z<5@RBYKAn`DSzQ`evZY<2)AJyiW}V)UXlgB^<Y*J`eZZ zy#uvI$cWs*+-BSqkMo*0qsenwsLI!3^%eBN<(R^IMblKw;k&$jM`}0B+^VOft2Ch~ zER;NLH5ZZ<WwQ^oa3IA$d#yB21yZ)Lw#7ed#3X<HXSIcWaNO24uegVcwMGqd6x_Ms z51p(0%8vq4pONPMIc_+&JvYYFh64V~5^}<~O6dFNS{pWTp%K`<dG_vpyl|Ruc+-43 z!fo^J`G|KQ&fwXy;$vx8&wFy+T9F#m*G)2&Q-6z2-&oHNM{B^#HKwpWups#S!|MZe z6;Rr{N@VYBHqP6X*y{gm!pQsBh_en<T#=s|v-lwmp6+Qo)0AGpSH}LuvX}~NojsD? zR>Z*8#!yDd#9j<69|;<q#DRT^59VGWBWT&G!upy{NHM;8PLHm@8mWsUgX?tgnR*Rv z+Q-53tl7fCr9EKyb{O$I&xO?6`VTH&l98+#*)uP?4+E*UR7aMzqfX9EU-V25MBEfk zkTp3dNy+D~`;?0lO`-HI=^o^%v_6{j@-~V#B^}#vjfp2GwKNUp(V$zGbv9;E70mRz zZ|_@}h1a34zN4uR%NJgC_O`D;2{lZ1>hxy#-gUlrsJ$BoIsI9sCeP8mCO9*4M>~c; z?OmMY-HkX4A2GpeS$OPm`w7dn28`Clx+26lx%AlS&Dq7!41M+aO?5dI3P$<|=TTrK zEu$K*PsK(N?ZX2H8Bo?-7`TAK!tN_8ykxm7d~TKZK7FPEf$A<FvW}*}PM1BU=5-x( z)hc6p5?SEaSC?>G_Xg@|t}1(z>M^`=pI~qX2TL@v>*fvj;vrxCHgWZCm>Y5jE>qrt zp|6*#)|rg;Pm=b2A<-~h?T(4n%LW)cm18*+Goi3}_F0uQE{61PIEPl(L2Sy|9UYlZ zale7GL^i4ow%a>Pzh$$qXy2-L5h7F^x)G41!OulVnyAi<sBT!a@~@)E_CvYkfD-pW z7t9hlg4z~zEdS8RGxbIzJjw>cR~2y)>OiXZb?d+n{d-w7mtK@?Fg&7?SpvH?lVe)9 z)gX#1L)&4^g)Ym$*Db#gpMn;0iUR83n4TrSaDE9AO0yJ8^IDPjB_hf$(i5rD>QWBE zedt`@^{#A19sGl`*fX}#z|XUWb+owyzOuXzeMNGhb+&b|x`PeD()|u@!P$^Z%xqgA zT7{Rpa+XeIw?XckzVyeAI=Fm`IM2Eo2};JEuJ!2*xP9{8IpGr<(y#C!_Fg|CwlFn( zRVdi_VOiTvnSQ)Id;k1^Yc)Dm_J@c_v(UVKr&mpVIz0V<#-?{YLA~<_UfOgzLgQBX z_VyOS_Fle~lVdOOf3%%4T$hFc1EHScBMG1`IlHf669+cKKGrv?yRhT%yrq>ddoe+7 z>+afWD*U%(YFJdzU?o@_a=V6wKl^+3*LwdP0{^;QC-vJ;5|_uA2c$__DMVWNlW+7s z|JaZ6_&3^jzW>~Y|AV>z9uLLecjOs$6G`KC(m$engdh3KhWh96@*Km<b1afF`k;UB zciR02Bk;d3|8K=(!q{cwxQzGz{dkZ>MwcXyo20+H|M_@K{Qduqo_@s}{?GC;{``L) z9+qPvx<AH4n50I;2!HKMl#o?H(y1d(hpjy<Y#p7g4muL!e;WrG2UlnmY~nonJpZ%% zuQdK%K1Mxz9=_3)$De<k{w*$lJO1yN7fqSbt$I%Xms|dOc`^H!(|@)9Lg4>v1PU9b z%S{ZbgS_RMPfq#w5FMI&WS&$BM*0MNA{;w#-&0w9_+ugL4VP*?rm^92b*{i3-Xd&T zX5iN((F#vZ=W2DGCJ4@G-H`Y&AKTTJB&eBnpsM61zqK4;CwKKV>k4JVBWTLWT8kt^ ze_DNdZ3Y*$nhOl7u23-WIx+52V<wbN+<Hgr?}lZF)0<-{9OQlKTvT?q2+Id{P)sJp zptH7PdQW#fl9NkiL~|*aCw}Vvsj>p(9k{|#+DV4@J85Z+g=JX(bp4W4b^#1Bv|EG< zUg1@K<}2s4K0NxC{N0Gjg}#F938~L52o%e^SGYV4@sl4Eb36KR{Z-oGD;y41x0!bB z{!aMWJa><KxYuKZd$etFZ7+13u6AGI?SlW4k5l-+*W-)Sz~0cOOboS%aD|R`K`k(> z>Oxd8@+?ob&QuJ9q+TxLM=%9n3ye}0ok)VW>gU9>;$4V)xLy8uNHX{)&p6D#ny{aP zc?;jQks-M*SWYOi8cEjrJc1`Vm|&DKFKq)AHAO8l8753f1~1)ReJc+S0(Ms#4KPrh zkNURcO!!gBRGqm@XazrQ+^^h=W>xz`S?vsLTAN{XytW0TJR>((wN7yOrA1ELG{L3B z@X(X|CXf;ho|;RyA#V6f_{JUC7@4xNAX%#)S&2pm<5Rc@sxX~=%8muigz!2Wo+jvh z6;3hPT!+`gq=}}9R8&0Oz0Tu28+v?u&8|oGfq%>U5`iHC_e>>ahm$R!#LT{2FxUr) z6<;QqPbMRThkn%NWHl_Wi>*=E7KsE)Kdou^>QSISRl6j#7kO(_(g)X7BI}uUtD8>` z)|=d<Y*^5a_bLb8dH(3f@lf%NQ-{i7cK31J=_Q@e;(O88s@H@7AGY}J)Ltlbr7Fek zp&)S5!Busex?!p|BwwG)Md0#d^*?R$;TdF|L%nwaW;f>^k%>=*|H)@oMZD#Zd~9-U zaqv4h4)WUeKW)U>gtDsL<^(^>dH#BlOyucp-Ry4~1z`=L$%{0L@j=bzR_JlUuih5$ z-gd%sc!r7?-4~94R6|!tVk#StE`EJezoQ4?Yi3Kd33r1vJ(RvjodZtpr(us})gXzc zEgHBJg}W5Jm}~iDOf2i#SbLp@S6LDY-zw>N#dV4o&ZVMhbLrBAnPe>g^icOu(Hlta z5z*d3_}AYX{XK-*t8n{#uicva`3SC`^5~{J9b&zid(|g1p=>tk!a<)d1a2<8G;>xz zTn@}Ab)}`?p!mVy(hfS51tbo&xz|8mvR>NRzXUk}m*{sy3J@n*J3wzvh1M5q8Afa` z27|peCJ*!>RkYQ4FSQq;mS?xmD(}Os+mB`(j-Vp<agb$kdjqcM8=RX?C*(9;{=mpX zCTxzA&UnnLh6}y<UecaY2=RQ&JbIT3^Cemb<$g4y`u+y>kfsz|=Ft}~(xAdK{^O;z zI2JrD4?8OJ<l@D^-k)VXOw<W>N?v-;LcU+Lrtslj@GstZ<lO6b=$)RgdT%8QmV&h^ z!i*3Y47JX~i5e`UJ`2j8#KxgFiybqFIL+a<1(E!ZD5!s3FRf%<h9T<A8k6-sAnos~ z@X4Zp91v;cu91%-ok%0ckUo6aP<FGsnv8(&Lz!A-El85>-+ky>28tU46DfqBJd`kT zj&*kvEVrc!9*PTu2Puj#OPz~6K2F8~z8t9g=Xt6h>mc4k>9=I|J6LAc1-VXa#JryR z^C|O+Az+lg-F7n>d`HCYUK{C!)ZN9hYv;ejYmRkA^)(_MF;r6Nca#dTt19cM!X4=I zKCd@u)Q(MNH3RP#_CsCk#Et$tY|ME6{GtJsi_42{eL1p*ffD-qSJFhhN8`?xA8(uc zut^|+R<w=|U1gFqQ==F|6%Bbxv~J{RFLS%_gN_N#BkplD1{h~rzpb^)fk1@UH8r<R zEEPR|LH8&ZgUru<dO8#^a@4vq-z0&Nx%;JwMG<r!KXY&^s>g-WMQeAM5`MdR<-tP_ zn&4Dg<q*1%20_sarL5dH$go>;G3`tqHjyQDpHS;?dmWEDS(1T~9rQEDYpD2|B1STc zOhT@@=tGr{bbL8MX{Vo{Vt-Tn1gpn%@TXZci^x^M^DJ)>qc95vGCDr9CXgYYZ1R|I zVm?BbcKJB$Er#c8`d#@+?l5>9^`WRG9=iGDTQ8@)h9Ps=*8c5Wkc*#PTwfcC@2qZ4 zMgR@w0?)!##EJNe>(7+10q~mue@L!baoWC7(Cg5OHgE_EgfM8VsB|C2%wK1xzFj zruA*4A?iI%xxb+w&0Tj=XbJt$4OzASvjGDcrdwti@Fn4ET;Wyjn_@^E;t!x4F2%z4 zin&!Ad*DN=H7sG1F_5^syK7Aw26lL@2$3&@#Pg5u1x-32`YFADcen#@Y}`v{sIlOY zzW(F+<_2iS(_guEb)z%SPxfg`8&(>Zt$Dz$LPeX3bLwO|?9R-xcF`<_2R-@6@E`-j zi(~|9J1J<+x)E(JNW<2oJ1Y;aBtvt?EA=~7WtfcJ)~x<k2+r4_zyDBx)c1!3X7`aH zmvU-)uuBu}&y$@}Us?c}g3q?G0$u34Fzc-DU>$CFNxs^h&cWHuDKh47+ac5wNDpr9 zM%Yrf0s-|_G<^7^EOMEFq#2(~_Yv`_Hvz&|<mR_yO~OpK##1y{PEB9UTpNz%5mpPU zBv~-`q$CUxaj|&G!%_~{@}MEEy3%ZKErwX$A=S@&VLq{N!B(A0yn3Aa?dlmSmbgp~ zUF%;9_2Z%q%v$2RE&kq1vZN8_Nj9(2QH`Kmandm^tq9QJ8m=86;_VS(#vO!Sw%obQ zF=2NBEGLG9WL@gURTa-k8ArRJcVTe;iakU;wetM2c&RF+2knn^B=QJDxqhDpi0?1S z^TE97LcuT#&{o!6K*Xy)Di+ay_Cn(7=C>(Ao$x((!uR~*CgjQ6y;vIX8lG1BMqEo@ zf^^1yvM(tF(LpP0o@SIoQSrz-_LUTr<sC|2FT_GC<t@KL2?s|QCZVm`y|`azU$p5* z1<r40D~S>MD9mkjrGRZ0Ja`k!X8f#$km)lg!&Nj`&^jv=?)G3YCv{-y0R|}dsCM>M zG>8lz*|Rvm7bM<wi@vUWiyZ#_AFk}JfbM|_PB%7{poO{bOa+mD*xy?9e(p*JCRg+u zt9mtqQ95@@mn;X7<;waOi_36p&FQ=PzTGHxp5>Hxf{ePEHc=HZWF&m|cRAD9g!~!@ z>5I`Uyp}!6wEIqmBhQjIQ(TI0wPGqwQ@#iH6~gvkU($~1U=s=DshNm$_LIp%4(8dJ z$#fhphJ)QF9p3vC@UE-#Tbs}V`?Q&B?#uT<#E*M}HK7}g%(_96Yd_W{PNH3sC*xgy zSI*lt&G;0yM%6x`2d~sP4i0)0Xy9p$Ctp8KIAt^R&(Ja86Z~n?*++0bK$nT#+=GLn zF8*0hX}GU(^v1PSc@VqleX;c^1Ix8%o9ld`;Rmmw&fL!&uzioNyYrLK%bTXT2XDy+ zNsN1+&EtuuK_0i2p7+Dk*Q&6|hyhxf*GE;^Mi^|%nSM?u4f?cjACq^r@Z>G&DX;ec z=kT}9Ge331L8W-o#DQ)&E{}<)dzYep>%221LvJB;!NzNYa6d9W4lM5-F2cT@Wv=^V z8N~A~S+I=Rjp|!Fc~xiDqA@IbX^(Fc%IP^pbG0a7-8@;6M%XVkG3PVS5&4IJ_8sa+ zzqKOpc)W7>aT>}WPw-o|pc7B+Jr}H-PQ&t)i@Xx`PtiD(({z;0LT*C3d$4~!G*`}e zWT?{!&9LC!oa<dgynilvl}|qI_uQF~qF)W+gzz^0&VKAo-T7K9pc%9kt2<`|bV8DI z^V1rSJP7;C$$4L^L^Suwx6+NJFuGkGWt-Lp%Sn3{Rqv&sI+40|TR|(_Hwi44O>0Hu z!3GJzSAEdT<@>6U5RADQgRx%pZm^qM+D?l%pnZ!CX?{a1qT|eRH4RI_$8bxN`^-R8 zLX_b)@jjT|)6G^Q@(k}T+GggMc4PX+3*l2d=`i{_pW>HQkKLg{oHhdIDPhKsKQ|D0 zmpF$d9?!{G>)>7ZRg#9n`&*>Hj}*f)VqN?ey%vO0it^1ov*2-U`NFzYg=iTxx-6s8 zjoa$hmLG*`@KNSo;qw+U_~lm13jZvCSh}TD=H5#5^p{ugcu~>#Mc_+SQX7I261)}7 z8SoW#qRGZm@W_EVV?Lz~Q;rS>%_rjM%Y&PXKi+D9VD>XFt+Y(6x7fO8m0}56Z~GlL zS7Ts?{>q_Nc{&W_%R9}yE75qad_Z++8%WY0y64;sBlONZ?Pml&A}^f#?zMB#`8I81 zg?kI8e3|{m;sOnkw<O!MU)@8%N7FV=5uvBQ88eJ2UGR)hGD;701xKMg?M*!g16wOn z%fs@qVD+S`UDa*KYf&6x$KJr)3$2~vk==-QrA=Sx+KKf!X2Yu!xaj@ipZ#5-53ypR z>qNC!C^Ff|be+!tImF(;c6KT>GLqfJ2z%Q;B34n`xe3!PJ37y%5b~t4`?g*w8+Y|w zji+&XU?8#R$i`C*Fivs4OegHKQyz7)LtChb>=?OPz5fv+!*9AqEr>wCk!T&I+y>;4 z{FJ3rpFor3_I=`^aF|`*vSvNA3Toavi*{R3A^WhZ?DFPrFqrw|OCuE+5RLy<WR`=Q zdFG)PYRE81<n6Sb+llk$rtj-Dx)Hee&i0eGL|({pb(-X}PSnRoUk>?DiDwD1S7VHb zd~3d~tW8lqB=*Fq*e26Zxuo{yW8P|b3tm^Q{aFrK1JN=$uNKIM%@&WereIF^0V$sF zR=n+<o2PKU9ZAkVT?;rhP;Yq@J3#2qzQIk(JEL2XMAcaAK7j>xV$SNgAr3OzsJHh% zU|~V%#R|JJI#%xK?+?|f#^>4A${+bS5IavdV6Ulw-JIP{$wWS^Q&+05?REpq=VZ^U zuqnflwfa$)0~rVqJhfrgO9sLZO$ka0=*CcZ>gw5sofufCv%uy<6tdno8-0lEgkXqx z-0Q{^NHlmnT(+zkN!34HHxS>!C6eYM%%#m}PvNg9C@Y3o(f3M8gLIGvOi#U-x)d%t z`7YcC@$fYMxNXnMiwKdjTE94njeS|?nr}bhBC&!JDPqCF{&%-FY_nuRr$PI5zc!&i z&Nfys?CF?j)*O0~-UIRiFVQ_8O2DM-cwt)Gheko|A+@Y_>`7T}Ekoq%Wv;nBNqSL- z^*3z;e%$VW>4>b7<hBMl4V7eu3w6NrafpiAvQWf5Z<Y^R(}eJ$AY1ap4m^+aN_Rd@ zLG3|GgsL$Uk)BEIzUQlm_e^O;^UudPY_`~TrEvoo=S-zVs`Ak%GH25}i5isd_lX<M z=7Pn?w0dOGk1BJuE6bj;@hyPQij&R3)veOsscX3qbu@fdB+!Y~bCSCb2e#w*oioZ= zt`)E$4=2y8Z$#|%x8cizm`HgjWG>%HMUqRGY(MKIoR5EcI{b)1e1Bq%G+s~<xIx8y zKB3=rjd<piPNNd}JcH(YgdC78x0%ydu7J|iYljL5dCa5MyI=KAfsn0|SArG;15wtl zSz52*CG)xPt_BS;q2hGWlU(e#*7b{i&4Se`cVDCR_1N`oaSVyj_X7z^lU)rvi1#IJ zeatRTe2%y-u~Df9O14)5Op`m&*ZZRiM0~|KONQ^qwH_=;mfAV9sv5kD>4S%JJ5eJl zcEdT3iCQNMjYk&Ec<kdN&tKVr^ht{58>?8bld(zmPwGXYg8KoQEs;OYU}-Mk%R^i% zAO8U&jxh74pQFNVD$Z$K>FX!_M$wx!D_E20$orbU^W@cs*rl#`T5v@HBqrZZSaX$w z3_cT5m|qp@v#d;Q9~I%K<YW=CLo`Tf2+6Hk--+T5wHL)R`Z08>UhNSPZxY)zKTTem zje$L1v@1JuKuNquv&|vm4pzZD0at3_wBT%OF!5b6p7t=>UV^Yc)=DHj5vYNs!56O+ z^UI+ewNx*uyAhV8?<T23!JvIxIg>My0qT*Tv#3{k;kf-0Q$MT~yQJsdi#^^5vY^>~ zC9M$fpY~(7uY8A+&2H1H^Ri*AHW(&D<RO=wN$`CXR1YWW$r57{6Y`l7oBL*jBb6&Q z%tPpV${oXzKtn1rgj8I7lxRpibz$3tGc0hw^uD|vNJa+TN<{fG8<+Hgvv~B$h+jOh z#q4A;-s_$3jjZoMR(YcfWqT9UwvoTgpWg<xz86zd&0CSRwe)elTrIw`lScNRr^98j z;ju8;66jIenF`06pt?}GX;&TL7czNOPbViJZmHbTBavB9YzeC|d-f7)6AJZDZ0|?q z0_z<<QeBYuD$w$?X2R@V{Nd9}i1*N&<z%5;0ePd(4&M_ia4%cyrZizMtGB1zdh?U8 zr$<U%Q(fvIe}0HvS{DsLivl~tPo>x-n=2scRt<Cifnl9)!e8EcJLsY83-syn?Gczp z)TOAZDo?blLFCaW#c93iU^pgtZ7yoSo2|24RX0^bLiUw-)YT5i%E=4|UF(2H*G0v- zF)gr|#(Ps^N-yL)dn^{ny~4^O#@_VL^$7j^ewE6FB4iW~SMpHPi2s?Rr|4gYpHmbr zS`qaMHoMYud$Q|bbMR|qr8*P4j`rDi?t23gPHIIH{Kjo}%KIa^DCK)NV3JAH7x5(5 z7Uy>3=(E_6WPJ*x8cni;hRC>EbuH>cMGunVpWn<ol7+*Ho$j_fnfNL<ZCdG28bU>V zcO>bhVI!aMjUrVFsGD4^DrCtRvh3{ku5W>wo%8;A_p@Mj0gK;#X@XWn;C5jYp!#Y) ziD93Jkq6s9ClmU{bI~<<Etw~9xFS<Ub7SJWBWducD-$FQtA^eAk076+(Zm(1MPORe zt;+mZs48Ssd{(01LHShHJi-r#&x))2syR?|il>QuB;(FL1+9mcJrFe9wYrYNh3rK) zgYxHuU(q3Z*u<Ly#t})=<j;h?(Q4KnUl0SAl-u^R783EMr(5EE3h8(hG}pI_&~rKm z+Z9c!TQET4OEpk@f#|MhIV|gbl=m-?)c#lk&zQlO4J(QIo7yFN?&>q)Yp{KF?XF~y zWY`{olaJwIqYvXpBppk3$9&W!?ATooWABI&bxG5O@?$2kx!`VoKIOXv3qRgEGp99h z@LlX~xj<JfxT;T5PZ4!l&Fh|9HXM5e+q3#F>ko3EcxB4z{Jj~7{5toR<e4aFUP@a% zs8A1PZ^rS2iA=0qdN(*Wv>Xi|cX}lrWZ~KJc#>^7p}&fkPoNuTK<<EMcV#0JWM}mO z$6cWieaw`InO_e_r~5OshMA~-ur0M#y8}|Oe65cAS|GLI>X|FwSeRI2*88=Yh=+Bh z@MvG7;^lL#kK(86(E8=%ya&;3D16YP>J>o&XU#mmx&s|JCuEgrnBR@$Ekl7y52!F` z2|v=S-+`|dQe}Ncc{ng)$72%QjF0>e<cv?#QC1<~7}nnl+VdAecMtW#ZtE!ro#b@z z?3>emvZN1hPeq%2S-{4Npbp3Qv)zcy61(mrl88XwcCzZz=MZ37OZN5kU|k=%eki9G zdb3y!VH<j2;U?}YtH{QcRn%fCm#Bw(pYq+WivqRnK61G$(h(B<L;Kj9UK|LIFfLit zgCOHr#wI5Qn0<`<k7kgu@-5qVqjnwGyhgf{+{v)?UY+C+7!HZc<+b`d*r@$_a#-Ve z2bia7JB^4q=2fTcJ!0+*ka}{2XK!^!r?;ls*L_^rmmK^ueH9%k_L|<h63q~-o2q&E zQ7%FZT-^dZ+CYhT>q^?d1`p|P^QEI{Odg)m{NQ;0ah(41_1bx(3CFSOgz;p~zs&ow z^tS95CM_S!i%upu1xZ%UCyrYjKjmUQcEMC)0|G>Qd>?Ly4myrjrt6L``KQwV+d6ow zv3mLO{aXI1yZc{@jn<R%6IBhPhwm?t{@@TCo0A`_5BW!|<MsO<;|bw^z$ia9ZaIFz XKj8ao_%8(hLf|h1{zBltCIbHhQi&?1 diff --git a/tests/integrated/test-io_hdf5/test_io_hdf5.cxx b/tests/integrated/test-io_hdf5/test_io_hdf5.cxx deleted file mode 100644 index 3ce5f9f861..0000000000 --- a/tests/integrated/test-io_hdf5/test_io_hdf5.cxx +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Input/Output regression test - * - * Read from and write to data files to check that - * the I/O routines are working. - * - * Test evolving and non-evolving variables - */ - -#include <bout.hxx> - -using bout::globals::dump; -using bout::globals::mesh; - -int main(int argc, char **argv) { - - // Initialise BOUT++, setting up mesh - BoutInitialise(argc, argv); - - // Variables to be read and written - int ivar, ivar_evol; - std::vector<int> ivar_vec = {1, 2, 3}; - std::vector<int> ivar_vec_evol = {4, 5, 6}; - std::string svar = "ab"; - std::string svar_evol = "cde"; - BoutReal rvar, rvar_evol; - bool bvar, bvar_evol; - Field2D f2d; - Field3D f3d; - // fperp is at yindex_global=0. - // fperp2 is at yindex_global=11, it is included to make sure the test does not pass - // only for the special case of the FieldPerp being present on processor number 0. - FieldPerp fperp, fperp2, fperp2_evol; - Vector2D v2d; - Vector3D v3d; - bool check_double_add = Options::root()["check_double_add"].withDefault(false); - auto check_incorrect_add = Options::root()["check_incorrect_add"].withDefault("none"); - - f2d = 0.0; - f3d = 0.0; - fperp = 0.0; - fperp2 = 0.0; - - // Read data from grid file - mesh->get(ivar, "ivar"); - mesh->get(rvar, "rvar"); - mesh->get(bvar, "bvar"); - mesh->get(f2d, "f2d"); - mesh->get(f3d, "f3d"); - mesh->get(fperp, "fperp"); - mesh->get(fperp2, "fperp2"); - - // Non-evolving variables - dump.add(ivar, "ivar", false); - dump.add(ivar_vec, "ivar_vec"); - dump.add(svar, "svar"); - dump.add(rvar, "rvar", false); - dump.add(bvar, "bvar", false); - dump.add(f2d, "f2d", false); - dump.add(f3d, "f3d", false); - dump.add(fperp, "fperp", false); - dump.add(fperp2, "fperp2", false); - - // Evolving variables - dump.add(ivar_evol, "ivar_evol", true); - dump.add(ivar_vec_evol, "ivar_vec_evol", true); - dump.add(svar_evol, "svar_evol", true); - dump.add(rvar_evol, "rvar_evol", true); - dump.add(bvar_evol, "bvar_evol", true); - dump.add(v2d, "v2d_evol", true); - dump.add(v3d, "v3d_evol", true); - dump.add(fperp2_evol, "fperp2_evol", true); - - if (check_double_add) { - // Add all variables twice to check this does not cause an error - dump.add(ivar, "ivar", false); - dump.add(ivar_vec, "ivar_vec"); - dump.add(svar, "svar"); - dump.add(rvar, "rvar", false); - dump.add(bvar, "bvar", false); - dump.add(f2d, "f2d", false); - dump.add(f3d, "f3d", false); - dump.add(fperp, "fperp", false); - dump.add(fperp2, "fperp2", false); - dump.add(ivar_evol, "ivar_evol", true); - dump.add(ivar_vec_evol, "ivar_vec_evol"); - dump.add(svar_evol, "svar_evol"); - dump.add(rvar_evol, "rvar_evol", true); - dump.add(bvar_evol, "bvar_evol", true); - dump.add(v2d, "v2d_evol", true); - dump.add(v3d, "v3d_evol", true); - dump.add(fperp2_evol, "fperp2_evol", true); - } - - // Cases to check expected fails - if (check_incorrect_add == "ivar") { - int dummy = 0; - dump.add(dummy, "ivar", false); - } else if (check_incorrect_add == "ivar_vec") { - std::vector<int> dummy = {-1}; - dump.add(dummy, "ivar_vec", false); - } else if (check_incorrect_add == "svar") { - std::string dummy = "y"; - dump.add(dummy, "svar", false); - } else if (check_incorrect_add == "rvar") { - BoutReal dummy = 0.0; - dump.add(dummy, "rvar", false); - } else if (check_incorrect_add == "bvar") { - bool dummy = false; - dump.add(dummy, "bvar", false); - } else if (check_incorrect_add == "f2d") { - Field2D dummy = 0.0; - dump.add(dummy, "f2d", false); - } else if (check_incorrect_add == "f3d") { - Field3D dummy = 0.0; - dump.add(dummy, "f3d", false); - } else if (check_incorrect_add == "fperp") { - FieldPerp dummy = 0.0; - dump.add(dummy, "fperp", false); - } else if (check_incorrect_add == "ivar_evol") { - int dummy = 0; - dump.add(dummy, "ivar_evol", true); - } else if (check_incorrect_add == "ivar_vec_evol") { - std::vector<int> dummy = {-1}; - dump.add(dummy, "ivar_vec_evol", false); - } else if (check_incorrect_add == "svar_evol") { - std::string dummy = "y"; - dump.add(dummy, "svar_evol", false); - } else if (check_incorrect_add == "rvar_evol") { - BoutReal dummy = 0.0; - dump.add(dummy, "rvar_evol", true); - } else if (check_incorrect_add == "bvar_evol") { - bool dummy = false; - dump.add(dummy, "bvar_evol", true); - } else if (check_incorrect_add == "v2d_evol") { - Vector2D dummy; - dump.add(dummy, "v2d_evol", true); - } else if (check_incorrect_add == "v3d_evol") { - Vector3D dummy; - dump.add(dummy, "v3d_evol", true); - } - - int MYPE; - MPI_Comm_rank(BoutComm::get(), &MYPE); - - bvar_evol = bvar; - for(int i=0;i<3;i++) { - ivar_evol = ivar + i; - ivar_vec_evol[0] += i; ivar_vec_evol[1] += i; ivar_vec_evol[2] += i; - svar_evol[0] += i; svar_evol[1] += i; svar_evol[2] += i; - rvar_evol = rvar + 0.5 * i; - bvar_evol = !bvar_evol; - v2d.x = v2d.y = v2d.z = f2d; - v3d.x = v3d.y = v3d.z = f3d; - fperp2_evol = fperp2; - - dump.write(); - } - - dump.close(); // Ensure data is written - - // Need to wait for all processes to finish writing - MPI_Barrier(BoutComm::get()); - - /// Finished, tidy up and free memory - BoutFinalise(); - - return 0; -} diff --git a/tests/integrated/test-restart-io_hdf5/.gitignore b/tests/integrated/test-restart-io_hdf5/.gitignore deleted file mode 100644 index 3f5630137c..0000000000 --- a/tests/integrated/test-restart-io_hdf5/.gitignore +++ /dev/null @@ -1 +0,0 @@ -test-restart-io diff --git a/tests/integrated/test-restart-io_hdf5/CMakeLists.txt b/tests/integrated/test-restart-io_hdf5/CMakeLists.txt deleted file mode 100644 index 09cdf40f1d..0000000000 --- a/tests/integrated/test-restart-io_hdf5/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -bout_add_integrated_test(test-restart-io-hdf5 - SOURCES test-restart-io.cxx - USE_RUNTEST - USE_DATA_BOUT_INP - REQUIRES BOUT_HAS_HDF5 - ) diff --git a/tests/integrated/test-restart-io_hdf5/data/BOUT.inp b/tests/integrated/test-restart-io_hdf5/data/BOUT.inp deleted file mode 100644 index bdacaef63b..0000000000 --- a/tests/integrated/test-restart-io_hdf5/data/BOUT.inp +++ /dev/null @@ -1,19 +0,0 @@ -restart = true -timestep = 1 -dump_format = h5 - -[mesh] -nx = 12 -ny = 16 -nz = 4 - -# no periodic region -ixseps1 = -1 -ixseps2 = -1 - -[solver] -type = euler -timestep = 0.5 - -[all] -bndry_all = none diff --git a/tests/integrated/test-restart-io_hdf5/makefile b/tests/integrated/test-restart-io_hdf5/makefile deleted file mode 100644 index 4be85e426e..0000000000 --- a/tests/integrated/test-restart-io_hdf5/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-restart-io.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-restart-io_hdf5/runtest b/tests/integrated/test-restart-io_hdf5/runtest deleted file mode 100755 index 8d6f00b7a2..0000000000 --- a/tests/integrated/test-restart-io_hdf5/runtest +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env python3 -# -# Test file I/O by loading from restart files and writing to dump files -# -# requires: hdf5 -# cores: 4 - -from boutdata import restart -from boutdata.collect import collect -from boututils.boutarray import BoutArray -from boututils.datafile import DataFile -from boututils.run_wrapper import build_and_log, shell, launch_safe -import numpy -import os -from sys import exit - -nx = 8 -ny = 16 -nz = 4 -mxg = 2 -myg = 2 - -build_and_log("restart I/O test") - -x = numpy.linspace(0., 1., nx+2*mxg)[:, numpy.newaxis, numpy.newaxis] -y = numpy.linspace(0., 1., ny+2*myg)[numpy.newaxis, :, numpy.newaxis] -z = numpy.linspace(0., 1., nz)[numpy.newaxis, numpy.newaxis, :] - -testvars = {} -testvars['f3d'] = BoutArray(numpy.exp(numpy.sin(x + y + z)), attributes = {'bout_type':'Field3D'}) -testvars['f2d'] = BoutArray(numpy.exp(numpy.sin(x + y + 1.))[:, :, 0], attributes = {'bout_type':'Field2D'}) -testvars['fperp_lower'] = BoutArray(numpy.exp(numpy.sin(x + z + 2.))[:, 0, :], attributes = {'bout_type':'FieldPerp', 'yindex_global':0}) -testvars['fperp_upper'] = BoutArray(numpy.exp(numpy.sin(x + z + 3.))[:, 0, :], attributes = {'bout_type':'FieldPerp', 'yindex_global':ny-1}) - -# make restart file -restartdir = os.path.join('data', 'restart') -try: - os.mkdir(restartdir) -except FileExistsError: - pass - -with DataFile(os.path.join(restartdir, 'BOUT.restart.0.h5'), create=True) as base_restart: - base_restart.write('MXSUB', nx) - base_restart.write('MYSUB', ny) - base_restart.write('MZSUB', nz) - base_restart.write('MXG', mxg) - base_restart.write('MYG', myg) - base_restart.write('MZG', 0) - base_restart.write('nx', nx+2*mxg) - base_restart.write('ny', ny) - base_restart.write('nz', nz) - base_restart.write('MZ', nz) - base_restart.write('NXPE', 1) - base_restart.write('NYPE', 1) - base_restart.write('NZPE', 1) - base_restart.write('tt', 0.) - base_restart.write('hist_hi', 0) - # set BOUT_VERSION to stop collect from changing nz or printing a warning - base_restart.write('BOUT_VERSION', 4.) - base_restart.write('f3d', testvars['f3d']) - base_restart.write('f2d', testvars['f2d']) - base_restart.write('fperp_lower', testvars['fperp_lower']) - base_restart.write('fperp_upper', testvars['fperp_upper']) - -success = True - -# Note: expect this to fail for 16 processors, because when there are 2 -# y-points per processor, the fperp_lower FieldPerp is in the grid cells of one -# set of processors and also in the guard cells of anoether set. This means -# valid FieldPerps get written to output files with different -# y-processor-indices, and collect() cannot handle this. -for nproc in [1, 2, 4]: - # delete any existing output - shell("rm -f data/BOUT.dmp.*.h5 data/BOUT.restart.*.h5") - - # create restart files for the run - restart.redistribute(nproc, path=restartdir, output='data') - - print(" %d processor...." % (nproc)) - - # run the test executable - s, out = launch_safe('./test-restart-io', nproc=nproc, pipe=True) - with open("run.log."+str(nproc), "w") as f: - f.write(out) - - # check the results - for name in testvars.keys(): - # check non-evolving version - result = collect(name+"_once", path='data', xguards=True, yguards=True, info=False) - testvar = testvars[name] - - if not numpy.all(testvar == result): - success = False - print(name+' is different') - # Don't plot anything by default - if False: - from boututils.showdata import showdata - showdata([result, testvar]) - if name == 'fperp_lower' or name == 'fperp_upper': - yindex_result = result.attributes['yindex_global'] - yindex_test = testvar.attributes['yindex_global'] - if not yindex_result == yindex_test: - success = False - print('Fail: yindex_global of '+name+' is '+str(yindex_result)+' should be '+str(yindex_test)) - - # check evolving versions - result = collect(name, path='data', xguards=True, yguards=True, info=False) - - for result_timeslice in result: - if not numpy.all(testvar == result_timeslice): - success = False - print(name+' evolving version is different') - if name == 'fperp_lower' or name == 'fperp_upper': - yindex_result = result.attributes['yindex_global'] - yindex_test = testvar.attributes['yindex_global'] - if not yindex_result == yindex_test: - success = False - print('Fail: yindex_global of '+name+' evolving version is '+str(yindex_result)+' should be '+str(yindex_test)) - -if success: - print('=> All restart I/O tests passed') - # clean up binary files - shell("rm -f data/BOUT.dmp.*.h5 data/BOUT.restart.*.h5 data/restart/BOUT.restart.0.h5") - exit(0) - -print("=> Some failed tests") -exit(1) diff --git a/tests/integrated/test-restart-io_hdf5/test-restart-io.cxx b/tests/integrated/test-restart-io_hdf5/test-restart-io.cxx deleted file mode 100644 index ad8d3a043d..0000000000 --- a/tests/integrated/test-restart-io_hdf5/test-restart-io.cxx +++ /dev/null @@ -1,34 +0,0 @@ -#include "bout/physicsmodel.hxx" - -class TestRestartIO : public PhysicsModel { - int init(bool UNUSED(restarting)) { - solver->add(f3d, "f3d"); - solver->add(f2d, "f2d"); - dump.addRepeat(fperp_lower, "fperp_lower"); - dump.addRepeat(fperp_upper, "fperp_upper"); - restart.addOnce(fperp_lower, "fperp_lower"); - restart.addOnce(fperp_upper, "fperp_upper"); - - dump.addOnce(f3d, "f3d_once"); - dump.addOnce(f2d, "f2d_once"); - dump.addOnce(fperp_lower, "fperp_lower_once"); - dump.addOnce(fperp_upper, "fperp_upper_once"); - - return 0; - } - - int rhs(BoutReal UNUSED(time)) { - ddt(f3d) = 0.; - ddt(f2d) = 0.; - return 0; - } - - Field3D f3d; - Field2D f2d; - // fperp_lower is at yindex_global=0. - // fperp_upper is at yindex_global=16, it is included to make sure the test does not - // pass only for the special case of the FieldPerp being present on prcossor number 0. - FieldPerp fperp_lower, fperp_upper; -}; - -BOUTMAIN(TestRestartIO); diff --git a/tests/requirements/requirements.py b/tests/requirements/requirements.py index cc46cb02b2..944dc18a57 100755 --- a/tests/requirements/requirements.py +++ b/tests/requirements/requirements.py @@ -17,7 +17,7 @@ class Requirements(object): #requires not make - #requires not (travis and hdf5) + #requires not (travis and netcdf) The individual requirements (netcdf, make, travis, etc.) are gathered from the bout-config scipt, or from executable diff --git a/tools/pylib/boutconfig/__init__.py.cin b/tools/pylib/boutconfig/__init__.py.cin index 1ec4263b9e..069823de7c 100644 --- a/tools/pylib/boutconfig/__init__.py.cin +++ b/tools/pylib/boutconfig/__init__.py.cin @@ -19,7 +19,6 @@ config = { "has_netcdf": "@BOUT_HAS_NETCDF@", "has_legacy_netcdf": "@BOUT_HAS_LEGACY_NETCDF@", "has_pnetcdf": "OFF", - "has_hdf5": "@BOUT_HAS_HDF5@", "has_pvode": "@BOUT_HAS_PVODE@", "has_cvode": "@BOUT_HAS_CVODE@", "has_ida": "@BOUT_HAS_IDA@", From 967210e71f657f65228b8c9dbec6f54f96cad6d4 Mon Sep 17 00:00:00 2001 From: John Omotani <john.omotani@ukaea.uk> Date: Tue, 12 Jan 2021 23:41:24 +0100 Subject: [PATCH 2/6] Support macros being removed in bout-v5-macro-upgrader.py --- bin/bout-v5-macro-upgrader.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/bin/bout-v5-macro-upgrader.py b/bin/bout-v5-macro-upgrader.py index 16d3b3ed5b..d39303b0f6 100755 --- a/bin/bout-v5-macro-upgrader.py +++ b/bin/bout-v5-macro-upgrader.py @@ -9,7 +9,8 @@ # List of macros, their replacements and what header to find them # in. Each element should be a dict with "old", "new" and "headers" # keys, with "old" and "new" values being strings, and "headers" being a -# list of strings +# list of strings. "new" can also be None if the macro has been removed, which +# will cause an error to be printed if the macro is found. MACRO_REPLACEMENTS = [ { "old": "REVISION", @@ -297,6 +298,13 @@ def apply_fixes(replacements, source): modified = copy.deepcopy(source) for replacement in replacements: + if replacement["new"] is None: + print( + "'%s' has been removed, please delete from your code" + % replacement["old"] + ) + continue + modified = fix_include_version_header( replacement["old"], replacement["headers"], modified ) From e37b4508fafa1d2dea3d61be850b3fb90575750b Mon Sep 17 00:00:00 2001 From: John Omotani <john.omotani@ukaea.uk> Date: Tue, 12 Jan 2021 23:44:22 +0100 Subject: [PATCH 3/6] Print error for HDF5 macros when running bout-v5-macro-upgrader.py --- bin/bout-v5-macro-upgrader.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/bout-v5-macro-upgrader.py b/bin/bout-v5-macro-upgrader.py index d39303b0f6..b6db6da427 100755 --- a/bin/bout-v5-macro-upgrader.py +++ b/bin/bout-v5-macro-upgrader.py @@ -64,8 +64,8 @@ }, { "old": "HAS_HDF5", - "new": "BOUT_HAS_HDF5", - "headers": "bout/build_config.hxx", + "new": None, + "headers": [], "macro": True, "always_defined": True, }, @@ -141,8 +141,8 @@ }, { "old": "HDF5", - "new": "BOUT_HAS_HDF5", - "headers": "bout/build_config.hxx", + "new": None, + "headers": [], "macro": True, "always_defined": True, }, From 4a7fda56821ec16d124d000a3228f04253dc343b Mon Sep 17 00:00:00 2001 From: John Omotani <john.omotani@ukaea.uk> Date: Sun, 17 Jan 2021 12:34:01 +0000 Subject: [PATCH 4/6] Update note on zShift in grid-files section of manual Needs to reflect change to using ParallelTransforms. --- manual/sphinx/user_docs/input_grids.rst | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/manual/sphinx/user_docs/input_grids.rst b/manual/sphinx/user_docs/input_grids.rst index 7c19db8eec..54b0c7d593 100644 --- a/manual/sphinx/user_docs/input_grids.rst +++ b/manual/sphinx/user_docs/input_grids.rst @@ -117,14 +117,9 @@ not found, a warning will be printed and the default values used. ``g13[nx][ny]``, and ``g23[nx][ny]``. If not found, these will be set to 0. -- Z shift for interpolation between field-aligned coordinates and - shifted coordinates (see ``manual/coordinates.pdf``). Perpendicular - differential operators are calculated in shifted coordinates when - ``ShiftXderivs`` in ``mesh/mesh.hxx`` is enabled. ``ShiftXderivs`` - can be set in the root section of ``BOUT.inp`` as - ``ShiftXderivs = true``. The shifts must be provided in the gridfile - in a field ``zshift[nx][ny]``. If not found, ``zshift`` is set to - zero. +- Z shift for interpolation between the base and field-aligned grids, see + :ref:`sec-parallel-transforms`. The shifts must be provided in the gridfile + in a field ``zShift[nx][ny]``. If not found, ``zShift`` is set to zero. The remaining quantities determine the topology of the grid. These are based on tokamak single/double-null configurations, but can be adapted From 8e50be642eb642c02c47c97f262616d8b5a1f611 Mon Sep 17 00:00:00 2001 From: johnomotani <john.omotani@ukaea.uk> Date: Mon, 18 Jan 2021 09:57:32 +0000 Subject: [PATCH 5/6] Better notation for indexing zShift Co-authored-by: Peter Hill <zed.three@gmail.com> --- manual/sphinx/user_docs/input_grids.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/manual/sphinx/user_docs/input_grids.rst b/manual/sphinx/user_docs/input_grids.rst index 54b0c7d593..09d989151f 100644 --- a/manual/sphinx/user_docs/input_grids.rst +++ b/manual/sphinx/user_docs/input_grids.rst @@ -119,7 +119,7 @@ not found, a warning will be printed and the default values used. - Z shift for interpolation between the base and field-aligned grids, see :ref:`sec-parallel-transforms`. The shifts must be provided in the gridfile - in a field ``zShift[nx][ny]``. If not found, ``zShift`` is set to zero. + in a field ``zShift(nx, ny)``. If not found, ``zShift`` is set to zero. The remaining quantities determine the topology of the grid. These are based on tokamak single/double-null configurations, but can be adapted @@ -761,4 +761,3 @@ with the following formula: where :math:`R_0` is the major radius, :math:`a` is the minor radius, :math:`\epsilon` is the elongation (``elong``), :math:`\delta` the triangularity (``triang``), and :math:`b` the indentation (``indent``). - From b500d188f0ec5e0bc29c5951de1528f6e9f18c05 Mon Sep 17 00:00:00 2001 From: Peter Hill <zed.three@gmail.com> Date: Thu, 4 Feb 2021 10:20:17 +0000 Subject: [PATCH 6/6] Note removing support for HDF5 in changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dba003c9d0..b93363159e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,8 @@ - `PhysicsModel` expects the options `datadir` and `dump_format` to have been set; this is only a problem if you don't call `BoutInitialise`. [\#2062](https://github.com/boutproject/BOUT-dev/pull/2062) +- Support for reading/writing HDF5 files has been removed ahead of completely + refactoring the I/O systems. [\#2208](https://github.com/boutproject/BOUT-dev/pull/2208) ## [v4.3.2](https://github.com/boutproject/BOUT-dev/tree/v4.3.2) (2020-10-19)